From 1892454036425efc3c39e25f38a7ae46accc0096 Mon Sep 17 00:00:00 2001 From: pawan Date: Sat, 4 Nov 2017 05:20:24 +0530 Subject: [PATCH 1/5] Add Total Row --- .../report/sales_payment_summary/sales_payment_summary.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/report/sales_payment_summary/sales_payment_summary.json b/erpnext/accounts/report/sales_payment_summary/sales_payment_summary.json index 1ff56d3184..8c6242f0a4 100644 --- a/erpnext/accounts/report/sales_payment_summary/sales_payment_summary.json +++ b/erpnext/accounts/report/sales_payment_summary/sales_payment_summary.json @@ -1,5 +1,5 @@ { - "add_total_row": 0, + "add_total_row": 1, "apply_user_permissions": 1, "creation": "2017-11-03 16:31:45.757516", "disabled": 0, @@ -7,7 +7,7 @@ "doctype": "Report", "idx": 0, "is_standard": "Yes", - "modified": "2017-11-03 17:00:37.871577", + "modified": "2017-11-04 05:15:35.892659", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Payment Summary", From de1e29bf1bca48e38e8557ed7330e34b69688909 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 12 Dec 2017 13:22:48 +0530 Subject: [PATCH 2/5] Production Order fixes (#11951) * Production Order from Sales Order fixes: Validate SO and set required items on save * Codacy fixes --- .../production_order/production_order.js | 2 + .../production_order/production_order.py | 44 +++++++++++++------ .../doctype/sales_order/sales_order.py | 7 ++- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/erpnext/manufacturing/doctype/production_order/production_order.js b/erpnext/manufacturing/doctype/production_order/production_order.js index c3e6f20b64..68a5dc4f8f 100644 --- a/erpnext/manufacturing/doctype/production_order/production_order.js +++ b/erpnext/manufacturing/doctype/production_order/production_order.js @@ -157,6 +157,7 @@ frappe.ui.form.on("Production Order", { item: frm.doc.production_item, project: frm.doc.project }, + freeze: true, callback: function(r) { if(r.message) { erpnext.in_production_item_onchange = true; @@ -184,6 +185,7 @@ frappe.ui.form.on("Production Order", { return frm.call({ doc: frm.doc, method: "get_items_and_operations_from_bom", + freeze: true, callback: function(r) { if(r.message["set_scrap_wh_mandatory"]){ frm.toggle_reqd("scrap_warehouse", true); diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py index 34ade1042d..891e6dc53a 100644 --- a/erpnext/manufacturing/doctype/production_order/production_order.py +++ b/erpnext/manufacturing/doctype/production_order/production_order.py @@ -43,10 +43,7 @@ class ProductionOrder(Document): validate_uom_is_integer(self, "stock_uom", ["qty", "produced_qty"]) - if not self.get("required_items"): - self.set_required_items() - else: - self.set_available_qty() + self.set_required_items(reset_only_qty = len(self.get("required_items"))) def validate_sales_order(self): if self.sales_order: @@ -57,6 +54,19 @@ class ProductionOrder(Document): and so.docstatus = 1 and so_item.item_code=%s """, (self.sales_order, self.production_item), as_dict=1) + if not so: + so = frappe.db.sql(""" + select + so.name, so_item.delivery_date, so.project + from + `tabSales Order` so, `tabSales Order Item` so_item, `tabPacked Item` packed_item + where so.name=%s + and so.name=so_item.parent + and so.name=packed_item.parent + and so_item.item_code = packed_item.parent_item + and so.docstatus = 1 and packed_item.item_code=%s + """, (self.sales_order, self.production_item), as_dict=1) + if len(so): if not self.expected_delivery_date: self.expected_delivery_date = so[0].delivery_date @@ -431,21 +441,27 @@ class ProductionOrder(Document): if self.wip_warehouse: d.available_qty_at_wip_warehouse = get_latest_stock_qty(d.item_code, self.wip_warehouse) - def set_required_items(self): + def set_required_items(self, reset_only_qty=False): '''set required_items for production to keep track of reserved qty''' - self.required_items = [] + if not reset_only_qty: + self.required_items = [] + if self.bom_no and self.qty: item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=self.qty, fetch_exploded = self.use_multi_level_bom) - for item in sorted(item_dict.values(), key=lambda d: d['idx']): - self.append('required_items', { - 'item_code': item.item_code, - 'item_name': item.item_name, - 'description': item.description, - 'required_qty': item.qty, - 'source_warehouse': item.source_warehouse or item.default_warehouse - }) + if reset_only_qty: + for d in self.get("required_items"): + d.required_qty = item_dict.get(d.item_code).get("qty") + else: + for item in sorted(item_dict.values(), key=lambda d: d['idx']): + self.append('required_items', { + 'item_code': item.item_code, + 'item_name': item.item_name, + 'description': item.description, + 'required_qty': item.qty, + 'source_warehouse': item.source_warehouse or item.default_warehouse + }) self.set_available_qty() diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 51e6c61ea3..d9284050a6 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -762,10 +762,15 @@ def make_production_orders(items, sales_order, company, project=None): out = [] for i in items: + if not i.get("bom"): + frappe.throw(_("Please select BOM against item {0}").format(i.get("item_code"))) + if not i.get("pending_qty"): + frappe.throw(_("Please select Qty against item {0}").format(i.get("item_code"))) + production_order = frappe.get_doc(dict( doctype='Production Order', production_item=i['item_code'], - bom_no=i['bom'], + bom_no=i.get('bom'), qty=i['pending_qty'], company=company, sales_order=sales_order, From aab1182c73436ca39feb365e119ca45ec7c54a94 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 12 Dec 2017 18:45:39 +0530 Subject: [PATCH 3/5] Update stock_entry.js --- erpnext/stock/doctype/stock_entry/stock_entry.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js index 853b20dd22..d45db3eba3 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.js +++ b/erpnext/stock/doctype/stock_entry/stock_entry.js @@ -281,7 +281,7 @@ frappe.ui.form.on('Stock Entry Detail', { 'item_code' : d.item_code, 'warehouse' : cstr(d.s_warehouse) || cstr(d.t_warehouse), 'transfer_qty' : d.transfer_qty, - 'serial_no ' : d.serial_no, + 'serial_no' : d.serial_no, 'bom_no' : d.bom_no, 'expense_account' : d.expense_account, 'cost_center' : d.cost_center, From af9bdfeaa320308fafb5c3a1b3da9859482bf9d1 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 12 Dec 2017 18:50:05 +0530 Subject: [PATCH 4/5] Fixed calculation of taxes and totals if tax is entered as Actual, for Deduction or valuation (#11965) --- erpnext/controllers/taxes_and_totals.py | 3 ++- erpnext/public/js/controllers/taxes_and_totals.js | 8 +++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py index e85e56b4d6..4b73abdef5 100644 --- a/erpnext/controllers/taxes_and_totals.py +++ b/erpnext/controllers/taxes_and_totals.py @@ -399,7 +399,8 @@ class calculate_taxes_and_totals(object): for tax in self.doc.get("taxes"): if tax.charge_type == "Actual": - actual_taxes_dict.setdefault(tax.idx, tax.tax_amount) + tax_amount = self.get_tax_amount_if_for_valuation_or_deduction(tax.tax_amount, tax) + actual_taxes_dict.setdefault(tax.idx, tax_amount) elif tax.row_id in actual_taxes_dict: actual_tax_amount = flt(actual_taxes_dict.get(tax.row_id, 0)) * flt(tax.rate) / 100 actual_taxes_dict.setdefault(tax.idx, actual_tax_amount) diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js index 84624b8997..960807a5c8 100644 --- a/erpnext/public/js/controllers/taxes_and_totals.js +++ b/erpnext/public/js/controllers/taxes_and_totals.js @@ -521,9 +521,11 @@ erpnext.taxes_and_totals = erpnext.payments.extend({ var actual_taxes_dict = {}; $.each(this.frm.doc["taxes"] || [], function(i, tax) { - if (tax.charge_type == "Actual") - actual_taxes_dict[tax.idx] = tax.tax_amount; - else if (actual_taxes_dict[tax.row_id] !== null) { + if (tax.charge_type == "Actual") { + var tax_amount = (tax.category == "Valuation") ? 0.0 : tax.tax_amount; + tax_amount *= (tax.add_deduct_tax == "Deduct") ? -1.0 : 1.0; + actual_taxes_dict[tax.idx] = tax_amount; + } else if (actual_taxes_dict[tax.row_id] !== null) { var actual_tax_amount = flt(actual_taxes_dict[tax.row_id]) * flt(tax.rate) / 100; actual_taxes_dict[tax.idx] = actual_tax_amount; } From 66456dae34ae99df9b3a5beefeb9b38c6e3c62f0 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 12 Dec 2017 19:47:51 +0600 Subject: [PATCH 5/5] bumped to version 9.2.22 --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 2597ed957a..04f881c634 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from erpnext.hooks import regional_overrides -__version__ = '9.2.21' +__version__ = '9.2.22' def get_default_company(user=None): '''Get default company for user'''