From c33412b6ae0b5638127351c4692e9414afe30d66 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 30 Mar 2020 22:44:13 +0530 Subject: [PATCH 1/9] feat: Link blanket order and quotation --- .../doctype/blanket_order/blanket_order.js | 38 ++++++---- .../doctype/blanket_order/blanket_order.py | 70 +++++++++++-------- .../blanket_order/blanket_order_dashboard.py | 2 +- .../public/js/controllers/taxes_and_totals.js | 2 +- .../selling/doctype/quotation/quotation.py | 5 ++ .../quotation_item/quotation_item.json | 31 +++++++- 6 files changed, 100 insertions(+), 48 deletions(-) diff --git a/erpnext/manufacturing/doctype/blanket_order/blanket_order.js b/erpnext/manufacturing/doctype/blanket_order/blanket_order.js index 1cd9446c8b..4c31bd0b7d 100644 --- a/erpnext/manufacturing/doctype/blanket_order/blanket_order.js +++ b/erpnext/manufacturing/doctype/blanket_order/blanket_order.js @@ -14,27 +14,37 @@ frappe.ui.form.on('Blanket Order', { refresh: function(frm) { erpnext.hide_company(); if (frm.doc.customer && frm.doc.docstatus === 1) { - frm.add_custom_button(__('View Orders'), function() { - frappe.set_route('List', 'Sales Order', {blanket_order: frm.doc.name}); - }); - frm.add_custom_button(__("Create Sales Order"), function(){ + frm.add_custom_button(__("Sales Order"), function() { frappe.model.open_mapped_doc({ - method: "erpnext.manufacturing.doctype.blanket_order.blanket_order.make_sales_order", - frm: frm + method: "erpnext.manufacturing.doctype.blanket_order.blanket_order.make_order", + frm: frm, + args: { + doctype: 'Sales Order' + } }); - }).addClass("btn-primary"); + }, __('Create')); + + frm.add_custom_button(__("Quotation"), function() { + frappe.model.open_mapped_doc({ + method: "erpnext.manufacturing.doctype.blanket_order.blanket_order.make_order", + frm: frm, + args: { + doctype: 'Quotation' + } + }); + }, __('Create')); } if (frm.doc.supplier && frm.doc.docstatus === 1) { - frm.add_custom_button(__('View Orders'), function() { - frappe.set_route('List', 'Purchase Order', {blanket_order: frm.doc.name}); - }); - frm.add_custom_button(__("Create Purchase Order"), function(){ + frm.add_custom_button(__("Purchase Order"), function(){ frappe.model.open_mapped_doc({ - method: "erpnext.manufacturing.doctype.blanket_order.blanket_order.make_purchase_order", - frm: frm + method: "erpnext.manufacturing.doctype.blanket_order.blanket_order.make_order", + frm: frm, + args: { + doctype: 'Purchase Order' + } }); - }).addClass("btn-primary"); + }, __('Create')); } }, diff --git a/erpnext/manufacturing/doctype/blanket_order/blanket_order.py b/erpnext/manufacturing/doctype/blanket_order/blanket_order.py index 38118bd78d..5eb4c513b0 100644 --- a/erpnext/manufacturing/doctype/blanket_order/blanket_order.py +++ b/erpnext/manufacturing/doctype/blanket_order/blanket_order.py @@ -17,7 +17,7 @@ class BlanketOrder(Document): def validate_dates(self): if getdate(self.from_date) > getdate(self.to_date): - frappe.throw(_("From date cannot be greater than To date")) + frappe.throw(_("From date cannot be greater than To date")) def update_ordered_qty(self): ref_doctype = "Sales Order" if self.blanket_order_type == "Selling" else "Purchase Order" @@ -35,7 +35,14 @@ class BlanketOrder(Document): d.db_set("ordered_qty", item_ordered_qty.get(d.item_code, 0)) @frappe.whitelist() -def make_sales_order(source_name): +def make_order(source_name): + doctype = frappe.flags.args.doctype + + def update_doc(source_doc, target_doc, source_parent): + if doctype == 'Quotation': + target_doc.quotation_to = 'Customer' + target_doc.party_name = source_doc.customer + def update_item(source, target, source_parent): target_qty = source.get("qty") - source.get("ordered_qty") target.qty = target_qty if not flt(target_qty) < 0 else 0 @@ -49,10 +56,11 @@ def make_sales_order(source_name): target_doc = get_mapped_doc("Blanket Order", source_name, { "Blanket Order": { - "doctype": "Sales Order" + "doctype": doctype, + "postprocess": update_doc }, "Blanket Order Item": { - "doctype": "Sales Order Item", + "doctype": doctype + " Item", "field_map": { "rate": "blanket_order_rate", "parent": "blanket_order" @@ -62,31 +70,31 @@ def make_sales_order(source_name): }) return target_doc -@frappe.whitelist() -def make_purchase_order(source_name): - def update_item(source, target, source_parent): - target_qty = source.get("qty") - source.get("ordered_qty") - target.qty = target_qty if not flt(target_qty) < 0 else 0 - item = get_item_defaults(target.item_code, source_parent.company) - if item: - target.item_name = item.get("item_name") - target.description = item.get("description") - target.uom = item.get("stock_uom") - target.warehouse = item.get("default_warehouse") - target.against_blanket_order = 1 - target.blanket_order = source_name +# @frappe.whitelist() +# def make_purchase_order(source_name): +# def update_item(source, target, source_parent): +# target_qty = source.get("qty") - source.get("ordered_qty") +# target.qty = target_qty if not flt(target_qty) < 0 else 0 +# item = get_item_defaults(target.item_code, source_parent.company) +# if item: +# target.item_name = item.get("item_name") +# target.description = item.get("description") +# target.uom = item.get("stock_uom") +# target.warehouse = item.get("default_warehouse") +# target.against_blanket_order = 1 +# target.blanket_order = source_name - target_doc = get_mapped_doc("Blanket Order", source_name, { - "Blanket Order": { - "doctype": "Purchase Order" - }, - "Blanket Order Item": { - "doctype": "Purchase Order Item", - "field_map": { - "rate": "blanket_order_rate", - "parent": "blanket_order" - }, - "postprocess": update_item - } - }) - return target_doc \ No newline at end of file +# target_doc = get_mapped_doc("Blanket Order", source_name, { +# "Blanket Order": { +# "doctype": "Purchase Order" +# }, +# "Blanket Order Item": { +# "doctype": "Purchase Order Item", +# "field_map": { +# "rate": "blanket_order_rate", +# "parent": "blanket_order" +# }, +# "postprocess": update_item +# } +# }) +# return target_doc \ No newline at end of file diff --git a/erpnext/manufacturing/doctype/blanket_order/blanket_order_dashboard.py b/erpnext/manufacturing/doctype/blanket_order/blanket_order_dashboard.py index ed319a0cef..d9aa0ca49d 100644 --- a/erpnext/manufacturing/doctype/blanket_order/blanket_order_dashboard.py +++ b/erpnext/manufacturing/doctype/blanket_order/blanket_order_dashboard.py @@ -6,7 +6,7 @@ def get_data(): 'fieldname': 'blanket_order', 'transactions': [ { - 'items': ['Purchase Order', 'Sales Order'] + 'items': ['Purchase Order', 'Sales Order', 'Quotation'] } ] } diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js index 9a5b750e8c..dbe48ec654 100644 --- a/erpnext/public/js/controllers/taxes_and_totals.js +++ b/erpnext/public/js/controllers/taxes_and_totals.js @@ -6,7 +6,7 @@ erpnext.taxes_and_totals = erpnext.payments.extend({ apply_pricing_rule_on_item: function(item){ let effective_item_rate = item.price_list_rate; - if (item.parenttype === "Sales Order" && item.blanket_order_rate) { + if (in_list(["Sales Order", "Quotation"], item.parenttype) && item.blanket_order_rate) { effective_item_rate = item.blanket_order_rate; } if(item.margin_type == "Percentage"){ diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index b79c91cef1..7c47b8ac51 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -155,6 +155,11 @@ def _make_sales_order(source_name, target_doc=None, ignore_permissions=False): def update_item(obj, target, source_parent): target.stock_qty = flt(obj.qty) * flt(obj.conversion_factor) + if obj.against_blanket_order: + target.against_blanket_order = obj.against_blanket_order + target.blanket_order = obj.blanket_order + target.blanket_order_rate = obj.blanket_order_rate + doclist = get_mapped_doc("Quotation", source_name, { "Quotation": { "doctype": "Sales Order", diff --git a/erpnext/selling/doctype/quotation_item/quotation_item.json b/erpnext/selling/doctype/quotation_item/quotation_item.json index 3ff5555e82..d50397cfad 100644 --- a/erpnext/selling/doctype/quotation_item/quotation_item.json +++ b/erpnext/selling/doctype/quotation_item/quotation_item.json @@ -55,6 +55,9 @@ "weight_uom", "reference", "warehouse", + "against_blanket_order", + "blanket_order", + "blanket_order_rate", "column_break_30", "prevdoc_doctype", "prevdoc_docname", @@ -573,12 +576,38 @@ "fieldname": "image_section", "fieldtype": "Section Break", "label": "Image" + }, + { + "depends_on": "eval:doc.against_blanket_order", + "fieldname": "blanket_order", + "fieldtype": "Link", + "label": "Blanket Order", + "no_copy": 1, + "options": "Blanket Order", + "print_hide": 1 + }, + { + "depends_on": "eval:doc.against_blanket_order", + "fieldname": "blanket_order_rate", + "fieldtype": "Currency", + "label": "Blanket Order Rate", + "no_copy": 1, + "print_hide": 1, + "read_only": 1 + }, + { + "default": "0", + "fieldname": "against_blanket_order", + "fieldtype": "Check", + "label": "Against Blanket Order", + "no_copy": 1, + "print_hide": 1 } ], "idx": 1, "istable": 1, "links": [], - "modified": "2020-03-05 14:18:58.783751", + "modified": "2020-03-30 18:40:28.782720", "modified_by": "Administrator", "module": "Selling", "name": "Quotation Item", From c014c802dd15ee4cee3633489690fcf3365cb4fa Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 30 Mar 2020 22:50:29 +0530 Subject: [PATCH 2/9] fix: Remove comments --- .../doctype/blanket_order/blanket_order.py | 31 +------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/erpnext/manufacturing/doctype/blanket_order/blanket_order.py b/erpnext/manufacturing/doctype/blanket_order/blanket_order.py index 5eb4c513b0..75b101fe24 100644 --- a/erpnext/manufacturing/doctype/blanket_order/blanket_order.py +++ b/erpnext/manufacturing/doctype/blanket_order/blanket_order.py @@ -68,33 +68,4 @@ def make_order(source_name): "postprocess": update_item } }) - return target_doc - -# @frappe.whitelist() -# def make_purchase_order(source_name): -# def update_item(source, target, source_parent): -# target_qty = source.get("qty") - source.get("ordered_qty") -# target.qty = target_qty if not flt(target_qty) < 0 else 0 -# item = get_item_defaults(target.item_code, source_parent.company) -# if item: -# target.item_name = item.get("item_name") -# target.description = item.get("description") -# target.uom = item.get("stock_uom") -# target.warehouse = item.get("default_warehouse") -# target.against_blanket_order = 1 -# target.blanket_order = source_name - -# target_doc = get_mapped_doc("Blanket Order", source_name, { -# "Blanket Order": { -# "doctype": "Purchase Order" -# }, -# "Blanket Order Item": { -# "doctype": "Purchase Order Item", -# "field_map": { -# "rate": "blanket_order_rate", -# "parent": "blanket_order" -# }, -# "postprocess": update_item -# } -# }) -# return target_doc \ No newline at end of file + return target_doc \ No newline at end of file From 4d9fe69ba59b75a8a7955fb4b2728cc9ec2a630c Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 31 Mar 2020 14:17:53 +0530 Subject: [PATCH 3/9] fix: Test cases --- .../blanket_order/test_blanket_order.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/erpnext/manufacturing/doctype/blanket_order/test_blanket_order.py b/erpnext/manufacturing/doctype/blanket_order/test_blanket_order.py index 455ea06137..3171defdae 100644 --- a/erpnext/manufacturing/doctype/blanket_order/test_blanket_order.py +++ b/erpnext/manufacturing/doctype/blanket_order/test_blanket_order.py @@ -7,13 +7,17 @@ import frappe import unittest from frappe.utils import add_months, today from erpnext import get_company_currency -from .blanket_order import make_sales_order, make_purchase_order +from .blanket_order import make_order class TestBlanketOrder(unittest.TestCase): + def setUp(self): + frappe.flags.args = frappe._dict() + def test_sales_order_creation(self): bo = make_blanket_order(blanket_order_type="Selling") - so = make_sales_order(bo.name) + frappe.flags.args.doctype = 'Sales Order' + so = make_order(bo.name) so.currency = get_company_currency(so.company) so.delivery_date = today() so.items[0].qty = 10 @@ -29,7 +33,8 @@ class TestBlanketOrder(unittest.TestCase): self.assertEqual(so.items[0].qty, bo.items[0].ordered_qty) # test the quantity - so1 = make_sales_order(bo.name) + frappe.flags.args.doctype = 'Sales Order' + so1 = make_order(bo.name) so1.currency = get_company_currency(so1.company) self.assertEqual(so1.items[0].qty, (bo.items[0].qty-bo.items[0].ordered_qty)) @@ -37,7 +42,8 @@ class TestBlanketOrder(unittest.TestCase): def test_purchase_order_creation(self): bo = make_blanket_order(blanket_order_type="Purchasing") - po = make_purchase_order(bo.name) + frappe.flags.args.doctype = 'Purchase Order' + po = make_order(bo.name) po.currency = get_company_currency(po.company) po.schedule_date = today() po.items[0].qty = 10 @@ -53,7 +59,8 @@ class TestBlanketOrder(unittest.TestCase): self.assertEqual(po.items[0].qty, bo.items[0].ordered_qty) # test the quantity - po1 = make_sales_order(bo.name) + frappe.flags.args.doctype = 'Purchase Order' + po1 = make_order(bo.name) po1.currency = get_company_currency(po1.company) self.assertEqual(po1.items[0].qty, (bo.items[0].qty-bo.items[0].ordered_qty)) @@ -78,7 +85,7 @@ def make_blanket_order(**args): "qty": args.quantity or 1000, "rate": args.rate or 100 }) - + bo.insert() bo.submit() return bo \ No newline at end of file From 625acab057332db0af52f5a8e75755928db01323 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 2 Apr 2020 11:18:22 +0530 Subject: [PATCH 4/9] fix: Add duplicate item validation --- .../manufacturing/doctype/blanket_order/blanket_order.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/erpnext/manufacturing/doctype/blanket_order/blanket_order.py b/erpnext/manufacturing/doctype/blanket_order/blanket_order.py index 75b101fe24..f2cb7f3bcc 100644 --- a/erpnext/manufacturing/doctype/blanket_order/blanket_order.py +++ b/erpnext/manufacturing/doctype/blanket_order/blanket_order.py @@ -19,6 +19,15 @@ class BlanketOrder(Document): if getdate(self.from_date) > getdate(self.to_date): frappe.throw(_("From date cannot be greater than To date")) + self.validate_duplicate_items() + + def validate_duplicate_items(self): + item_list = [] + for item in self.items: + if item.item_code in item_list: + frappe.throw(_("Note: Item {0} added multiple times").format(frappe.bold(item.item_code))) + item_list.append(item.item_code) + def update_ordered_qty(self): ref_doctype = "Sales Order" if self.blanket_order_type == "Selling" else "Purchase Order" item_ordered_qty = frappe._dict(frappe.db.sql(""" From d9a17a9be170f52207e174ef6247577fd03691a9 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Thu, 2 Apr 2020 19:57:11 +0530 Subject: [PATCH 5/9] fix (tests): reload doctype --- erpnext/patches.txt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 8aec8bddb9..5f5df6c476 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -626,10 +626,11 @@ erpnext.patches.v12_0.update_ewaybill_field_position erpnext.patches.v12_0.create_accounting_dimensions_in_missing_doctypes erpnext.patches.v11_1.set_status_for_material_request_type_manufacture erpnext.patches.v12_0.move_plaid_settings_to_doctype -execute:frappe.reload_doc('desk', 'doctype','dashboard_chart_link') -execute:frappe.reload_doc('desk', 'doctype','dashboard') -execute:frappe.reload_doc('desk', 'doctype','dashboard_chart_source') -execute:frappe.reload_doc('desk', 'doctype','dashboard_chart') +execute:frappe.reload_doc('desk', 'doctype', 'dashboard_chart_link') +execute:frappe.reload_doc('desk', 'doctype', 'dashboard') +execute:frappe.reload_doc('desk', 'doctype', 'dashboard_chart_source') +execute:frappe.reload_doc('desk', 'doctype', 'dashboard_chart') +execute:frappe.reload_doc('desk', 'doctype', 'dashboard_chart_field') erpnext.patches.v12_0.add_default_dashboards erpnext.patches.v12_0.remove_bank_remittance_custom_fields erpnext.patches.v12_0.generate_leave_ledger_entries From d29dd58e894afa16889b71ab525d8e5fc1aed499 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 2 Apr 2020 21:29:59 +0530 Subject: [PATCH 6/9] fix: Validation --- erpnext/manufacturing/doctype/blanket_order/blanket_order.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/erpnext/manufacturing/doctype/blanket_order/blanket_order.py b/erpnext/manufacturing/doctype/blanket_order/blanket_order.py index f2cb7f3bcc..d7556add80 100644 --- a/erpnext/manufacturing/doctype/blanket_order/blanket_order.py +++ b/erpnext/manufacturing/doctype/blanket_order/blanket_order.py @@ -14,13 +14,12 @@ from erpnext.stock.doctype.item.item import get_item_defaults class BlanketOrder(Document): def validate(self): self.validate_dates() + self.validate_duplicate_items() def validate_dates(self): if getdate(self.from_date) > getdate(self.to_date): frappe.throw(_("From date cannot be greater than To date")) - self.validate_duplicate_items() - def validate_duplicate_items(self): item_list = [] for item in self.items: From 438e0433a3116520d91386f6e0dc726a55f05f83 Mon Sep 17 00:00:00 2001 From: Saqib Date: Fri, 3 Apr 2020 10:02:56 +0530 Subject: [PATCH 7/9] fix: cannot set warehouse on deleting all so items and updating them (#21078) * fix: cannot set warehouse on deleting all so items and updating them * fix: travis * fix: docname is editable in update items dialog --- erpnext/controllers/accounts_controller.py | 15 +++--- erpnext/public/js/utils.js | 3 +- erpnext/stock/get_item_details.py | 60 ++++++++++++++-------- 3 files changed, 49 insertions(+), 29 deletions(-) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index d661bcbf34..76eb56f523 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -19,6 +19,7 @@ from erpnext.accounts.doctype.pricing_rule.utils import (apply_pricing_rule_on_t from erpnext.exceptions import InvalidCurrency from six import text_type from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions +from erpnext.stock.get_item_details import get_item_warehouse force_item_fields = ("item_group", "brand", "stock_uom", "is_fixed_asset", "item_tax_rate", "pricing_rules") @@ -1126,16 +1127,16 @@ def set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, """ Returns a Sales Order Item child item containing the default values """ - p_doctype = frappe.get_doc(parent_doctype, parent_doctype_name) - child_item = frappe.new_doc('Sales Order Item', p_doctype, child_docname) + p_doc = frappe.get_doc(parent_doctype, parent_doctype_name) + child_item = frappe.new_doc('Sales Order Item', p_doc, child_docname) item = frappe.get_doc("Item", item_code) child_item.item_code = item.item_code child_item.item_name = item.item_name child_item.description = item.description - child_item.reqd_by_date = p_doctype.delivery_date + child_item.reqd_by_date = p_doc.delivery_date child_item.uom = item.stock_uom child_item.conversion_factor = get_conversion_factor(item_code, item.stock_uom).get("conversion_factor") or 1.0 - child_item.warehouse = p_doctype.set_warehouse or p_doctype.items[0].warehouse + child_item.warehouse = get_item_warehouse(item, p_doc, overwrite_warehouse=True) return child_item @@ -1143,13 +1144,13 @@ def set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docna """ Returns a Purchase Order Item child item containing the default values """ - p_doctype = frappe.get_doc(parent_doctype, parent_doctype_name) - child_item = frappe.new_doc('Purchase Order Item', p_doctype, child_docname) + p_doc = frappe.get_doc(parent_doctype, parent_doctype_name) + child_item = frappe.new_doc('Purchase Order Item', p_doc, child_docname) item = frappe.get_doc("Item", item_code) child_item.item_code = item.item_code child_item.item_name = item.item_name child_item.description = item.description - child_item.schedule_date = p_doctype.schedule_date + child_item.schedule_date = p_doc.schedule_date child_item.uom = item.stock_uom child_item.conversion_factor = get_conversion_factor(item_code, item.stock_uom).get("conversion_factor") or 1.0 child_item.base_rate = 1 # Initiallize value will update in parent validation diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js index 4eb3175186..4d44eae086 100755 --- a/erpnext/public/js/utils.js +++ b/erpnext/public/js/utils.js @@ -453,7 +453,8 @@ erpnext.utils.update_child_items = function(opts) { fields: [{ fieldtype:'Data', fieldname:"docname", - hidden: 0, + read_only: 1, + hidden: 1, }, { fieldtype:'Link', fieldname:"item_code", diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index 53964f24c4..9c5a8e1be8 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -240,26 +240,13 @@ def get_basic_details(args, item, overwrite_warehouse=True): item_group_defaults = get_item_group_defaults(item.name, args.company) brand_defaults = get_brand_defaults(item.name, args.company) - if overwrite_warehouse or not args.warehouse: - warehouse = ( - args.get("set_warehouse") or - item_defaults.get("default_warehouse") or - item_group_defaults.get("default_warehouse") or - brand_defaults.get("default_warehouse") or - args.warehouse - ) - - if not warehouse: - defaults = frappe.defaults.get_defaults() or {} - warehouse_exists = frappe.db.exists("Warehouse", { - 'name': defaults.default_warehouse, - 'company': args.company - }) - if defaults.get("default_warehouse") and warehouse_exists: - warehouse = defaults.default_warehouse - - else: - warehouse = args.warehouse + defaults = frappe._dict({ + 'item_defaults': item_defaults, + 'item_group_defaults': item_group_defaults, + 'brand_defaults': brand_defaults + }) + + warehouse = get_item_warehouse(item, args, overwrite_warehouse, defaults) if args.get('doctype') == "Material Request" and not args.get('material_request_type'): args['material_request_type'] = frappe.db.get_value('Material Request', @@ -272,7 +259,7 @@ def get_basic_details(args, item, overwrite_warehouse=True): expense_account = get_asset_category_account(fieldname = "fixed_asset_account", item = args.item_code, company= args.company) #Set the UOM to the Default Sales UOM or Default Purchase UOM if configured in the Item Master - if not args.uom: + if not args.get('uom'): if args.get('doctype') in sales_doctypes: args.uom = item.sales_uom if item.sales_uom else item.stock_uom elif (args.get('doctype') in ['Purchase Order', 'Purchase Receipt', 'Purchase Invoice']) or \ @@ -362,6 +349,37 @@ def get_basic_details(args, item, overwrite_warehouse=True): return out +def get_item_warehouse(item, args, overwrite_warehouse, defaults={}): + if not defaults: + defaults = frappe._dict({ + 'item_defaults' : get_item_defaults(item.name, args.company), + 'item_group_defaults' : get_item_group_defaults(item.name, args.company), + 'brand_defaults' : get_brand_defaults(item.name, args.company) + }) + + if overwrite_warehouse or not args.warehouse: + warehouse = ( + args.get("set_warehouse") or + defaults.item_defaults.get("default_warehouse") or + defaults.item_group_defaults.get("default_warehouse") or + defaults.brand_defaults.get("default_warehouse") or + args.get('warehouse') + ) + + if not warehouse: + defaults = frappe.defaults.get_defaults() or {} + warehouse_exists = frappe.db.exists("Warehouse", { + 'name': defaults.default_warehouse, + 'company': args.company + }) + if defaults.get("default_warehouse") and warehouse_exists: + warehouse = defaults.default_warehouse + + else: + warehouse = args.get('warehouse') + + return warehouse + def update_barcode_value(out): from erpnext.accounts.doctype.sales_invoice.pos import get_barcode_data barcode_data = get_barcode_data([out]) From 66c4a087038e75bc0e53cf5744fcb960916e93a7 Mon Sep 17 00:00:00 2001 From: Marica Date: Fri, 3 Apr 2020 10:07:06 +0530 Subject: [PATCH 8/9] fix: Update Received Qty in Material Request as per Stock UOM (#21054) * fix: Update Received Qty in Material Request as per Stock UOM * fix: Process each PR only once * fix: minor suggested changes Co-authored-by: Nabin Hait --- erpnext/patches.txt | 1 + ...ty_in_material_request_as_per_stock_uom.py | 30 +++++++++++++++++++ .../purchase_receipt/purchase_receipt.py | 8 ++--- 3 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 erpnext/patches/v12_0/set_received_qty_in_material_request_as_per_stock_uom.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 8aec8bddb9..bd50ff48f7 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -660,3 +660,4 @@ erpnext.patches.v12_0.set_job_offer_applicant_email erpnext.patches.v12_0.create_irs_1099_field_united_states erpnext.patches.v12_0.move_bank_account_swift_number_to_bank erpnext.patches.v12_0.rename_bank_reconciliation_fields # 2020-01-22 +erpnext.patches.v12_0.set_received_qty_in_material_request_as_per_stock_uom \ No newline at end of file diff --git a/erpnext/patches/v12_0/set_received_qty_in_material_request_as_per_stock_uom.py b/erpnext/patches/v12_0/set_received_qty_in_material_request_as_per_stock_uom.py new file mode 100644 index 0000000000..88c3e2e302 --- /dev/null +++ b/erpnext/patches/v12_0/set_received_qty_in_material_request_as_per_stock_uom.py @@ -0,0 +1,30 @@ +from __future__ import unicode_literals +import frappe + +def execute(): + purchase_receipts = frappe.db.sql(""" + SELECT + parent from `tabPurchase Receipt Item` + WHERE + material_request is not null + AND docstatus=1 + """,as_dict=1) + + purchase_receipts = set([d.parent for d in purchase_receipts]) + + for pr in purchase_receipts: + doc = frappe.get_doc("Purchase Receipt", pr) + doc.status_updater = [ + { + 'source_dt': 'Purchase Receipt Item', + 'target_dt': 'Material Request Item', + 'join_field': 'material_request_item', + 'target_field': 'received_qty', + 'target_parent_dt': 'Material Request', + 'target_parent_field': 'per_received', + 'target_ref_field': 'stock_qty', + 'source_field': 'stock_qty', + 'percent_join_field': 'material_request' + } + ] + doc.update_qty() diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index 3b43690658..c2b38927f7 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -50,8 +50,8 @@ class PurchaseReceipt(BuyingController): 'target_field': 'received_qty', 'target_parent_dt': 'Material Request', 'target_parent_field': 'per_received', - 'target_ref_field': 'qty', - 'source_field': 'qty', + 'target_ref_field': 'stock_qty', + 'source_field': 'stock_qty', 'percent_join_field': 'material_request' }] if cint(self.is_return): @@ -357,7 +357,7 @@ class PurchaseReceipt(BuyingController): if warehouse_with_no_account: frappe.msgprint(_("No accounting entries for the following warehouses") + ": \n" + "\n".join(warehouse_with_no_account)) - + return process_gl_map(gl_entries) def get_asset_gl_entry(self, gl_entries): @@ -628,7 +628,7 @@ def get_item_account_wise_additional_cost(purchase_document): if not landed_cost_vouchers: return - + item_account_wise_cost = {} for lcv in landed_cost_vouchers: From 3251e1304c9c46b5c4f74fd35765eda1ba090136 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 3 Apr 2020 10:08:19 +0530 Subject: [PATCH 9/9] fix: lms quiz type error (#21152) --- erpnext/public/js/education/lms/quiz.js | 2 +- erpnext/www/lms/content.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/public/js/education/lms/quiz.js b/erpnext/public/js/education/lms/quiz.js index 52481291e0..91cbbf4d66 100644 --- a/erpnext/public/js/education/lms/quiz.js +++ b/erpnext/public/js/education/lms/quiz.js @@ -29,7 +29,7 @@ class Quiz { this.questions.push(question) this.wrapper.appendChild(question_wrapper); }) - if (data.activity.is_complete) { + if (data.activity && data.activity.is_complete) { this.disable() let indicator = 'red' let message = 'Your are not allowed to attempt the quiz again.' diff --git a/erpnext/www/lms/content.html b/erpnext/www/lms/content.html index 5607c0814d..cdc71412c4 100644 --- a/erpnext/www/lms/content.html +++ b/erpnext/www/lms/content.html @@ -63,7 +63,7 @@
-

{{ content.name }} ({{ position + 1 }}/{{length}})

+

{{ content.name }} ({{ position + 1 }}/{{length}})

{% endmacro %}