From 3f4885e3423c82a745fee4f4d87d6992f962b22f Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 2 Sep 2014 19:59:20 +0530 Subject: [PATCH 1/2] repost stock reconciliation --- .../v4_2/repost_stock_reconciliation.py | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 erpnext/patches/v4_2/repost_stock_reconciliation.py diff --git a/erpnext/patches/v4_2/repost_stock_reconciliation.py b/erpnext/patches/v4_2/repost_stock_reconciliation.py new file mode 100644 index 0000000000..eb4de53a01 --- /dev/null +++ b/erpnext/patches/v4_2/repost_stock_reconciliation.py @@ -0,0 +1,31 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe +import json + +def execute(): + existing_allow_negative_stock = frappe.db.get_default("allow_negative_stock") + frappe.db.set_default("allow_negative_stock", 1) + + head_row = ["Item Code", "Warehouse", "Quantity", "Valuation Rate"] + stock_reco_to_be_reposted = [] + for d in frappe.db.sql("""select name, reconciliation_json from `tabStock Reconciliation` + where docstatus=1 and creation > '2014-03-01'""", as_dict=1): + data = json.loads(d.reconciliation_json) + for row in data[data.index(head_row)+1:]: + if row[3] in ["", None]: + stock_reco_to_be_reposted.append(d.name) + break + + for dn in stock_reco_to_be_reposted: + reco = frappe.get_doc("Stock Reconciliation", dn) + reco.docstatus = 2 + reco.on_cancel() + + reco.docstatus = 1 + reco.validate() + reco.on_submit() + + frappe.db.set_default("allow_negative_stock", existing_allow_negative_stock) From 96bdc5834ce7f983ffac3c60645e1a41325299ad Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 2 Sep 2014 20:00:20 +0530 Subject: [PATCH 2/2] Get valuation rate in manufacturing/repack entry --- .../stock/doctype/stock_entry/stock_entry.py | 17 ++++++++++------ erpnext/stock/doctype/warehouse/warehouse.py | 20 +++++++++---------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index fd673a3200..e4bab8eaf2 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -206,7 +206,7 @@ class StockEntry(StockController): def set_total_amount(self): self.total_amount = sum([flt(item.amount) for item in self.get("mtn_details")]) - def get_stock_and_rate(self): + def get_stock_and_rate(self, force=False): """get stock and incoming rate on posting date""" raw_material_cost = 0.0 @@ -237,7 +237,7 @@ class StockEntry(StockController): # get incoming rate if not d.bom_no: - if not flt(d.incoming_rate) or d.s_warehouse or self.purpose == "Sales Return": + if not flt(d.incoming_rate) or d.s_warehouse or self.purpose == "Sales Return" or force: incoming_rate = flt(self.get_incoming_rate(args), self.precision("incoming_rate", d)) if incoming_rate > 0: d.incoming_rate = incoming_rate @@ -247,13 +247,18 @@ class StockEntry(StockController): # set incoming rate for fg item if self.purpose == "Manufacture/Repack": + number_of_fg_items = len([t.t_warehouse for t in self.get("mtn_details")]) + for d in self.get("mtn_details"): - if d.bom_no: - if not flt(d.incoming_rate): - bom = frappe.db.get_value("BOM", d.bom_no, ["operating_cost", "quantity"], as_dict=1) - operation_cost_per_unit = flt(bom.operating_cost) / flt(bom.quantity) + if d.bom_no or (d.t_warehouse and number_of_fg_items == 1): + if not flt(d.incoming_rate) or force: + operation_cost_per_unit = 0 + if d.bom_no: + bom = frappe.db.get_value("BOM", d.bom_no, ["operating_cost", "quantity"], as_dict=1) + operation_cost_per_unit = flt(bom.operating_cost) / flt(bom.quantity) d.incoming_rate = operation_cost_per_unit + (raw_material_cost / flt(d.transfer_qty)) d.amount = flt(d.transfer_qty) * flt(d.incoming_rate) + break def get_incoming_rate(self, args): incoming_rate = 0 diff --git a/erpnext/stock/doctype/warehouse/warehouse.py b/erpnext/stock/doctype/warehouse/warehouse.py index 0095bbb4e5..f50c184ad2 100644 --- a/erpnext/stock/doctype/warehouse/warehouse.py +++ b/erpnext/stock/doctype/warehouse/warehouse.py @@ -22,16 +22,16 @@ class Warehouse(Document): self.update_parent_account() def update_parent_account(self): - + if not getattr(self, "__islocal", None) \ and (self.create_account_under != frappe.db.get_value("Warehouse", self.name, "create_account_under")): - + self.validate_parent_account() - - warehouse_account = frappe.db.get_value("Account", - {"account_type": "Warehouse", "company": self.company, "master_name": self.name}, + + warehouse_account = frappe.db.get_value("Account", + {"account_type": "Warehouse", "company": self.company, "master_name": self.name}, ["name", "parent_account"]) - + if warehouse_account and warehouse_account[1] != self.create_account_under: acc_doc = frappe.get_doc("Account", warehouse_account[0]) acc_doc.parent_account = self.create_account_under @@ -64,19 +64,19 @@ class Warehouse(Document): def validate_parent_account(self): if not self.company: frappe.throw(_("Warehouse {0}: Company is mandatory").format(self.name)) - + if not self.create_account_under: parent_account = frappe.db.get_value("Account", {"account_name": "Stock Assets", "company": self.company}) - + if parent_account: self.create_account_under = parent_account else: - frappe.throw(_("Please enter parent account group for warehouse account")) + frappe.throw(_("Please enter parent account group for warehouse {0}").format(self.name)) elif frappe.db.get_value("Account", self.create_account_under, "company") != self.company: frappe.throw(_("Warehouse {0}: Parent account {1} does not bolong to the company {2}") .format(self.name, self.create_account_under, self.company)) - + def on_trash(self): # delete bin