diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index 69ab661616..3cb6bf7fbb 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -256,8 +256,6 @@ class BuyingController(StockController): rm.required_qty = required_qty rm.conversion_factor = item.conversion_factor - rm.rate = bom_item.rate - rm.amount = required_qty * flt(bom_item.rate) rm.idx = rm_supplied_idx if self.doctype == "Purchase Receipt": @@ -268,7 +266,20 @@ class BuyingController(StockController): rm_supplied_idx += 1 - raw_materials_cost += required_qty * flt(bom_item.rate) + # get raw materials rate + from erpnext.stock.utils import get_incoming_rate + item_rate = get_incoming_rate({ + "item_code": bom_item.item_code, + "warehouse": self.supplier_warehouse, + "posting_date": self.posting_date, + "posting_time": self.posting_time, + "qty": -1 * required_qty, + "serial_no": rm.serial_no + }) + rm.rate = item_rate + rm.amount = required_qty * flt(item_rate) + + raw_materials_cost += flt(rm.amount) if self.doctype == "Purchase Receipt": item.rm_supp_cost = raw_materials_cost diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index 8c5bcac407..20eb40c418 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -30,7 +30,7 @@ class StockController(AccountsController): def get_gl_entries(self, warehouse_account=None, default_expense_account=None, default_cost_center=None, allow_negative_stock=False): - # block_negative_stock(allow_negative_stock) + block_negative_stock(allow_negative_stock) if not warehouse_account: warehouse_account = get_warehouse_account() @@ -51,7 +51,7 @@ class StockController(AccountsController): stock_value_difference = flt(sle.stock_value_difference, 2) if not stock_value_difference: - valuation_rate = get_valuation_rate(sle.item_code, sle.warehouse, sle.posting_date) + valuation_rate = get_valuation_rate(sle.item_code, sle.warehouse) stock_value_difference = flt(sle.actual_qty)*flt(valuation_rate) gl_list.append(self.get_gl_dict({ @@ -301,12 +301,12 @@ def block_negative_stock(allow_negative_stock=False): if cint(frappe.db.get_value("Stock Settings", None, "allow_negative_stock")): frappe.throw(_("Negative stock is not allowed in case of Perpetual Inventory, please disable it from Stock Settings")) -def get_valuation_rate(item_code, warehouse, posting_date): +def get_valuation_rate(item_code, warehouse): last_valuation_rate = frappe.db.sql("""select valuation_rate from `tabStock Ledger Entry` where item_code = %s and warehouse = %s - and ifnull(qty_after_transaction, 0) > 0 and posting_date < %s - order by posting_date desc limit 1""", (item_code, warehouse, posting_date)) + and ifnull(qty_after_transaction, 0) > 0 + order by posting_date desc, posting_time desc, name desc limit 1""", (item_code, warehouse)) valuation_rate = flt(last_valuation_rate[0][0]) if last_valuation_rate else 0 diff --git a/erpnext/public/js/stock_analytics.js b/erpnext/public/js/stock_analytics.js index 84c0386c57..a86d7ade95 100644 --- a/erpnext/public/js/stock_analytics.js +++ b/erpnext/public/js/stock_analytics.js @@ -140,6 +140,9 @@ erpnext.StockAnalytics = erpnext.StockGridReport.extend({ if(sl.voucher_type=="Stock Reconciliation") { var diff = (sl.qty_after_transaction * sl.valuation_rate) - item.closing_qty_value; + wh.fifo_stack.push([sl.qty_after_transaction, sl.valuation_rate, sl.posting_date]); + wh.balance_qty = sl.qty_after_transaction; + wh.balance_value = sl.valuation_rate * sl.qty_after_transaction; } else { var diff = me.get_value_diff(wh, sl, is_fifo); } diff --git a/erpnext/public/js/stock_grid_report.js b/erpnext/public/js/stock_grid_report.js index f58c1ab613..726852f7ce 100644 --- a/erpnext/public/js/stock_grid_report.js +++ b/erpnext/public/js/stock_grid_report.js @@ -9,8 +9,8 @@ erpnext.StockGridReport = frappe.views.TreeGridReport.extend({ }; return this.item_warehouse[item][warehouse]; }, - - get_value_diff: function(wh, sl, is_fifo) { + + get_value_diff: function(wh, sl, is_fifo) { // value if(sl.qty > 0) { // incoming - rate is given @@ -30,9 +30,9 @@ erpnext.StockGridReport = frappe.views.TreeGridReport.extend({ } else { var value_diff = (rate * add_qty); } - + if(add_qty) - wh.fifo_stack.push([add_qty, sl.incoming_rate, sl.posting_date]); + wh.fifo_stack.push([add_qty, sl.incoming_rate, sl.posting_date]); } else { // called everytime for maintaining fifo stack var fifo_value_diff = this.get_fifo_value_diff(wh, sl); @@ -44,13 +44,13 @@ erpnext.StockGridReport = frappe.views.TreeGridReport.extend({ var value_diff = fifo_value_diff; } else { // average rate for weighted average - var rate = (wh.balance_qty.toFixed(2) == 0.00 ? 0 : + var rate = (wh.balance_qty.toFixed(2) == 0.00 ? 0 : flt(wh.balance_value) / flt(wh.balance_qty)); - + // no change in value if negative qty if((wh.balance_qty + sl.qty).toFixed(2) >= 0.00) var value_diff = (rate * sl.qty); - else + else var value_diff = -wh.balance_value; } } @@ -58,7 +58,6 @@ erpnext.StockGridReport = frappe.views.TreeGridReport.extend({ // update balance (only needed in case of valuation) wh.balance_qty += sl.qty; wh.balance_value += value_diff; - return value_diff; }, get_fifo_value_diff: function(wh, sl) { @@ -66,19 +65,19 @@ erpnext.StockGridReport = frappe.views.TreeGridReport.extend({ var fifo_stack = (wh.fifo_stack || []).reverse(); var fifo_value_diff = 0.0; var qty = -sl.qty; - + for(var i=0, j=fifo_stack.length; i= qty) { batch[0] = batch[0] - qty; fifo_value_diff += (qty * batch[1]); - + qty = 0.0; if(batch[0]) { // batch still has qty put it back fifo_stack.push(batch); } - + // all qty found break; } else { @@ -87,35 +86,34 @@ erpnext.StockGridReport = frappe.views.TreeGridReport.extend({ qty = qty - batch[0]; } } - // reset the updated stack wh.fifo_stack = fifo_stack.reverse(); return -fifo_value_diff; }, - + get_serialized_value_diff: function(sl) { var me = this; - + var value_diff = 0.0; - + $.each(sl.serial_no.trim().split("\n"), function(i, sr) { if(sr) { value_diff += flt(me.serialized_buying_rates[sr.trim().toLowerCase()]); } }); - + return value_diff; }, - + get_serialized_buying_rates: function() { var serialized_buying_rates = {}; - + if (frappe.report_dump.data["Serial No"]) { $.each(frappe.report_dump.data["Serial No"], function(i, sn) { serialized_buying_rates[sn.name.toLowerCase()] = flt(sn.incoming_rate); }); } - + return serialized_buying_rates; }, -}); \ No newline at end of file +}); diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 4cc96bfec7..4f3480c0bb 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -527,7 +527,7 @@ class StockEntry(StockController): } }, bom_no=self.bom_no) - self.e() + self.get_stock_and_rate() def get_bom_raw_materials(self, qty): from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py index 6c3c395d88..b67090d137 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -16,8 +16,6 @@ class StockReconciliation(StockController): self.head_row = ["Item Code", "Warehouse", "Quantity", "Valuation Rate"] def validate(self): - self.entries = [] - self.validate_data() self.validate_expense_account() @@ -179,9 +177,6 @@ class StockReconciliation(StockController): }) self.make_sl_entries([args]) - # append to entries - self.entries.append(args) - def delete_and_repost_sle(self): """ Delete Stock Ledger Entries related to this voucher and repost future Stock Ledger Entries""" diff --git a/erpnext/stock/page/stock_balance/stock_balance.js b/erpnext/stock/page/stock_balance/stock_balance.js index 7405227116..ecd1108bc6 100644 --- a/erpnext/stock/page/stock_balance/stock_balance.js +++ b/erpnext/stock/page/stock_balance/stock_balance.js @@ -107,6 +107,9 @@ erpnext.StockBalance = erpnext.StockAnalytics.extend({ if(sl.voucher_type=="Stock Reconciliation") { var qty_diff = sl.qty_after_transaction - (item.temp_closing_qty || 0.0); var value_diff = (sl.valuation_rate * sl.qty_after_transaction) - (item.temp_closing_value || 0.0); + wh.fifo_stack.push([sl.qty_after_transaction, sl.valuation_rate, sl.posting_date]); + wh.balance_qty = sl.qty_after_transaction; + wh.balance_value = sl.valuation_rate * sl.qty_after_transaction; } else { var qty_diff = sl.qty; var value_diff = me.get_value_diff(wh, sl, is_fifo); diff --git a/erpnext/utilities/repost_stock.py b/erpnext/utilities/repost_stock.py index 9c3bf1d0e9..51b472e155 100644 --- a/erpnext/utilities/repost_stock.py +++ b/erpnext/utilities/repost_stock.py @@ -214,9 +214,8 @@ def repost_all_stock_vouchers(): from `tabStock Ledger Entry` order by posting_date, posting_time, name""") rejected = [] - i = 0 + # vouchers = [["Purchase Receipt", "GRN00062"]] for voucher_type, voucher_no in vouchers: - i += 1 print voucher_type, voucher_no try: for dt in ["Stock Ledger Entry", "GL Entry"]: @@ -226,13 +225,15 @@ def repost_all_stock_vouchers(): doc = frappe.get_doc(voucher_type, voucher_no) if voucher_type=="Stock Entry" and doc.purpose in ["Manufacture", "Repack"]: doc.get_stock_and_rate(force=1) + # elif voucher_type=="Purchase Receipt": + # doc.create_raw_materials_supplied("pr_raw_material_details") + doc.update_stock_ledger() - doc.make_gl_entries() - if i%100 == 0: - frappe.db.commit() - except: + doc.make_gl_entries(repost_future_gle=False, allow_negative_stock=True) + frappe.db.commit() + except Exception, e: + print frappe.get_traceback() rejected.append([voucher_type, voucher_no]) - pass + frappe.db.rollback() print rejected -