From 6751290988d55a6abfa12bbe7549919bfa396b79 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 24 Aug 2021 14:21:14 +0530 Subject: [PATCH 01/59] fix: Use remove_all from file_manager --- erpnext/regional/italy/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/regional/italy/utils.py b/erpnext/regional/italy/utils.py index ba1aeafc3e9..024f8205686 100644 --- a/erpnext/regional/italy/utils.py +++ b/erpnext/regional/italy/utils.py @@ -6,7 +6,7 @@ import frappe from frappe.utils import flt, cstr from erpnext.controllers.taxes_and_totals import get_itemised_tax from frappe import _ -from frappe.core.doctype.file.file import remove_file +from frappe.utils.file_manager import remove_file from six import string_types from frappe.desk.form.load import get_attachments from erpnext.regional.italy import state_codes From 0fd037eb6a51c2f0046e36229750f7750c923dea Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Thu, 2 Sep 2021 18:28:41 +0530 Subject: [PATCH 02/59] fix: minor linting issues (#27314) (#27315) * fix: syntax error in gratuity * fix: unpacking None into three variables * fix: unexpected kwarg for delete_accounting_dimensions (cherry picked from commit eec40513be4804ef226b5fd68f884dfebd56dff9) Co-authored-by: Ankush Menat --- .../doctype/accounting_dimension/accounting_dimension.py | 4 ++-- erpnext/accounts/doctype/payment_entry/payment_entry.py | 6 +++--- erpnext/payroll/doctype/gratuity_rule/gratuity_rule.py | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py index fac28c92397..4e68d8408b7 100644 --- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py +++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py @@ -47,9 +47,9 @@ class AccountingDimension(Document): def on_trash(self): if frappe.flags.in_test: - delete_accounting_dimension(doc=self, queue='long') + delete_accounting_dimension(doc=self) else: - frappe.enqueue(delete_accounting_dimension, doc=self) + frappe.enqueue(delete_accounting_dimension, doc=self, queue='long') def set_fieldname_and_label(self): if not self.label: diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index c544e7e35a3..9f3cc85742f 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -1390,7 +1390,7 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre }) def get_amounts_based_on_reference_doctype(reference_doctype, ref_doc, party_account_currency, company_currency, reference_name): - total_amount, outstanding_amount, exchange_rate = None + total_amount = outstanding_amount = exchange_rate = None if reference_doctype == "Fees": total_amount = ref_doc.get("grand_total") exchange_rate = 1 @@ -1410,7 +1410,7 @@ def get_amounts_based_on_reference_doctype(reference_doctype, ref_doc, party_acc return total_amount, outstanding_amount, exchange_rate def get_amounts_based_on_ref_doc(reference_doctype, ref_doc, party_account_currency, company_currency): - total_amount, outstanding_amount, exchange_rate = None + total_amount = outstanding_amount = exchange_rate = None if ref_doc.doctype == "Expense Claim": total_amount = flt(ref_doc.total_sanctioned_amount) + flt(ref_doc.total_taxes_and_charges) elif ref_doc.doctype == "Employee Advance": @@ -1450,7 +1450,7 @@ def get_total_amount_exchange_rate_base_on_currency(party_account_currency, comp return total_amount, exchange_rate def get_bill_no_and_update_amounts(reference_doctype, ref_doc, total_amount, exchange_rate, party_account_currency, company_currency): - outstanding_amount, bill_no = None + outstanding_amount = bill_no = None if reference_doctype in ("Sales Invoice", "Purchase Invoice"): outstanding_amount = ref_doc.get("outstanding_amount") bill_no = ref_doc.get("bill_no") diff --git a/erpnext/payroll/doctype/gratuity_rule/gratuity_rule.py b/erpnext/payroll/doctype/gratuity_rule/gratuity_rule.py index 29a6ebe1a6a..49705ddae75 100644 --- a/erpnext/payroll/doctype/gratuity_rule/gratuity_rule.py +++ b/erpnext/payroll/doctype/gratuity_rule/gratuity_rule.py @@ -12,7 +12,7 @@ class GratuityRule(Document): def validate(self): for current_slab in self.gratuity_rule_slabs: if (current_slab.from_year > current_slab.to_year) and current_slab.to_year != 0: - frappe(_("Row {0}: From (Year) can not be greater than To (Year)").format(current_slab.idx)) + frappe.throw(_("Row {0}: From (Year) can not be greater than To (Year)").format(current_slab.idx)) if current_slab.to_year == 0 and current_slab.from_year == 0 and len(self.gratuity_rule_slabs) > 1: frappe.throw(_("You can not define multiple slabs if you have a slab with no lower and upper limits.")) From 7a7665d1d0b7c0767480b6f1c583837e336eb707 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 20 Aug 2021 02:16:49 +0530 Subject: [PATCH 03/59] fix: Return data as dict if the report is grouped by Invoice --- .../report/gross_profit/gross_profit.py | 62 ++++++++++++++++--- 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py index c949d9b74e5..308872c3405 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.py +++ b/erpnext/accounts/report/gross_profit/gross_profit.py @@ -41,15 +41,35 @@ def execute(filters=None): columns = get_columns(group_wise_columns, filters) - for idx, src in enumerate(gross_profit_data.grouped_data): - row = [] - for col in group_wise_columns.get(scrub(filters.group_by)): - row.append(src.get(col)) + if filters.group_by == 'Invoice': + column_names = get_column_names() - row.append(filters.currency) - if idx == len(gross_profit_data.grouped_data)-1: - row[0] = frappe.bold("Total") - data.append(row) + for src in gross_profit_data.si_list: + row = frappe._dict() + row['currency'] = filters.currency + + for col in group_wise_columns.get(scrub(filters.group_by)): + row[column_names[col]] = src.get(col) + + if row.item_code: + row.indent = 1.0 + row.parent_invoice = src.parent_invoice + else: + row.indent = 0.0 + row.parent_invoice = '' + + data.append(row) + + else: + for idx, src in enumerate(gross_profit_data.grouped_data): + row = [] + for col in group_wise_columns.get(scrub(filters.group_by)): + row.append(src.get(col)) + + row.append(filters.currency) + if idx == len(gross_profit_data.grouped_data)-1: + row[0] = frappe.bold("Total") + data.append(row) return columns, data @@ -93,12 +113,38 @@ def get_columns(group_wise_columns, filters): return columns +def get_column_names(): + return frappe._dict({ + 'parent': 'sales_invoice', + 'customer': 'customer', + 'customer_group': 'customer_group', + 'posting_date': 'posting_date', + 'item_code': 'item_code', + 'item_name': 'item_name', + 'item_group': 'item_group', + 'brand': 'brand', + 'description': 'description', + 'warehouse': 'warehouse', + 'qty': 'qty', + 'base_rate': 'avg._selling_rate', + 'buying_rate': 'valuation_rate', + 'base_amount': 'selling_amount', + 'buying_amount': 'buying_amount', + 'gross_profit': 'gross_profit', + 'gross_profit_percent': 'gross_profit_%', + 'project': 'project' + }) + class GrossProfitGenerator(object): def __init__(self, filters=None): self.data = [] self.average_buying_rate = {} self.filters = frappe._dict(filters) self.load_invoice_items() + + # if filters.group_by == 'Invoice': + # self.group_items_by_invoice() + self.load_stock_ledger_entries() self.load_product_bundle() self.load_non_stock_items() From 1f147e5b9e7f4261b8c50070fd4baefaddbb4a8c Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 20 Aug 2021 02:19:18 +0530 Subject: [PATCH 04/59] fix: Display data in tree form --- erpnext/accounts/report/gross_profit/gross_profit.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/report/gross_profit/gross_profit.js b/erpnext/accounts/report/gross_profit/gross_profit.js index ba17a94e8d3..c6c43251acf 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.js +++ b/erpnext/accounts/report/gross_profit/gross_profit.js @@ -36,5 +36,9 @@ frappe.query_reports["Gross Profit"] = { "options": "Invoice\nItem Code\nItem Group\nBrand\nWarehouse\nCustomer\nCustomer Group\nTerritory\nSales Person\nProject", "default": "Invoice" }, - ] + ], + "tree": true, + "name_field": "parent", + "parent_field": "parent_invoice", + "initial_depth": 2 } From fdfae33ff4c74a750da1150c0c02b77fad8f9306 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 20 Aug 2021 02:20:18 +0530 Subject: [PATCH 05/59] fix: Display items as descendants of invoices --- .../report/gross_profit/gross_profit.py | 49 ++++++++++++++++++- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py index 308872c3405..24f590de632 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.py +++ b/erpnext/accounts/report/gross_profit/gross_profit.py @@ -142,8 +142,8 @@ class GrossProfitGenerator(object): self.filters = frappe._dict(filters) self.load_invoice_items() - # if filters.group_by == 'Invoice': - # self.group_items_by_invoice() + if filters.group_by == 'Invoice': + self.group_items_by_invoice() self.load_stock_ledger_entries() self.load_product_bundle() @@ -400,6 +400,51 @@ class GrossProfitGenerator(object): .format(conditions=conditions, sales_person_cols=sales_person_cols, sales_team_table=sales_team_table, match_cond = get_match_cond('Sales Invoice')), self.filters, as_dict=1) + def group_items_by_invoice(self): + parents = [] + + for row in self.si_list: + if row.parent not in parents: + parents.append(row.parent) + + parents_index = 0 + for index, row in enumerate(self.si_list): + if parents_index < len(parents) and row.parent == parents[parents_index]: + invoice = frappe._dict({ + 'parent_invoice': "", + 'parent': row.parent, + 'indent': 0.0, + 'posting_date': row.posting_date, + 'posting_time': row.posting_time, + 'project': row.project, + 'update_stock': row.update_stock, + 'customer': row.customer, + 'customer_group': row.customer_group, + 'customer_group': row.customer_group, + 'item_code': None, + 'item_name': None, + 'description': None, + 'warehouse': None, + 'item_group': None, + 'brand': None, + 'dn_detail': None, + 'delivery_note': None, + 'qty': 0, + 'item_row': None, + 'is_return': row.is_return, + 'cost_center': row.cost_center, + 'base_net_amount': 0 + }) + + self.si_list.insert(index, invoice) + parents_index += 1 + + else: + row.indent = 1.0 + row.parent_invoice = row.parent + row.parent = row.item_code + self.si_list[0].base_net_amount += row.base_net_amount + def load_stock_ledger_entries(self): res = frappe.db.sql("""select item_code, voucher_type, voucher_no, voucher_detail_no, stock_value, warehouse, actual_qty as qty From 416d1ceb6f83691ee4af7efc8fab58c5fb803221 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 20 Aug 2021 02:38:34 +0530 Subject: [PATCH 06/59] fix: Make Invoice row bold --- .../accounts/report/gross_profit/gross_profit.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/report/gross_profit/gross_profit.js b/erpnext/accounts/report/gross_profit/gross_profit.js index c6c43251acf..b3b16a8852a 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.js +++ b/erpnext/accounts/report/gross_profit/gross_profit.js @@ -40,5 +40,16 @@ frappe.query_reports["Gross Profit"] = { "tree": true, "name_field": "parent", "parent_field": "parent_invoice", - "initial_depth": 2 + "initial_depth": 2, + "formatter": function(value, row, column, data, default_formatter) { + value = default_formatter(value, row, column, data); + + if (data && !data.parent_invoice) { + value = $(`${value}`); + var $value = $(value).css("font-weight", "bold"); + value = $value.wrap("

").parent().html(); + } + + return value; + }, } From d2d9f7e75833a0b8dfcf242c80d8c078a9c804cc Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 20 Aug 2021 03:54:19 +0530 Subject: [PATCH 07/59] fix: Assign indent and parent_invoice --- .../report/gross_profit/gross_profit.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py index 24f590de632..e6abbbdf9d3 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.py +++ b/erpnext/accounts/report/gross_profit/gross_profit.py @@ -46,18 +46,13 @@ def execute(filters=None): for src in gross_profit_data.si_list: row = frappe._dict() - row['currency'] = filters.currency + row.indent = src.indent + row.parent_invoice = src.parent_invoice + row.currency = filters.currency for col in group_wise_columns.get(scrub(filters.group_by)): row[column_names[col]] = src.get(col) - if row.item_code: - row.indent = 1.0 - row.parent_invoice = src.parent_invoice - else: - row.indent = 0.0 - row.parent_invoice = '' - data.append(row) else: @@ -433,7 +428,9 @@ class GrossProfitGenerator(object): 'item_row': None, 'is_return': row.is_return, 'cost_center': row.cost_center, - 'base_net_amount': 0 + 'base_net_amount': 0, + 'indent': 0.0, + 'parent_invoice': '' }) self.si_list.insert(index, invoice) @@ -443,7 +440,8 @@ class GrossProfitGenerator(object): row.indent = 1.0 row.parent_invoice = row.parent row.parent = row.item_code - self.si_list[0].base_net_amount += row.base_net_amount + # ind = parents_index-1 if parents_index > 0 else parents_index + # self.si_list[ind].base_net_amount += row.base_net_amount def load_stock_ledger_entries(self): res = frappe.db.sql("""select item_code, voucher_type, voucher_no, From cacecbbaa5ad3d14327ab59d8ff7c8359073d82d Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 20 Aug 2021 06:06:47 +0530 Subject: [PATCH 08/59] fix: Set initial_depth to 3 --- erpnext/accounts/report/gross_profit/gross_profit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/report/gross_profit/gross_profit.js b/erpnext/accounts/report/gross_profit/gross_profit.js index b3b16a8852a..5a6346c1c1d 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.js +++ b/erpnext/accounts/report/gross_profit/gross_profit.js @@ -40,7 +40,7 @@ frappe.query_reports["Gross Profit"] = { "tree": true, "name_field": "parent", "parent_field": "parent_invoice", - "initial_depth": 2, + "initial_depth": 3, "formatter": function(value, row, column, data, default_formatter) { value = default_formatter(value, row, column, data); From 6ab58c7faf718db2d63c313cae656a862c5ee817 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 20 Aug 2021 06:07:53 +0530 Subject: [PATCH 09/59] fix: Add items belonging to Product Bundles as children --- .../report/gross_profit/gross_profit.py | 58 ++++++++++++++++--- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py index e6abbbdf9d3..be2e0332ff6 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.py +++ b/erpnext/accounts/report/gross_profit/gross_profit.py @@ -396,6 +396,10 @@ class GrossProfitGenerator(object): sales_team_table=sales_team_table, match_cond = get_match_cond('Sales Invoice')), self.filters, as_dict=1) def group_items_by_invoice(self): + """ + Turns list of Sales Invoice Items to a tree of Sales Invoices with their Items as children. + """ + parents = [] for row in self.si_list: @@ -407,15 +411,14 @@ class GrossProfitGenerator(object): if parents_index < len(parents) and row.parent == parents[parents_index]: invoice = frappe._dict({ 'parent_invoice': "", - 'parent': row.parent, 'indent': 0.0, + 'parent': row.parent, 'posting_date': row.posting_date, 'posting_time': row.posting_time, 'project': row.project, 'update_stock': row.update_stock, 'customer': row.customer, 'customer_group': row.customer_group, - 'customer_group': row.customer_group, 'item_code': None, 'item_name': None, 'description': None, @@ -428,21 +431,60 @@ class GrossProfitGenerator(object): 'item_row': None, 'is_return': row.is_return, 'cost_center': row.cost_center, - 'base_net_amount': 0, - 'indent': 0.0, - 'parent_invoice': '' + 'base_net_amount': 0 }) self.si_list.insert(index, invoice) parents_index += 1 else: - row.indent = 1.0 - row.parent_invoice = row.parent - row.parent = row.item_code + # skipping the bundle items rows + if not row.indent: + row.indent = 1.0 + row.parent_invoice = row.parent + row.parent = row.item_code + # ind = parents_index-1 if parents_index > 0 else parents_index # self.si_list[ind].base_net_amount += row.base_net_amount + if frappe.db.exists('Product Bundle', row.item_code): + self.add_bundle_items(row, index) + + def add_bundle_items(self, product_bundle, index): + bundle_items = frappe.get_all( + 'Product Bundle Item', + filters = { + 'parent': product_bundle.item_code + }, + fields = ['item_code', 'qty'] + ) + + for i, item in enumerate(bundle_items): + bundle_item = frappe._dict({ + 'parent_invoice': product_bundle.item_code, + 'indent': product_bundle.indent + 1, + 'parent': item.item_code, + 'posting_date': product_bundle.posting_date, + 'posting_time': product_bundle.posting_time, + 'project': product_bundle.project, + 'customer': product_bundle.customer, + 'customer_group': product_bundle.customer_group, + 'item_code': item.item_code, + 'item_name': frappe.db.get_value('Item', item.item_code, 'item_name'), + 'description': frappe.db.get_value('Item', item.item_code, 'description'), + 'warehouse': product_bundle.warehouse, + 'item_group': frappe.db.get_value('Item', item.item_code, 'item_group'), + 'brand': frappe.db.get_value('Item', item.item_code, 'brand'), + 'dn_detail': product_bundle.dn_detail, + 'delivery_note': product_bundle.delivery_note, + 'qty': (product_bundle.qty * item.qty), + 'item_row': None, + 'is_return': product_bundle.is_return, + 'cost_center': product_bundle.cost_center + }) + + self.si_list.insert((index+i+1), bundle_item) + def load_stock_ledger_entries(self): res = frappe.db.sql("""select item_code, voucher_type, voucher_no, voucher_detail_no, stock_value, warehouse, actual_qty as qty From 55781171ccdbd0bbc389940d8a8ead1f39938857 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 20 Aug 2021 18:25:36 +0530 Subject: [PATCH 10/59] fix: Display Items in the format Item Code: Item Name --- .../report/gross_profit/gross_profit.py | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py index be2e0332ff6..0e9640424ec 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.py +++ b/erpnext/accounts/report/gross_profit/gross_profit.py @@ -44,6 +44,9 @@ def execute(filters=None): if filters.group_by == 'Invoice': column_names = get_column_names() + # to display item as Item Code: Item Name + columns[0] = 'Sales Invoice:Link/Item:300' + for src in gross_profit_data.si_list: row = frappe._dict() row.indent = src.indent @@ -424,12 +427,12 @@ class GrossProfitGenerator(object): 'description': None, 'warehouse': None, 'item_group': None, - 'brand': None, - 'dn_detail': None, - 'delivery_note': None, - 'qty': 0, - 'item_row': None, - 'is_return': row.is_return, + 'brand': None, + 'dn_detail': None, + 'delivery_note': None, + 'qty': 0, + 'item_row': None, + 'is_return': row.is_return, 'cost_center': row.cost_center, 'base_net_amount': 0 }) @@ -474,12 +477,12 @@ class GrossProfitGenerator(object): 'description': frappe.db.get_value('Item', item.item_code, 'description'), 'warehouse': product_bundle.warehouse, 'item_group': frappe.db.get_value('Item', item.item_code, 'item_group'), - 'brand': frappe.db.get_value('Item', item.item_code, 'brand'), - 'dn_detail': product_bundle.dn_detail, - 'delivery_note': product_bundle.delivery_note, - 'qty': (product_bundle.qty * item.qty), - 'item_row': None, - 'is_return': product_bundle.is_return, + 'brand': frappe.db.get_value('Item', item.item_code, 'brand'), + 'dn_detail': product_bundle.dn_detail, + 'delivery_note': product_bundle.delivery_note, + 'qty': (product_bundle.qty * item.qty), + 'item_row': None, + 'is_return': product_bundle.is_return, 'cost_center': product_bundle.cost_center }) From 0fa13fb3f11256c4951e70e70f83fc2ff72388db Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 20 Aug 2021 18:26:17 +0530 Subject: [PATCH 11/59] fix: Remove Item Code and Item Name columns --- erpnext/accounts/report/gross_profit/gross_profit.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py index 0e9640424ec..d5296d03011 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.py +++ b/erpnext/accounts/report/gross_profit/gross_profit.py @@ -46,6 +46,8 @@ def execute(filters=None): # to display item as Item Code: Item Name columns[0] = 'Sales Invoice:Link/Item:300' + # removing Item Code and Item Name columns + del columns[4:6] for src in gross_profit_data.si_list: row = frappe._dict() From 316b65facee635e8328f957a3d184cf101e50c65 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Mon, 23 Aug 2021 21:17:32 +0530 Subject: [PATCH 12/59] fix: Calculate total buying_amount and gross profit for each invoice --- .../report/gross_profit/gross_profit.py | 42 +++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py index d5296d03011..273c94c3252 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.py +++ b/erpnext/accounts/report/gross_profit/gross_profit.py @@ -158,7 +158,12 @@ class GrossProfitGenerator(object): self.currency_precision = cint(frappe.db.get_default("currency_precision")) or 3 self.float_precision = cint(frappe.db.get_default("float_precision")) or 2 - for row in self.si_list: + grouped_by_invoice = True if self.filters.get("group_by") == "Invoice" else False + + if grouped_by_invoice: + buying_amount = 0 + + for row in reversed(self.si_list): if self.skip_row(row, self.product_bundles): continue @@ -180,6 +185,13 @@ class GrossProfitGenerator(object): row.buying_amount = flt(self.get_buying_amount(row, row.item_code), self.currency_precision) + if grouped_by_invoice: + if row.indent == 1.0: + buying_amount = row.buying_amount + elif row.indent == 0.0: + row.buying_amount = buying_amount + buying_amount = 0 + # get buying rate if row.qty: row.buying_rate = flt(row.buying_amount / row.qty, self.float_precision) @@ -449,12 +461,36 @@ class GrossProfitGenerator(object): row.parent_invoice = row.parent row.parent = row.item_code - # ind = parents_index-1 if parents_index > 0 else parents_index - # self.si_list[ind].base_net_amount += row.base_net_amount + # if not self.si_list[parents_index-1].base_net_amount: + # self.si_list[parents_index-1].base_net_amount = 0 + + # self.si_list[parents_index-1].base_net_amount += row.base_net_amount + + # print("\n\n\n\n\nRow Details: ", index, ". ", row.parent, ": ", row.base_net_amount) + # print("Ind details: ", parents_index-1, ": ", self.si_list[parents_index-1].base_net_amount, "\n\n\n") if frappe.db.exists('Product Bundle', row.item_code): self.add_bundle_items(row, index) + base_net_amount = 0 + for row in reversed(self.si_list): + if row.indent == 1.0: + base_net_amount += row.get('base_net_amount') + + elif row.indent == 0.0: + row.base_net_amount = base_net_amount + base_net_amount = 0 + + # print("\n"*10) + # for index, row in enumerate(self.si_list): + # if row.indent == 0.0: + # print(index, ". ", row.parent, ": ", row.base_net_amount) + # elif row.indent == 1.0: + # print("\t", index, ". ", row.parent, ": ", row.base_net_amount) + # elif row.indent == 2.0: + # print("\t\t", index, ". ", row.parent, ": ", row.base_net_amount) + # print("") + def add_bundle_items(self, product_bundle, index): bundle_items = frappe.get_all( 'Product Bundle Item', From 3b23341d357528d4798111d8a4b7ec5534020a92 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Tue, 24 Aug 2021 17:57:55 +0530 Subject: [PATCH 13/59] fix: Add Bundle Items table --- erpnext/selling/doctype/quotation/quotation.json | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/erpnext/selling/doctype/quotation/quotation.json b/erpnext/selling/doctype/quotation/quotation.json index 3eba62bc193..6a638a3c2b7 100644 --- a/erpnext/selling/doctype/quotation/quotation.json +++ b/erpnext/selling/doctype/quotation/quotation.json @@ -84,6 +84,8 @@ "rounding_adjustment", "rounded_total", "in_words", + "bundle_items_section", + "packed_items", "payment_schedule_section", "payment_terms_template", "payment_schedule", @@ -926,6 +928,17 @@ "label": "Lost Reasons", "options": "Quotation Lost Reason Detail", "read_only": 1 + }, + { + "fieldname": "packed_items", + "fieldtype": "Table", + "label": "Bundle Items", + "options": "Packed Item" + }, + { + "fieldname": "bundle_items_section", + "fieldtype": "Section Break", + "label": "Bundle Items" } ], "icon": "fa fa-shopping-cart", @@ -933,7 +946,7 @@ "is_submittable": 1, "links": [], "max_attachments": 1, - "modified": "2020-10-30 13:58:59.212060", + "modified": "2021-08-24 17:56:39.199033", "modified_by": "Administrator", "module": "Selling", "name": "Quotation", From 272ca96d2c58cf609429ede60891a5039a7c1888 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Tue, 24 Aug 2021 17:58:23 +0530 Subject: [PATCH 14/59] fix: Populate Bundle Items table --- erpnext/selling/doctype/quotation/quotation.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index e4f8a475816..6cd03dd2791 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -31,6 +31,9 @@ class Quotation(SellingController): if self.items: self.with_items = 1 + from erpnext.stock.doctype.packed_item.packed_item import make_packing_list + make_packing_list(self) + def validate_valid_till(self): if self.valid_till and getdate(self.valid_till) < getdate(self.transaction_date): frappe.throw(_("Valid till date cannot be before transaction date")) From 0967d226edfd4f6927d071fb2c44f03fd079e45f Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Tue, 24 Aug 2021 17:59:11 +0530 Subject: [PATCH 15/59] fix: Add editable Rate column --- erpnext/stock/doctype/packed_item/packed_item.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/packed_item/packed_item.json b/erpnext/stock/doctype/packed_item/packed_item.json index bb396e806f6..00c175f03b6 100644 --- a/erpnext/stock/doctype/packed_item/packed_item.json +++ b/erpnext/stock/doctype/packed_item/packed_item.json @@ -16,6 +16,7 @@ "conversion_factor", "column_break_9", "qty", + "rate", "uom", "section_break_9", "serial_no", @@ -215,13 +216,20 @@ "fieldname": "conversion_factor", "fieldtype": "Float", "label": "Conversion Factor" + }, + { + "fetch_from": "item_code.valuation_rate", + "fieldname": "rate", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Rate" } ], "idx": 1, "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-05-26 07:08:05.111385", + "modified": "2021-08-20 23:31:05.393712", "modified_by": "Administrator", "module": "Stock", "name": "Packed Item", From c37dc7ca33ef87d8d50adcc4b56eb0909eeb8b22 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Tue, 24 Aug 2021 21:42:44 +0530 Subject: [PATCH 16/59] fix: Update Product Bundle price based on the rates of its child Items --- .../stock/doctype/packed_item/packed_item.py | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/erpnext/stock/doctype/packed_item/packed_item.py b/erpnext/stock/doctype/packed_item/packed_item.py index 4ab71bdf629..d2c07d28067 100644 --- a/erpnext/stock/doctype/packed_item/packed_item.py +++ b/erpnext/stock/doctype/packed_item/packed_item.py @@ -85,6 +85,7 @@ def make_packing_list(doc): parent_items.append([d.item_code, d.name]) cleanup_packing_list(doc, parent_items) + update_product_bundle_price(doc, parent_items) def cleanup_packing_list(doc, parent_items): """Remove all those child items which are no longer present in main item table""" @@ -103,6 +104,40 @@ def cleanup_packing_list(doc, parent_items): if d not in delete_list: doc.append("packed_items", d) +def update_product_bundle_price(doc, parent_items): + """Updates the prices of Product Bundles based on the rates of the Items in the bundle.""" + + parent_items_index = 0 + bundle_price = 0 + parent_items_doctype = doc.items[0].doctype + + for bundle_item in doc.get("packed_items"): + if parent_items[parent_items_index][0] == bundle_item.parent_item: + bundle_price += bundle_item.qty * bundle_item.rate + else: + update_parent_item_price(doc, parent_items_doctype, parent_items[parent_items_index][0], bundle_price) + + bundle_price = 0 + parent_items_index += 1 + + # for the last product bundle + update_parent_item_price(doc, parent_items_doctype, parent_items[parent_items_index][0], bundle_price) + doc.reload() + +def update_parent_item_price(doc, parent_items_doctype, parent_item_code, bundle_price): + parent_item_doc_name = frappe.db.get_value( + parent_items_doctype, + { + 'parent': doc.name, + 'item_code': parent_item_code + }, + 'name' + ) + + current_parent_item_price = frappe.db.get_value(parent_items_doctype, parent_item_doc_name, 'amount') + if current_parent_item_price != bundle_price: + frappe.db.set_value(parent_items_doctype, parent_item_doc_name, 'amount', bundle_price) + @frappe.whitelist() def get_items_from_product_bundle(args): args = json.loads(args) From 58ef1e30a5da6a50fc5aeac2899708e84ec46c4b Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Tue, 24 Aug 2021 21:55:54 +0530 Subject: [PATCH 17/59] fix: Update Product Bundle rate based on its updated amount --- erpnext/stock/doctype/packed_item/packed_item.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/erpnext/stock/doctype/packed_item/packed_item.py b/erpnext/stock/doctype/packed_item/packed_item.py index d2c07d28067..ea963ed8e89 100644 --- a/erpnext/stock/doctype/packed_item/packed_item.py +++ b/erpnext/stock/doctype/packed_item/packed_item.py @@ -137,6 +137,11 @@ def update_parent_item_price(doc, parent_items_doctype, parent_item_code, bundle current_parent_item_price = frappe.db.get_value(parent_items_doctype, parent_item_doc_name, 'amount') if current_parent_item_price != bundle_price: frappe.db.set_value(parent_items_doctype, parent_item_doc_name, 'amount', bundle_price) + update_parent_item_rate(parent_items_doctype, parent_item_doc_name, bundle_price) + +def update_parent_item_rate(parent_items_doctype, parent_item_doc_name, bundle_price): + parent_item_qty = frappe.db.get_value(parent_items_doctype, parent_item_doc_name, 'qty') + frappe.db.set_value(parent_items_doctype, parent_item_doc_name, 'rate', (bundle_price/parent_item_qty)) @frappe.whitelist() def get_items_from_product_bundle(args): From 80b3a032fb36be375fe9a5276dd40964d4907700 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Tue, 24 Aug 2021 22:04:03 +0530 Subject: [PATCH 18/59] fix: Add checkbox to enable calculation of Product Bundle price based on child Items' rates --- .../selling_settings/selling_settings.json | 54 ++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/erpnext/selling/doctype/selling_settings/selling_settings.json b/erpnext/selling/doctype/selling_settings/selling_settings.json index f01934b7e6b..bb45a4f0ba8 100644 --- a/erpnext/selling/doctype/selling_settings/selling_settings.json +++ b/erpnext/selling/doctype/selling_settings/selling_settings.json @@ -14,6 +14,13 @@ "close_opportunity_after_days", "default_valid_till", "column_break_5", + "column_break_15", + "maintain_same_sales_rate", + "maintain_same_rate_action", + "editable_price_list_rate", + "validate_selling_price", + "calculate_product_bundle_price_based_on_child_items_rates", + "sales_transactions_settings_section", "so_required", "dn_required", "sales_update_frequency", @@ -152,6 +159,47 @@ "fieldtype": "Link", "label": "Role Allowed to Override Stop Action", "options": "Role" +<<<<<<< HEAD +======= + }, + { + "fieldname": "customer_defaults_section", + "fieldtype": "Section Break", + "label": "Customer Defaults" + }, + { + "fieldname": "column_break_4", + "fieldtype": "Column Break" + }, + { + "fieldname": "crm_settings_section", + "fieldtype": "Section Break", + "label": "CRM Settings" + }, + { + "fieldname": "column_break_9", + "fieldtype": "Column Break" + }, + { + "fieldname": "item_price_settings_section", + "fieldtype": "Section Break", + "label": "Item Price Settings" + }, + { + "fieldname": "column_break_15", + "fieldtype": "Column Break" + }, + { + "fieldname": "sales_transactions_settings_section", + "fieldtype": "Section Break", + "label": "Transaction Settings" + }, + { + "default": "0", + "fieldname": "calculate_product_bundle_price_based_on_child_items_rates", + "fieldtype": "Check", + "label": "Calculate Product Bundle Price based on Child Items' Rates" +>>>>>>> 2293ba302a (fix: Add checkbox to enable calculation of Product Bundle price based on child Items' rates) } ], "icon": "fa fa-cog", @@ -159,7 +207,11 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], +<<<<<<< HEAD "modified": "2021-04-04 20:18:12.814624", +======= + "modified": "2021-08-24 22:02:23.949616", +>>>>>>> 2293ba302a (fix: Add checkbox to enable calculation of Product Bundle price based on child Items' rates) "modified_by": "Administrator", "module": "Selling", "name": "Selling Settings", @@ -178,4 +230,4 @@ "sort_field": "modified", "sort_order": "DESC", "track_changes": 1 -} \ No newline at end of file +} From 39a3ffcb569727178cea0c1d2c80b47e1fcfc933 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Tue, 24 Aug 2021 22:09:12 +0530 Subject: [PATCH 19/59] fix: Make fieldname more concise --- .../selling_settings/selling_settings.json | 42 ++----------------- 1 file changed, 3 insertions(+), 39 deletions(-) diff --git a/erpnext/selling/doctype/selling_settings/selling_settings.json b/erpnext/selling/doctype/selling_settings/selling_settings.json index bb45a4f0ba8..d45ff27a81c 100644 --- a/erpnext/selling/doctype/selling_settings/selling_settings.json +++ b/erpnext/selling/doctype/selling_settings/selling_settings.json @@ -19,8 +19,7 @@ "maintain_same_rate_action", "editable_price_list_rate", "validate_selling_price", - "calculate_product_bundle_price_based_on_child_items_rates", - "sales_transactions_settings_section", + "editable_bundle_item_rates", "so_required", "dn_required", "sales_update_frequency", @@ -159,47 +158,16 @@ "fieldtype": "Link", "label": "Role Allowed to Override Stop Action", "options": "Role" -<<<<<<< HEAD -======= - }, - { - "fieldname": "customer_defaults_section", - "fieldtype": "Section Break", - "label": "Customer Defaults" - }, - { - "fieldname": "column_break_4", - "fieldtype": "Column Break" - }, - { - "fieldname": "crm_settings_section", - "fieldtype": "Section Break", - "label": "CRM Settings" - }, - { - "fieldname": "column_break_9", - "fieldtype": "Column Break" - }, - { - "fieldname": "item_price_settings_section", - "fieldtype": "Section Break", - "label": "Item Price Settings" }, { "fieldname": "column_break_15", "fieldtype": "Column Break" }, - { - "fieldname": "sales_transactions_settings_section", - "fieldtype": "Section Break", - "label": "Transaction Settings" - }, { "default": "0", - "fieldname": "calculate_product_bundle_price_based_on_child_items_rates", + "fieldname": "editable_bundle_item_rates", "fieldtype": "Check", "label": "Calculate Product Bundle Price based on Child Items' Rates" ->>>>>>> 2293ba302a (fix: Add checkbox to enable calculation of Product Bundle price based on child Items' rates) } ], "icon": "fa fa-cog", @@ -207,11 +175,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], -<<<<<<< HEAD - "modified": "2021-04-04 20:18:12.814624", -======= - "modified": "2021-08-24 22:02:23.949616", ->>>>>>> 2293ba302a (fix: Add checkbox to enable calculation of Product Bundle price based on child Items' rates) + "modified": "2021-08-24 22:08:34.470897", "modified_by": "Administrator", "module": "Selling", "name": "Selling Settings", From d730f0e092b036e54e88e74b5e0bad161c50cdf6 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Tue, 24 Aug 2021 22:25:59 +0530 Subject: [PATCH 20/59] fix: Make Rate editable if editable_bundle_item_rates is checked --- .../selling/doctype/selling_settings/selling_settings.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/erpnext/selling/doctype/selling_settings/selling_settings.py b/erpnext/selling/doctype/selling_settings/selling_settings.py index b219e7ecce0..b54559ad288 100644 --- a/erpnext/selling/doctype/selling_settings/selling_settings.py +++ b/erpnext/selling/doctype/selling_settings/selling_settings.py @@ -15,6 +15,7 @@ from frappe.model.document import Document class SellingSettings(Document): def on_update(self): self.toggle_hide_tax_id() + self.toggle_editable_rate_for_bundle_items() def validate(self): for key in ["cust_master_name", "campaign_naming_by", "customer_group", "territory", @@ -33,6 +34,11 @@ class SellingSettings(Document): make_property_setter(doctype, "tax_id", "hidden", self.hide_tax_id, "Check", validate_fields_for_doctype=False) make_property_setter(doctype, "tax_id", "print_hide", self.hide_tax_id, "Check", validate_fields_for_doctype=False) + def toggle_editable_rate_for_bundle_items(self): + editable_bundle_item_rates = cint(self.editable_bundle_item_rates) + + make_property_setter("Packed Item", "rate", "read_only", not(editable_bundle_item_rates), "Check", validate_fields_for_doctype=False) + def set_default_customer_group_and_territory(self): if not self.customer_group: self.customer_group = get_root_of('Customer Group') From ae40c2ad342d9b23cfb398be8b21b65f7b6915e1 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Tue, 24 Aug 2021 23:30:50 +0530 Subject: [PATCH 21/59] fix: Remove qty from Sales Invoice rows --- .../report/gross_profit/gross_profit.py | 54 +++++++------------ 1 file changed, 18 insertions(+), 36 deletions(-) diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py index 273c94c3252..6e1822765e7 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.py +++ b/erpnext/accounts/report/gross_profit/gross_profit.py @@ -193,11 +193,12 @@ class GrossProfitGenerator(object): buying_amount = 0 # get buying rate - if row.qty: - row.buying_rate = flt(row.buying_amount / row.qty, self.float_precision) - row.base_rate = flt(row.base_amount / row.qty, self.float_precision) + if flt(row.qty): + row.buying_rate = flt(row.buying_amount / flt(row.qty), self.float_precision) + row.base_rate = flt(row.base_amount / flt(row.qty), self.float_precision) else: - row.buying_rate, row.base_rate = 0.0, 0.0 + if self.filters.get("group_by") != "Invoice": + row.buying_rate, row.base_rate = 0.0, 0.0 # calculate gross profit row.gross_profit = flt(row.base_amount - row.buying_amount, self.currency_precision) @@ -229,7 +230,7 @@ class GrossProfitGenerator(object): if i==0: new_row = row else: - new_row.qty += row.qty + new_row.qty += flt(row.qty) new_row.buying_amount += flt(row.buying_amount, self.currency_precision) new_row.base_amount += flt(row.base_amount, self.currency_precision) new_row = self.set_average_rate(new_row) @@ -241,10 +242,10 @@ class GrossProfitGenerator(object): and row.item_code in self.returned_invoices[row.parent]: returned_item_rows = self.returned_invoices[row.parent][row.item_code] for returned_item_row in returned_item_rows: - row.qty += returned_item_row.qty + row.qty += flt(returned_item_row.qty) row.base_amount += flt(returned_item_row.base_amount, self.currency_precision) - row.buying_amount = flt(row.qty * row.buying_rate, self.currency_precision) - if row.qty or row.base_amount: + row.buying_amount = flt(flt(row.qty) * row.buying_rate, self.currency_precision) + if flt(row.qty) or row.base_amount: row = self.set_average_rate(row) self.grouped_data.append(row) self.add_to_totals(row) @@ -261,6 +262,8 @@ class GrossProfitGenerator(object): new_row.gross_profit = flt(new_row.base_amount - new_row.buying_amount, self.currency_precision) new_row.gross_profit_percent = flt(((new_row.gross_profit / new_row.base_amount) * 100.0), self.currency_precision) \ if new_row.base_amount else 0 + new_row.buying_rate = flt(new_row.buying_amount / flt(new_row.qty), self.float_precision) if flt(new_row.qty) else 0 + new_row.base_rate = flt(new_row.base_amount / flt(new_row.qty), self.float_precision) if flt(new_row.qty) else 0 def add_to_totals(self, new_row): for key in self.totals: @@ -444,11 +447,12 @@ class GrossProfitGenerator(object): 'brand': None, 'dn_detail': None, 'delivery_note': None, - 'qty': 0, + 'qty': None, 'item_row': None, 'is_return': row.is_return, 'cost_center': row.cost_center, - 'base_net_amount': 0 + 'base_net_amount': 0, + 'base_rate': None }) self.si_list.insert(index, invoice) @@ -463,34 +467,12 @@ class GrossProfitGenerator(object): # if not self.si_list[parents_index-1].base_net_amount: # self.si_list[parents_index-1].base_net_amount = 0 - + # self.si_list[parents_index-1].base_net_amount += row.base_net_amount - # print("\n\n\n\n\nRow Details: ", index, ". ", row.parent, ": ", row.base_net_amount) - # print("Ind details: ", parents_index-1, ": ", self.si_list[parents_index-1].base_net_amount, "\n\n\n") + if frappe.db.exists('Product Bundle', row.item_code): + self.add_bundle_items(row, index) - if frappe.db.exists('Product Bundle', row.item_code): - self.add_bundle_items(row, index) - - base_net_amount = 0 - for row in reversed(self.si_list): - if row.indent == 1.0: - base_net_amount += row.get('base_net_amount') - - elif row.indent == 0.0: - row.base_net_amount = base_net_amount - base_net_amount = 0 - - # print("\n"*10) - # for index, row in enumerate(self.si_list): - # if row.indent == 0.0: - # print(index, ". ", row.parent, ": ", row.base_net_amount) - # elif row.indent == 1.0: - # print("\t", index, ". ", row.parent, ": ", row.base_net_amount) - # elif row.indent == 2.0: - # print("\t\t", index, ". ", row.parent, ": ", row.base_net_amount) - # print("") - def add_bundle_items(self, product_bundle, index): bundle_items = frappe.get_all( 'Product Bundle Item', @@ -518,7 +500,7 @@ class GrossProfitGenerator(object): 'brand': frappe.db.get_value('Item', item.item_code, 'brand'), 'dn_detail': product_bundle.dn_detail, 'delivery_note': product_bundle.delivery_note, - 'qty': (product_bundle.qty * item.qty), + 'qty': (flt(product_bundle.qty) * flt(item.qty)), 'item_row': None, 'is_return': product_bundle.is_return, 'cost_center': product_bundle.cost_center From e52b0612fc149a9fadc8552cd5e1baa950d34c5c Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Tue, 24 Aug 2021 23:32:19 +0530 Subject: [PATCH 22/59] fix: Fetch base_net_total for each Invoice --- erpnext/accounts/report/gross_profit/gross_profit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py index 6e1822765e7..3430ab1f4a9 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.py +++ b/erpnext/accounts/report/gross_profit/gross_profit.py @@ -451,7 +451,7 @@ class GrossProfitGenerator(object): 'item_row': None, 'is_return': row.is_return, 'cost_center': row.cost_center, - 'base_net_amount': 0, + 'base_net_amount': frappe.db.get_value('Sales Invoice', row.parent, 'base_net_total'), 'base_rate': None }) From b14a87eb2b6ee397535ce57e8e2034f359a73e04 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Tue, 24 Aug 2021 23:38:24 +0530 Subject: [PATCH 23/59] fix: Fetch bundle item details --- .../report/gross_profit/gross_profit.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py index 3430ab1f4a9..70703ca9cb0 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.py +++ b/erpnext/accounts/report/gross_profit/gross_profit.py @@ -483,6 +483,8 @@ class GrossProfitGenerator(object): ) for i, item in enumerate(bundle_items): + item_name, description, item_group, brand = self.get_bundle_item_details(item.item_code) + bundle_item = frappe._dict({ 'parent_invoice': product_bundle.item_code, 'indent': product_bundle.indent + 1, @@ -493,11 +495,11 @@ class GrossProfitGenerator(object): 'customer': product_bundle.customer, 'customer_group': product_bundle.customer_group, 'item_code': item.item_code, - 'item_name': frappe.db.get_value('Item', item.item_code, 'item_name'), - 'description': frappe.db.get_value('Item', item.item_code, 'description'), + 'item_name': item_name, + 'description': description, 'warehouse': product_bundle.warehouse, - 'item_group': frappe.db.get_value('Item', item.item_code, 'item_group'), - 'brand': frappe.db.get_value('Item', item.item_code, 'brand'), + 'item_group': item_group, + 'brand': brand, 'dn_detail': product_bundle.dn_detail, 'delivery_note': product_bundle.delivery_note, 'qty': (flt(product_bundle.qty) * flt(item.qty)), @@ -508,6 +510,13 @@ class GrossProfitGenerator(object): self.si_list.insert((index+i+1), bundle_item) + def get_bundle_item_details(self, item_code): + return frappe.db.get_value( + 'Item', + item_code, + ['item_name', 'description', 'item_group', 'brand'] + ) + def load_stock_ledger_entries(self): res = frappe.db.sql("""select item_code, voucher_type, voucher_no, voucher_detail_no, stock_value, warehouse, actual_qty as qty From fc9557bbb6cb23cba3d3316d59322bb27add3e50 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 25 Aug 2021 00:09:07 +0530 Subject: [PATCH 24/59] fix: Calculate total buying_amount for each invoice --- erpnext/accounts/report/gross_profit/gross_profit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py index 70703ca9cb0..776149acfb1 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.py +++ b/erpnext/accounts/report/gross_profit/gross_profit.py @@ -187,7 +187,7 @@ class GrossProfitGenerator(object): if grouped_by_invoice: if row.indent == 1.0: - buying_amount = row.buying_amount + buying_amount += row.buying_amount elif row.indent == 0.0: row.buying_amount = buying_amount buying_amount = 0 From 8478a83148c37b2a14c568c5c04ac5c3917f83cc Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 25 Aug 2021 00:12:43 +0530 Subject: [PATCH 25/59] fix: Only update Product Bundle prices if 'Calculate Product Bundle Price based on Child Items' Rates' is enabled --- erpnext/stock/doctype/packed_item/packed_item.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/packed_item/packed_item.py b/erpnext/stock/doctype/packed_item/packed_item.py index ea963ed8e89..a42bde2a572 100644 --- a/erpnext/stock/doctype/packed_item/packed_item.py +++ b/erpnext/stock/doctype/packed_item/packed_item.py @@ -85,7 +85,9 @@ def make_packing_list(doc): parent_items.append([d.item_code, d.name]) cleanup_packing_list(doc, parent_items) - update_product_bundle_price(doc, parent_items) + + if frappe.db.get_single_value("Selling Settings", "editable_bundle_item_rates"): + update_product_bundle_price(doc, parent_items) def cleanup_packing_list(doc, parent_items): """Remove all those child items which are no longer present in main item table""" From 7ef595217604a0ccffe83617e11aa391d2c2703a Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 25 Aug 2021 00:33:55 +0530 Subject: [PATCH 26/59] fix: Remove base_rate and buying_rate for Invoice rows --- erpnext/accounts/report/gross_profit/gross_profit.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py index 776149acfb1..ad690d3291c 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.py +++ b/erpnext/accounts/report/gross_profit/gross_profit.py @@ -197,7 +197,7 @@ class GrossProfitGenerator(object): row.buying_rate = flt(row.buying_amount / flt(row.qty), self.float_precision) row.base_rate = flt(row.base_amount / flt(row.qty), self.float_precision) else: - if self.filters.get("group_by") != "Invoice": + if self.is_not_invoice_row(row): row.buying_rate, row.base_rate = 0.0, 0.0 # calculate gross profit @@ -244,14 +244,17 @@ class GrossProfitGenerator(object): for returned_item_row in returned_item_rows: row.qty += flt(returned_item_row.qty) row.base_amount += flt(returned_item_row.base_amount, self.currency_precision) - row.buying_amount = flt(flt(row.qty) * row.buying_rate, self.currency_precision) - if flt(row.qty) or row.base_amount: + row.buying_amount = flt(flt(row.qty) * flt(row.buying_rate), self.currency_precision) + if (flt(row.qty) or row.base_amount) and self.is_not_invoice_row(row): row = self.set_average_rate(row) self.grouped_data.append(row) self.add_to_totals(row) self.set_average_gross_profit(self.totals) self.grouped_data.append(self.totals) + def is_not_invoice_row(self, row): + return (self.filters.get("group_by") == "Invoice" and row.indent != 0.0) or self.filters.get("group_by") != "Invoice" + def set_average_rate(self, new_row): self.set_average_gross_profit(new_row) new_row.buying_rate = flt(new_row.buying_amount / new_row.qty, self.float_precision) if new_row.qty else 0 @@ -451,8 +454,7 @@ class GrossProfitGenerator(object): 'item_row': None, 'is_return': row.is_return, 'cost_center': row.cost_center, - 'base_net_amount': frappe.db.get_value('Sales Invoice', row.parent, 'base_net_total'), - 'base_rate': None + 'base_net_amount': frappe.db.get_value('Sales Invoice', row.parent, 'base_net_total') }) self.si_list.insert(index, invoice) From 498377fbbca1c62b5c6d6bea78d06b1e7bc808d0 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 25 Aug 2021 02:49:14 +0530 Subject: [PATCH 27/59] fix: Display only the Invoice rows in bold --- erpnext/accounts/report/gross_profit/gross_profit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/report/gross_profit/gross_profit.js b/erpnext/accounts/report/gross_profit/gross_profit.js index 5a6346c1c1d..856b97d1645 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.js +++ b/erpnext/accounts/report/gross_profit/gross_profit.js @@ -44,7 +44,7 @@ frappe.query_reports["Gross Profit"] = { "formatter": function(value, row, column, data, default_formatter) { value = default_formatter(value, row, column, data); - if (data && !data.parent_invoice) { + if (data && data.indent == 0.0) { value = $(`${value}`); var $value = $(value).css("font-weight", "bold"); value = $value.wrap("

").parent().html(); From fd8657d2f7960286b03aa7f35454a7e22692ccb3 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 25 Aug 2021 02:52:18 +0530 Subject: [PATCH 28/59] fix: Get data when grouped by invoice and otherwise --- .../report/gross_profit/gross_profit.py | 58 ++++++++++--------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py index ad690d3291c..e5941e5bf5a 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.py +++ b/erpnext/accounts/report/gross_profit/gross_profit.py @@ -42,37 +42,43 @@ def execute(filters=None): columns = get_columns(group_wise_columns, filters) if filters.group_by == 'Invoice': - column_names = get_column_names() - - # to display item as Item Code: Item Name - columns[0] = 'Sales Invoice:Link/Item:300' - # removing Item Code and Item Name columns - del columns[4:6] - - for src in gross_profit_data.si_list: - row = frappe._dict() - row.indent = src.indent - row.parent_invoice = src.parent_invoice - row.currency = filters.currency - - for col in group_wise_columns.get(scrub(filters.group_by)): - row[column_names[col]] = src.get(col) - - data.append(row) + get_data_when_grouped_by_invoice(columns, gross_profit_data, filters, group_wise_columns, data) else: - for idx, src in enumerate(gross_profit_data.grouped_data): - row = [] - for col in group_wise_columns.get(scrub(filters.group_by)): - row.append(src.get(col)) - - row.append(filters.currency) - if idx == len(gross_profit_data.grouped_data)-1: - row[0] = frappe.bold("Total") - data.append(row) + get_data_when_not_grouped_by_invoice(gross_profit_data, filters, group_wise_columns, data) return columns, data +def get_data_when_grouped_by_invoice(columns, gross_profit_data, filters, group_wise_columns, data): + column_names = get_column_names() + + # to display item as Item Code: Item Name + columns[0] = 'Sales Invoice:Link/Item:300' + # removing Item Code and Item Name columns + del columns[4:6] + + for src in gross_profit_data.si_list: + row = frappe._dict() + row.indent = src.indent + row.parent_invoice = src.parent_invoice + row.currency = filters.currency + + for col in group_wise_columns.get(scrub(filters.group_by)): + row[column_names[col]] = src.get(col) + + data.append(row) + +def get_data_when_not_grouped_by_invoice(gross_profit_data, filters, group_wise_columns, data): + for idx, src in enumerate(gross_profit_data.grouped_data): + row = [] + for col in group_wise_columns.get(scrub(filters.group_by)): + row.append(src.get(col)) + + row.append(filters.currency) + if idx == len(gross_profit_data.grouped_data)-1: + row[0] = frappe.bold("Total") + data.append(row) + def get_columns(group_wise_columns, filters): columns = [] column_map = frappe._dict({ From 3e177ede137f65e826d88c1caa6725997e4c810f Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 25 Aug 2021 15:20:27 +0530 Subject: [PATCH 29/59] fix: Remove comments --- erpnext/accounts/report/gross_profit/gross_profit.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py index e5941e5bf5a..63786708c6f 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.py +++ b/erpnext/accounts/report/gross_profit/gross_profit.py @@ -473,11 +473,6 @@ class GrossProfitGenerator(object): row.parent_invoice = row.parent row.parent = row.item_code - # if not self.si_list[parents_index-1].base_net_amount: - # self.si_list[parents_index-1].base_net_amount = 0 - - # self.si_list[parents_index-1].base_net_amount += row.base_net_amount - if frappe.db.exists('Product Bundle', row.item_code): self.add_bundle_items(row, index) From 9039effd6950582aec8985fb927a94dd20c0ef8f Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 25 Aug 2021 15:33:53 +0530 Subject: [PATCH 30/59] fix: Get Bundle Items --- .../report/gross_profit/gross_profit.py | 111 ++++++++++-------- 1 file changed, 59 insertions(+), 52 deletions(-) diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py index 63786708c6f..1f6318f2c14 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.py +++ b/erpnext/accounts/report/gross_profit/gross_profit.py @@ -438,31 +438,7 @@ class GrossProfitGenerator(object): parents_index = 0 for index, row in enumerate(self.si_list): if parents_index < len(parents) and row.parent == parents[parents_index]: - invoice = frappe._dict({ - 'parent_invoice': "", - 'indent': 0.0, - 'parent': row.parent, - 'posting_date': row.posting_date, - 'posting_time': row.posting_time, - 'project': row.project, - 'update_stock': row.update_stock, - 'customer': row.customer, - 'customer_group': row.customer_group, - 'item_code': None, - 'item_name': None, - 'description': None, - 'warehouse': None, - 'item_group': None, - 'brand': None, - 'dn_detail': None, - 'delivery_note': None, - 'qty': None, - 'item_row': None, - 'is_return': row.is_return, - 'cost_center': row.cost_center, - 'base_net_amount': frappe.db.get_value('Sales Invoice', row.parent, 'base_net_total') - }) - + invoice = self.get_invoice_row(row) self.si_list.insert(index, invoice) parents_index += 1 @@ -476,8 +452,41 @@ class GrossProfitGenerator(object): if frappe.db.exists('Product Bundle', row.item_code): self.add_bundle_items(row, index) + def get_invoice_row(self, row): + return frappe._dict({ + 'parent_invoice': "", + 'indent': 0.0, + 'parent': row.parent, + 'posting_date': row.posting_date, + 'posting_time': row.posting_time, + 'project': row.project, + 'update_stock': row.update_stock, + 'customer': row.customer, + 'customer_group': row.customer_group, + 'item_code': None, + 'item_name': None, + 'description': None, + 'warehouse': None, + 'item_group': None, + 'brand': None, + 'dn_detail': None, + 'delivery_note': None, + 'qty': None, + 'item_row': None, + 'is_return': row.is_return, + 'cost_center': row.cost_center, + 'base_net_amount': frappe.db.get_value('Sales Invoice', row.parent, 'base_net_total') + }) + def add_bundle_items(self, product_bundle, index): - bundle_items = frappe.get_all( + bundle_items = self.get_bundle_items(product_bundle) + + for i, item in enumerate(bundle_items): + bundle_item = self.get_bundle_item_row(product_bundle, item) + self.si_list.insert((index+i+1), bundle_item) + + def get_bundle_items(self, product_bundle): + return frappe.get_all( 'Product Bundle Item', filters = { 'parent': product_bundle.item_code @@ -485,33 +494,31 @@ class GrossProfitGenerator(object): fields = ['item_code', 'qty'] ) - for i, item in enumerate(bundle_items): - item_name, description, item_group, brand = self.get_bundle_item_details(item.item_code) + def get_bundle_item_row(self, product_bundle, item): + item_name, description, item_group, brand = self.get_bundle_item_details(item.item_code) - bundle_item = frappe._dict({ - 'parent_invoice': product_bundle.item_code, - 'indent': product_bundle.indent + 1, - 'parent': item.item_code, - 'posting_date': product_bundle.posting_date, - 'posting_time': product_bundle.posting_time, - 'project': product_bundle.project, - 'customer': product_bundle.customer, - 'customer_group': product_bundle.customer_group, - 'item_code': item.item_code, - 'item_name': item_name, - 'description': description, - 'warehouse': product_bundle.warehouse, - 'item_group': item_group, - 'brand': brand, - 'dn_detail': product_bundle.dn_detail, - 'delivery_note': product_bundle.delivery_note, - 'qty': (flt(product_bundle.qty) * flt(item.qty)), - 'item_row': None, - 'is_return': product_bundle.is_return, - 'cost_center': product_bundle.cost_center - }) - - self.si_list.insert((index+i+1), bundle_item) + return frappe._dict({ + 'parent_invoice': product_bundle.item_code, + 'indent': product_bundle.indent + 1, + 'parent': item.item_code, + 'posting_date': product_bundle.posting_date, + 'posting_time': product_bundle.posting_time, + 'project': product_bundle.project, + 'customer': product_bundle.customer, + 'customer_group': product_bundle.customer_group, + 'item_code': item.item_code, + 'item_name': item_name, + 'description': description, + 'warehouse': product_bundle.warehouse, + 'item_group': item_group, + 'brand': brand, + 'dn_detail': product_bundle.dn_detail, + 'delivery_note': product_bundle.delivery_note, + 'qty': (flt(product_bundle.qty) * flt(item.qty)), + 'item_row': None, + 'is_return': product_bundle.is_return, + 'cost_center': product_bundle.cost_center + }) def get_bundle_item_details(self, item_code): return frappe.db.get_value( From 084b27bb34c919f6c7eba629ec085825d0802a05 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 25 Aug 2021 15:40:42 +0530 Subject: [PATCH 31/59] fix: Return if there are no Items --- erpnext/stock/doctype/packed_item/packed_item.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erpnext/stock/doctype/packed_item/packed_item.py b/erpnext/stock/doctype/packed_item/packed_item.py index a42bde2a572..d8a8959a4df 100644 --- a/erpnext/stock/doctype/packed_item/packed_item.py +++ b/erpnext/stock/doctype/packed_item/packed_item.py @@ -109,6 +109,9 @@ def cleanup_packing_list(doc, parent_items): def update_product_bundle_price(doc, parent_items): """Updates the prices of Product Bundles based on the rates of the Items in the bundle.""" + if not doc.get('items'): + return + parent_items_index = 0 bundle_price = 0 parent_items_doctype = doc.items[0].doctype From 2b56e6280574ac891780cfd66c26ccf3d99a4784 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 27 Aug 2021 01:02:34 +0530 Subject: [PATCH 32/59] fix: Calculate Product Bundle price based on the prices of its child items --- .../stock/doctype/packed_item/packed_item.py | 38 ++++++++----------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/erpnext/stock/doctype/packed_item/packed_item.py b/erpnext/stock/doctype/packed_item/packed_item.py index d8a8959a4df..4f1a67597d9 100644 --- a/erpnext/stock/doctype/packed_item/packed_item.py +++ b/erpnext/stock/doctype/packed_item/packed_item.py @@ -114,39 +114,31 @@ def update_product_bundle_price(doc, parent_items): parent_items_index = 0 bundle_price = 0 - parent_items_doctype = doc.items[0].doctype for bundle_item in doc.get("packed_items"): if parent_items[parent_items_index][0] == bundle_item.parent_item: - bundle_price += bundle_item.qty * bundle_item.rate + bundle_item_rate = bundle_item.rate if bundle_item.rate else 0 + bundle_price += bundle_item.qty * bundle_item_rate else: - update_parent_item_price(doc, parent_items_doctype, parent_items[parent_items_index][0], bundle_price) + update_parent_item_price(doc, parent_items[parent_items_index][0], bundle_price) bundle_price = 0 parent_items_index += 1 # for the last product bundle - update_parent_item_price(doc, parent_items_doctype, parent_items[parent_items_index][0], bundle_price) - doc.reload() - -def update_parent_item_price(doc, parent_items_doctype, parent_item_code, bundle_price): - parent_item_doc_name = frappe.db.get_value( - parent_items_doctype, - { - 'parent': doc.name, - 'item_code': parent_item_code - }, - 'name' - ) - - current_parent_item_price = frappe.db.get_value(parent_items_doctype, parent_item_doc_name, 'amount') - if current_parent_item_price != bundle_price: - frappe.db.set_value(parent_items_doctype, parent_item_doc_name, 'amount', bundle_price) - update_parent_item_rate(parent_items_doctype, parent_item_doc_name, bundle_price) + if doc.get("packed_items"): + update_parent_item_price(doc, parent_items[parent_items_index][0], bundle_price) + +def update_parent_item_price(doc, parent_item_code, bundle_price): + parent_item_doc = doc.get('items', {'item_code': parent_item_code})[0] -def update_parent_item_rate(parent_items_doctype, parent_item_doc_name, bundle_price): - parent_item_qty = frappe.db.get_value(parent_items_doctype, parent_item_doc_name, 'qty') - frappe.db.set_value(parent_items_doctype, parent_item_doc_name, 'rate', (bundle_price/parent_item_qty)) + current_parent_item_price = parent_item_doc.amount + if current_parent_item_price != bundle_price: + parent_item_doc.amount = bundle_price + update_parent_item_rate(parent_item_doc, bundle_price) + +def update_parent_item_rate(parent_item_doc, bundle_price): + parent_item_doc.rate = bundle_price/parent_item_doc.qty @frappe.whitelist() def get_items_from_product_bundle(args): From 1ecec7154bfe1d4ae012be5b832d0f58b8100ba0 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 27 Aug 2021 01:06:48 +0530 Subject: [PATCH 33/59] fix: Enable Fetch If Empty for Rate --- erpnext/stock/doctype/packed_item/packed_item.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/packed_item/packed_item.json b/erpnext/stock/doctype/packed_item/packed_item.json index 00c175f03b6..729ab2c5862 100644 --- a/erpnext/stock/doctype/packed_item/packed_item.json +++ b/erpnext/stock/doctype/packed_item/packed_item.json @@ -219,6 +219,7 @@ }, { "fetch_from": "item_code.valuation_rate", + "fetch_if_empty": 1, "fieldname": "rate", "fieldtype": "Currency", "in_list_view": 1, @@ -229,7 +230,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-08-20 23:31:05.393712", + "modified": "2021-08-27 01:04:30.242238", "modified_by": "Administrator", "module": "Stock", "name": "Packed Item", From b9a33eca97a0694814c3332c92be03cfce26a632 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 27 Aug 2021 01:14:23 +0530 Subject: [PATCH 34/59] fix: Display Bundle Items right below the Items table --- erpnext/selling/doctype/quotation/quotation.json | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/erpnext/selling/doctype/quotation/quotation.json b/erpnext/selling/doctype/quotation/quotation.json index 6a638a3c2b7..007fa338378 100644 --- a/erpnext/selling/doctype/quotation/quotation.json +++ b/erpnext/selling/doctype/quotation/quotation.json @@ -43,6 +43,7 @@ "ignore_pricing_rule", "items_section", "items", + "packed_items", "pricing_rule_details", "pricing_rules", "sec_break23", @@ -84,8 +85,6 @@ "rounding_adjustment", "rounded_total", "in_words", - "bundle_items_section", - "packed_items", "payment_schedule_section", "payment_terms_template", "payment_schedule", @@ -934,11 +933,6 @@ "fieldtype": "Table", "label": "Bundle Items", "options": "Packed Item" - }, - { - "fieldname": "bundle_items_section", - "fieldtype": "Section Break", - "label": "Bundle Items" } ], "icon": "fa fa-shopping-cart", @@ -946,7 +940,7 @@ "is_submittable": 1, "links": [], "max_attachments": 1, - "modified": "2021-08-24 17:56:39.199033", + "modified": "2021-08-27 01:09:54.587572", "modified_by": "Administrator", "module": "Selling", "name": "Quotation", From 288d0191ab7f0b9995ab9782296146952b849e0f Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 27 Aug 2021 01:15:01 +0530 Subject: [PATCH 35/59] fix: Make Rate column read only by default --- erpnext/stock/doctype/packed_item/packed_item.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/packed_item/packed_item.json b/erpnext/stock/doctype/packed_item/packed_item.json index 729ab2c5862..e85d04966e9 100644 --- a/erpnext/stock/doctype/packed_item/packed_item.json +++ b/erpnext/stock/doctype/packed_item/packed_item.json @@ -223,14 +223,15 @@ "fieldname": "rate", "fieldtype": "Currency", "in_list_view": 1, - "label": "Rate" + "label": "Rate", + "read_only": 1 } ], "idx": 1, "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-08-27 01:04:30.242238", + "modified": "2021-08-27 01:13:40.138203", "modified_by": "Administrator", "module": "Stock", "name": "Packed Item", From bb7ad885da433159b8886fe0e3cd12c24f8c2d33 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 27 Aug 2021 01:21:52 +0530 Subject: [PATCH 36/59] fix: Hide Rate of Bundle Items while printing --- erpnext/stock/doctype/packed_item/packed_item.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/packed_item/packed_item.json b/erpnext/stock/doctype/packed_item/packed_item.json index e85d04966e9..6f0f527d139 100644 --- a/erpnext/stock/doctype/packed_item/packed_item.json +++ b/erpnext/stock/doctype/packed_item/packed_item.json @@ -224,14 +224,14 @@ "fieldtype": "Currency", "in_list_view": 1, "label": "Rate", - "read_only": 1 + "print_hide": 1 } ], "idx": 1, "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-08-27 01:13:40.138203", + "modified": "2021-08-27 01:20:55.308822", "modified_by": "Administrator", "module": "Stock", "name": "Packed Item", From ba73df161dd8b99544860c7ea9ab05724cfaf2df Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 27 Aug 2021 01:48:46 +0530 Subject: [PATCH 37/59] fix: Make Sales Order field editable so the PO can be linked with an SO later --- .../doctype/purchase_order_item/purchase_order_item.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json index 132dd1769c5..01526fc65a5 100644 --- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json +++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json @@ -488,7 +488,6 @@ "no_copy": 1, "options": "Sales Order", "print_hide": 1, - "read_only": 1, "search_index": 1 }, { @@ -836,7 +835,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-06-28 19:22:22.715365", + "modified": "2021-08-27 01:35:37.755413", "modified_by": "Administrator", "module": "Buying", "name": "Purchase Order Item", From f10fdb4eeb14b7a795c05031215795f6db4f1bff Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 27 Aug 2021 01:49:28 +0530 Subject: [PATCH 38/59] feat: Add Bundle Items table --- .../purchase_order/purchase_order.json | 477 +++++------------- 1 file changed, 124 insertions(+), 353 deletions(-) diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json index a55a0b7f9fc..873ab709996 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.json +++ b/erpnext/buying/doctype/purchase_order/purchase_order.json @@ -61,6 +61,7 @@ "set_warehouse", "items_section", "items", + "packed_items", "sb_last_purchase", "total_qty", "base_total", @@ -144,9 +145,7 @@ { "fieldname": "supplier_section", "fieldtype": "Section Break", - "options": "fa fa-user", - "show_days": 1, - "show_seconds": 1 + "options": "fa fa-user" }, { "allow_on_submit": 1, @@ -156,9 +155,7 @@ "hidden": 1, "label": "Title", "no_copy": 1, - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "fieldname": "naming_series", @@ -170,9 +167,7 @@ "options": "PUR-ORD-.YYYY.-", "print_hide": 1, "reqd": 1, - "set_only_once": 1, - "show_days": 1, - "show_seconds": 1 + "set_only_once": 1 }, { "bold": 1, @@ -186,18 +181,14 @@ "options": "Supplier", "print_hide": 1, "reqd": 1, - "search_index": 1, - "show_days": 1, - "show_seconds": 1 + "search_index": 1 }, { "depends_on": "eval:doc.supplier && doc.docstatus===0 && (!(doc.items && doc.items.length) || (doc.items.length==1 && !doc.items[0].item_code))", "description": "Fetch items based on Default Supplier.", "fieldname": "get_items_from_open_material_requests", "fieldtype": "Button", - "label": "Get Items from Open Material Requests", - "show_days": 1, - "show_seconds": 1 + "label": "Get Items from Open Material Requests" }, { "bold": 1, @@ -206,9 +197,7 @@ "fieldtype": "Data", "in_global_search": 1, "label": "Supplier Name", - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "company", @@ -220,17 +209,13 @@ "options": "Company", "print_hide": 1, "remember_last_selected_value": 1, - "reqd": 1, - "show_days": 1, - "show_seconds": 1 + "reqd": 1 }, { "fieldname": "column_break1", "fieldtype": "Column Break", "oldfieldtype": "Column Break", "print_width": "50%", - "show_days": 1, - "show_seconds": 1, "width": "50%" }, { @@ -242,35 +227,27 @@ "oldfieldname": "transaction_date", "oldfieldtype": "Date", "reqd": 1, - "search_index": 1, - "show_days": 1, - "show_seconds": 1 + "search_index": 1 }, { "allow_on_submit": 1, "fieldname": "schedule_date", "fieldtype": "Date", - "label": "Required By", - "show_days": 1, - "show_seconds": 1 + "label": "Required By" }, { "allow_on_submit": 1, "depends_on": "eval:doc.docstatus===1", "fieldname": "order_confirmation_no", "fieldtype": "Data", - "label": "Order Confirmation No", - "show_days": 1, - "show_seconds": 1 + "label": "Order Confirmation No" }, { "allow_on_submit": 1, "depends_on": "eval:doc.order_confirmation_no", "fieldname": "order_confirmation_date", "fieldtype": "Date", - "label": "Order Confirmation Date", - "show_days": 1, - "show_seconds": 1 + "label": "Order Confirmation Date" }, { "fieldname": "amended_from", @@ -282,25 +259,19 @@ "oldfieldtype": "Data", "options": "Purchase Order", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "drop_ship", "fieldtype": "Section Break", - "label": "Drop Ship", - "show_days": 1, - "show_seconds": 1 + "label": "Drop Ship" }, { "fieldname": "customer", "fieldtype": "Link", "label": "Customer", "options": "Customer", - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "bold": 1, @@ -308,41 +279,31 @@ "fieldtype": "Data", "label": "Customer Name", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "column_break_19", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "fieldname": "customer_contact_person", "fieldtype": "Link", "label": "Customer Contact", - "options": "Contact", - "show_days": 1, - "show_seconds": 1 + "options": "Contact" }, { "fieldname": "customer_contact_display", "fieldtype": "Small Text", "hidden": 1, "label": "Customer Contact", - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "fieldname": "customer_contact_mobile", "fieldtype": "Small Text", "hidden": 1, "label": "Customer Mobile No", - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "fieldname": "customer_contact_email", @@ -350,35 +311,27 @@ "hidden": 1, "label": "Customer Contact Email", "options": "Email", - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "collapsible": 1, "fieldname": "section_addresses", "fieldtype": "Section Break", - "label": "Address and Contact", - "show_days": 1, - "show_seconds": 1 + "label": "Address and Contact" }, { "fieldname": "supplier_address", "fieldtype": "Link", "label": "Supplier Address", "options": "Address", - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "fieldname": "contact_person", "fieldtype": "Link", "label": "Supplier Contact", "options": "Contact", - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "fieldname": "address_display", @@ -405,42 +358,32 @@ "label": "Contact Email", "options": "Email", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "col_break_address", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "fieldname": "shipping_address", "fieldtype": "Link", "label": "Company Shipping Address", "options": "Address", - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "fieldname": "shipping_address_display", "fieldtype": "Small Text", "label": "Shipping Address Details", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "collapsible": 1, "fieldname": "currency_and_price_list", "fieldtype": "Section Break", "label": "Currency and Price List", - "options": "fa fa-tag", - "show_days": 1, - "show_seconds": 1 + "options": "fa fa-tag" }, { "fieldname": "currency", @@ -450,9 +393,7 @@ "oldfieldtype": "Select", "options": "Currency", "print_hide": 1, - "reqd": 1, - "show_days": 1, - "show_seconds": 1 + "reqd": 1 }, { "fieldname": "conversion_rate", @@ -462,24 +403,18 @@ "oldfieldtype": "Currency", "precision": "9", "print_hide": 1, - "reqd": 1, - "show_days": 1, - "show_seconds": 1 + "reqd": 1 }, { "fieldname": "cb_price_list", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "fieldname": "buying_price_list", "fieldtype": "Link", "label": "Price List", "options": "Price List", - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "fieldname": "price_list_currency", @@ -487,18 +422,14 @@ "label": "Price List Currency", "options": "Currency", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "plc_conversion_rate", "fieldtype": "Float", "label": "Price List Exchange Rate", "precision": "9", - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "default": "0", @@ -507,9 +438,7 @@ "label": "Ignore Pricing Rule", "no_copy": 1, "permlevel": 1, - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "fieldname": "sec_warehouse", @@ -522,15 +451,11 @@ "fieldtype": "Link", "label": "Set Target Warehouse", "options": "Warehouse", - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "fieldname": "col_break_warehouse", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "default": "No", @@ -539,35 +464,27 @@ "in_standard_filter": 1, "label": "Supply Raw Materials", "options": "No\nYes", - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "depends_on": "eval:doc.is_subcontracted==\"Yes\"", "fieldname": "supplier_warehouse", "fieldtype": "Link", "label": "Supplier Warehouse", - "options": "Warehouse", - "show_days": 1, - "show_seconds": 1 + "options": "Warehouse" }, { "fieldname": "items_section", "fieldtype": "Section Break", "hide_border": 1, "oldfieldtype": "Section Break", - "options": "fa fa-shopping-cart", - "show_days": 1, - "show_seconds": 1 + "options": "fa fa-shopping-cart" }, { "fieldname": "scan_barcode", "fieldtype": "Data", "label": "Scan Barcode", - "options": "Barcode", - "show_days": 1, - "show_seconds": 1 + "options": "Barcode" }, { "allow_bulk_edit": 1, @@ -577,34 +494,26 @@ "oldfieldname": "po_details", "oldfieldtype": "Table", "options": "Purchase Order Item", - "reqd": 1, - "show_days": 1, - "show_seconds": 1 + "reqd": 1 }, { "collapsible": 1, "fieldname": "section_break_48", "fieldtype": "Section Break", - "label": "Pricing Rules", - "show_days": 1, - "show_seconds": 1 + "label": "Pricing Rules" }, { "fieldname": "pricing_rules", "fieldtype": "Table", "label": "Purchase Order Pricing Rule", "options": "Pricing Rule Detail", - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "collapsible_depends_on": "supplied_items", "fieldname": "raw_material_details", "fieldtype": "Section Break", - "label": "Raw Materials Supplied", - "show_days": 1, - "show_seconds": 1 + "label": "Raw Materials Supplied" }, { "fieldname": "supplied_items", @@ -615,23 +524,17 @@ "oldfieldtype": "Table", "options": "Purchase Order Item Supplied", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "sb_last_purchase", - "fieldtype": "Section Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Section Break" }, { "fieldname": "total_qty", "fieldtype": "Float", "label": "Total Quantity", - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "base_total", @@ -639,9 +542,7 @@ "label": "Total (Company Currency)", "options": "Company:company:default_currency", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "base_net_total", @@ -652,24 +553,18 @@ "oldfieldtype": "Currency", "options": "Company:company:default_currency", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "column_break_26", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "fieldname": "total", "fieldtype": "Currency", "label": "Total", "options": "currency", - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "net_total", @@ -679,26 +574,20 @@ "oldfieldtype": "Currency", "options": "currency", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "total_net_weight", "fieldtype": "Float", "label": "Total Net Weight", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "taxes_section", "fieldtype": "Section Break", "oldfieldtype": "Section Break", - "options": "fa fa-money", - "show_days": 1, - "show_seconds": 1 + "options": "fa fa-money" }, { "fieldname": "taxes_and_charges", @@ -707,24 +596,18 @@ "oldfieldname": "purchase_other_charges", "oldfieldtype": "Link", "options": "Purchase Taxes and Charges Template", - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "fieldname": "column_break_50", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "fieldname": "shipping_rule", "fieldtype": "Link", "label": "Shipping Rule", "options": "Shipping Rule", - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "fieldname": "section_break_52", @@ -737,17 +620,13 @@ "label": "Purchase Taxes and Charges", "oldfieldname": "purchase_tax_details", "oldfieldtype": "Table", - "options": "Purchase Taxes and Charges", - "show_days": 1, - "show_seconds": 1 + "options": "Purchase Taxes and Charges" }, { "collapsible": 1, "fieldname": "sec_tax_breakup", "fieldtype": "Section Break", - "label": "Tax Breakup", - "show_days": 1, - "show_seconds": 1 + "label": "Tax Breakup" }, { "fieldname": "other_charges_calculation", @@ -756,18 +635,14 @@ "no_copy": 1, "oldfieldtype": "HTML", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "totals", "fieldtype": "Section Break", "label": "Taxes and Charges", "oldfieldtype": "Section Break", - "options": "fa fa-money", - "show_days": 1, - "show_seconds": 1 + "options": "fa fa-money" }, { "depends_on": "base_taxes_and_charges_added", @@ -778,9 +653,7 @@ "oldfieldtype": "Currency", "options": "Company:company:default_currency", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "depends_on": "base_taxes_and_charges_deducted", @@ -791,9 +664,7 @@ "oldfieldtype": "Currency", "options": "Company:company:default_currency", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "depends_on": "base_total_taxes_and_charges", @@ -805,15 +676,11 @@ "oldfieldtype": "Currency", "options": "Company:company:default_currency", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "column_break_39", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "depends_on": "taxes_and_charges_added", @@ -824,9 +691,7 @@ "oldfieldtype": "Currency", "options": "currency", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "depends_on": "taxes_and_charges_deducted", @@ -837,9 +702,7 @@ "oldfieldtype": "Currency", "options": "currency", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "depends_on": "total_taxes_and_charges", @@ -848,18 +711,14 @@ "label": "Total Taxes and Charges", "options": "currency", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "collapsible": 1, "collapsible_depends_on": "apply_discount_on", "fieldname": "discount_section", "fieldtype": "Section Break", - "label": "Additional Discount", - "show_days": 1, - "show_seconds": 1 + "label": "Additional Discount" }, { "default": "Grand Total", @@ -867,9 +726,7 @@ "fieldtype": "Select", "label": "Apply Additional Discount On", "options": "\nGrand Total\nNet Total", - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "fieldname": "base_discount_amount", @@ -877,32 +734,24 @@ "label": "Additional Discount Amount (Company Currency)", "options": "Company:company:default_currency", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "column_break_45", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "fieldname": "additional_discount_percentage", "fieldtype": "Float", "label": "Additional Discount Percentage", - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "fieldname": "discount_amount", "fieldtype": "Currency", "label": "Additional Discount Amount", "options": "currency", - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "fieldname": "totals_section", @@ -918,9 +767,7 @@ "oldfieldtype": "Currency", "options": "Company:company:default_currency", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "depends_on": "eval:!doc.disable_rounded_total", @@ -930,9 +777,7 @@ "no_copy": 1, "options": "Company:company:default_currency", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "description": "In Words will be visible once you save the Purchase Order.", @@ -943,9 +788,7 @@ "oldfieldname": "in_words", "oldfieldtype": "Data", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "base_rounded_total", @@ -955,16 +798,12 @@ "oldfieldtype": "Currency", "options": "Company:company:default_currency", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "column_break4", "fieldtype": "Column Break", - "oldfieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "oldfieldtype": "Column Break" }, { "fieldname": "grand_total", @@ -974,9 +813,7 @@ "oldfieldname": "grand_total_import", "oldfieldtype": "Currency", "options": "currency", - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "depends_on": "eval:!doc.disable_rounded_total", @@ -986,26 +823,20 @@ "no_copy": 1, "options": "currency", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "rounded_total", "fieldtype": "Currency", "label": "Rounded Total", "options": "currency", - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "default": "0", "fieldname": "disable_rounded_total", "fieldtype": "Check", - "label": "Disable Rounded Total", - "show_days": 1, - "show_seconds": 1 + "label": "Disable Rounded Total" }, { "fieldname": "in_words", @@ -1015,9 +846,7 @@ "oldfieldname": "in_words_import", "oldfieldtype": "Data", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "advance_paid", @@ -1026,25 +855,19 @@ "no_copy": 1, "options": "party_account_currency", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "collapsible": 1, "fieldname": "payment_schedule_section", "fieldtype": "Section Break", - "label": "Payment Terms", - "show_days": 1, - "show_seconds": 1 + "label": "Payment Terms" }, { "fieldname": "payment_terms_template", "fieldtype": "Link", "label": "Payment Terms Template", - "options": "Payment Terms Template", - "show_days": 1, - "show_seconds": 1 + "options": "Payment Terms Template" }, { "fieldname": "payment_schedule", @@ -1052,9 +875,7 @@ "label": "Payment Schedule", "no_copy": 1, "options": "Payment Schedule", - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "collapsible": 1, @@ -1063,9 +884,7 @@ "fieldtype": "Section Break", "label": "Terms and Conditions", "oldfieldtype": "Section Break", - "options": "fa fa-legal", - "show_days": 1, - "show_seconds": 1 + "options": "fa fa-legal" }, { "fieldname": "tc_name", @@ -1074,27 +893,21 @@ "oldfieldname": "tc_name", "oldfieldtype": "Link", "options": "Terms and Conditions", - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "fieldname": "terms", "fieldtype": "Text Editor", "label": "Terms and Conditions", "oldfieldname": "terms", - "oldfieldtype": "Text Editor", - "show_days": 1, - "show_seconds": 1 + "oldfieldtype": "Text Editor" }, { "collapsible": 1, "fieldname": "more_info", "fieldtype": "Section Break", "label": "More Information", - "oldfieldtype": "Section Break", - "show_days": 1, - "show_seconds": 1 + "oldfieldtype": "Section Break" }, { "default": "Draft", @@ -1109,9 +922,7 @@ "print_hide": 1, "read_only": 1, "reqd": 1, - "search_index": 1, - "show_days": 1, - "show_seconds": 1 + "search_index": 1 }, { "fieldname": "ref_sq", @@ -1122,9 +933,7 @@ "oldfieldtype": "Data", "options": "Supplier Quotation", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "party_account_currency", @@ -1134,24 +943,18 @@ "no_copy": 1, "options": "Currency", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "inter_company_order_reference", "fieldtype": "Link", "label": "Inter Company Order Reference", "options": "Sales Order", - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "fieldname": "column_break_74", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "depends_on": "eval:!doc.__islocal", @@ -1161,9 +964,7 @@ "label": "% Received", "no_copy": 1, "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "depends_on": "eval:!doc.__islocal", @@ -1173,9 +974,7 @@ "label": "% Billed", "no_copy": 1, "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "collapsible": 1, @@ -1185,8 +984,6 @@ "oldfieldtype": "Column Break", "print_hide": 1, "print_width": "50%", - "show_days": 1, - "show_seconds": 1, "width": "50%" }, { @@ -1197,9 +994,7 @@ "oldfieldname": "letter_head", "oldfieldtype": "Select", "options": "Letter Head", - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "allow_on_submit": 1, @@ -1211,15 +1006,11 @@ "oldfieldtype": "Link", "options": "Print Heading", "print_hide": 1, - "report_hide": 1, - "show_days": 1, - "show_seconds": 1 + "report_hide": 1 }, { "fieldname": "column_break_86", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "allow_on_submit": 1, @@ -1227,25 +1018,19 @@ "fieldname": "group_same_items", "fieldtype": "Check", "label": "Group same items", - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "fieldname": "language", "fieldtype": "Data", "label": "Print Language", - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "collapsible": 1, "fieldname": "subscription_section", "fieldtype": "Section Break", - "label": "Subscription Section", - "show_days": 1, - "show_seconds": 1 + "label": "Subscription Section" }, { "allow_on_submit": 1, @@ -1253,9 +1038,7 @@ "fieldtype": "Date", "label": "From Date", "no_copy": 1, - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "allow_on_submit": 1, @@ -1263,15 +1046,11 @@ "fieldtype": "Date", "label": "To Date", "no_copy": 1, - "print_hide": 1, - "show_days": 1, - "show_seconds": 1 + "print_hide": 1 }, { "fieldname": "column_break_97", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "fieldname": "auto_repeat", @@ -1280,35 +1059,27 @@ "no_copy": 1, "options": "Auto Repeat", "print_hide": 1, - "read_only": 1, - "show_days": 1, - "show_seconds": 1 + "read_only": 1 }, { "allow_on_submit": 1, "depends_on": "eval: doc.auto_repeat", "fieldname": "update_auto_repeat_reference", "fieldtype": "Button", - "label": "Update Auto Repeat Reference", - "show_days": 1, - "show_seconds": 1 + "label": "Update Auto Repeat Reference" }, { "fieldname": "tax_category", "fieldtype": "Link", "label": "Tax Category", - "options": "Tax Category", - "show_days": 1, - "show_seconds": 1 + "options": "Tax Category" }, { "depends_on": "supplied_items", "fieldname": "set_reserve_warehouse", "fieldtype": "Link", "label": "Set Reserve Warehouse", - "options": "Warehouse", - "show_days": 1, - "show_seconds": 1 + "options": "Warehouse" }, { "collapsible": 1, @@ -1318,9 +1089,7 @@ }, { "fieldname": "column_break_75", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "fieldname": "billing_address", @@ -1361,25 +1130,27 @@ "default": "0", "fieldname": "apply_tds", "fieldtype": "Check", - "label": "Apply Tax Withholding Amount", - "show_days": 1, - "show_seconds": 1 + "label": "Apply Tax Withholding Amount" }, { "depends_on": "eval: doc.apply_tds", "fieldname": "tax_withholding_category", "fieldtype": "Link", "label": "Tax Withholding Category", - "options": "Tax Withholding Category", - "show_days": 1, - "show_seconds": 1 + "options": "Tax Withholding Category" + }, + { + "fieldname": "packed_items", + "fieldtype": "Table", + "label": "Bundle Items", + "options": "Packed Item" } ], "icon": "fa fa-file-text", "idx": 105, "is_submittable": 1, "links": [], - "modified": "2021-08-17 20:16:12.737743", + "modified": "2021-08-27 01:46:33.944417", "modified_by": "Administrator", "module": "Buying", "name": "Purchase Order", From 2d9138ab6470258f9f9d4d3707e3e9667fef79ee Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 27 Aug 2021 01:49:58 +0530 Subject: [PATCH 39/59] feat: Populate Bundle Items table --- erpnext/buying/doctype/purchase_order/purchase_order.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py index ca3bd90960c..e7d422d9ccf 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/purchase_order.py @@ -67,6 +67,9 @@ class PurchaseOrder(BuyingController): self.set_received_qty_for_drop_ship_items() validate_inter_company_party(self.doctype, self.supplier, self.company, self.inter_company_order_reference) + from erpnext.stock.doctype.packed_item.packed_item import make_packing_list + make_packing_list(self) + def validate_with_previous_doc(self): super(PurchaseOrder, self).validate_with_previous_doc({ "Supplier Quotation": { From 6bfd5daba0a1b745a75d6fadd95fe821136ae291 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 27 Aug 2021 02:29:47 +0530 Subject: [PATCH 40/59] fix: Create separate section for Bundle Items --- .../buying/doctype/purchase_order/purchase_order.json | 11 ++++++++++- erpnext/selling/doctype/quotation/quotation.json | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json index 873ab709996..e37d31a6740 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.json +++ b/erpnext/buying/doctype/purchase_order/purchase_order.json @@ -61,6 +61,7 @@ "set_warehouse", "items_section", "items", + "bundle_items_section", "packed_items", "sb_last_purchase", "total_qty", @@ -1144,13 +1145,21 @@ "fieldtype": "Table", "label": "Bundle Items", "options": "Packed Item" + }, + { + "collapsible": 1, + "collapsible_depends_on": "packed_items", + "fieldname": "bundle_items_section", + "fieldtype": "Section Break", + "label": "Bundle Items", + "options": "fa fa-suitcase" } ], "icon": "fa fa-file-text", "idx": 105, "is_submittable": 1, "links": [], - "modified": "2021-08-27 01:46:33.944417", + "modified": "2021-08-27 02:18:07.342249", "modified_by": "Administrator", "module": "Buying", "name": "Purchase Order", diff --git a/erpnext/selling/doctype/quotation/quotation.json b/erpnext/selling/doctype/quotation/quotation.json index 007fa338378..6bfb2c2a73f 100644 --- a/erpnext/selling/doctype/quotation/quotation.json +++ b/erpnext/selling/doctype/quotation/quotation.json @@ -43,6 +43,7 @@ "ignore_pricing_rule", "items_section", "items", + "bundle_items_section", "packed_items", "pricing_rule_details", "pricing_rules", @@ -933,6 +934,14 @@ "fieldtype": "Table", "label": "Bundle Items", "options": "Packed Item" + }, + { + "collapsible": 1, + "collapsible_depends_on": "packed_items", + "fieldname": "bundle_items_section", + "fieldtype": "Section Break", + "label": "Bundle Items", + "options": "fa fa-suitcase" } ], "icon": "fa fa-shopping-cart", @@ -940,7 +949,7 @@ "is_submittable": 1, "links": [], "max_attachments": 1, - "modified": "2021-08-27 01:09:54.587572", + "modified": "2021-08-27 02:23:33.460607", "modified_by": "Administrator", "module": "Selling", "name": "Quotation", From 34546d02be6c4038265060e1a6dc393097b2627d Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 27 Aug 2021 02:32:34 +0530 Subject: [PATCH 41/59] fix: Disable Add Row and Delete Row for Bundle Items --- erpnext/buying/doctype/purchase_order/purchase_order.js | 3 +++ erpnext/selling/doctype/quotation/quotation.js | 2 ++ 2 files changed, 5 insertions(+) diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index 233a9c87e59..51adbe5e37b 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -28,6 +28,9 @@ frappe.ui.form.on("Purchase Order", { } }); + frm.set_df_property('packed_items', 'cannot_add_rows', true); + frm.set_df_property('packed_items', 'cannot_delete_rows', true); + }, company: function(frm) { diff --git a/erpnext/selling/doctype/quotation/quotation.js b/erpnext/selling/doctype/quotation/quotation.js index 5a0d9c90655..474cf56fc1b 100644 --- a/erpnext/selling/doctype/quotation/quotation.js +++ b/erpnext/selling/doctype/quotation/quotation.js @@ -18,6 +18,8 @@ frappe.ui.form.on('Quotation', { } }); + frm.set_df_property('packed_items', 'cannot_add_rows', true); + frm.set_df_property('packed_items', 'cannot_delete_rows', true); }, refresh: function(frm) { From fd8482757e9e612723c41c7b9f068ee6b721ceab Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 27 Aug 2021 02:47:11 +0530 Subject: [PATCH 42/59] fix: Move Packed Items table right below the Items table --- erpnext/selling/doctype/sales_order/sales_order.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json index 38ea5c81d49..6c4a4033ba4 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.json +++ b/erpnext/selling/doctype/sales_order/sales_order.json @@ -55,6 +55,8 @@ "items_section", "scan_barcode", "items", + "packing_list", + "packed_items", "pricing_rule_details", "pricing_rules", "section_break_31", @@ -101,8 +103,6 @@ "in_words", "advance_paid", "disable_rounded_total", - "packing_list", - "packed_items", "payment_schedule_section", "payment_terms_template", "payment_schedule", @@ -1511,7 +1511,7 @@ "idx": 105, "is_submittable": 1, "links": [], - "modified": "2021-08-17 20:15:26.531553", + "modified": "2021-08-27 02:45:54.968867", "modified_by": "Administrator", "module": "Selling", "name": "Sales Order", From f2c4c1dc0e59781c4dbe8125d40695cac02ee39b Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 27 Aug 2021 20:06:22 +0530 Subject: [PATCH 43/59] fix: Enable Print Hide for Bundle Items --- erpnext/buying/doctype/purchase_order/purchase_order.json | 8 +++++--- erpnext/selling/doctype/quotation/quotation.json | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json index e37d31a6740..3eee5066f1e 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.json +++ b/erpnext/buying/doctype/purchase_order/purchase_order.json @@ -1144,7 +1144,8 @@ "fieldname": "packed_items", "fieldtype": "Table", "label": "Bundle Items", - "options": "Packed Item" + "options": "Packed Item", + "print_hide": 1 }, { "collapsible": 1, @@ -1152,14 +1153,15 @@ "fieldname": "bundle_items_section", "fieldtype": "Section Break", "label": "Bundle Items", - "options": "fa fa-suitcase" + "options": "fa fa-suitcase", + "print_hide": 1 } ], "icon": "fa fa-file-text", "idx": 105, "is_submittable": 1, "links": [], - "modified": "2021-08-27 02:18:07.342249", + "modified": "2021-08-27 20:05:54.869308", "modified_by": "Administrator", "module": "Buying", "name": "Purchase Order", diff --git a/erpnext/selling/doctype/quotation/quotation.json b/erpnext/selling/doctype/quotation/quotation.json index 6bfb2c2a73f..7185bb94de7 100644 --- a/erpnext/selling/doctype/quotation/quotation.json +++ b/erpnext/selling/doctype/quotation/quotation.json @@ -933,7 +933,8 @@ "fieldname": "packed_items", "fieldtype": "Table", "label": "Bundle Items", - "options": "Packed Item" + "options": "Packed Item", + "print_hide": 1 }, { "collapsible": 1, @@ -941,7 +942,8 @@ "fieldname": "bundle_items_section", "fieldtype": "Section Break", "label": "Bundle Items", - "options": "fa fa-suitcase" + "options": "fa fa-suitcase", + "print_hide": 1 } ], "icon": "fa fa-shopping-cart", @@ -949,7 +951,7 @@ "is_submittable": 1, "links": [], "max_attachments": 1, - "modified": "2021-08-27 02:23:33.460607", + "modified": "2021-08-27 20:04:26.357378", "modified_by": "Administrator", "module": "Selling", "name": "Quotation", From 18680990bf45015a806b3133d7fb1985f8e29914 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 27 Aug 2021 20:16:13 +0530 Subject: [PATCH 44/59] fix: Display Packed/Bundle Items table only if it exists --- .../doctype/pos_invoice/pos_invoice.json | 4 +++- .../doctype/sales_invoice/sales_invoice.json | 16 ++++++---------- .../doctype/purchase_order/purchase_order.json | 4 +++- erpnext/selling/doctype/quotation/quotation.json | 4 +++- .../selling/doctype/sales_order/sales_order.json | 4 +++- erpnext/selling/sales_common.js | 5 +---- .../doctype/delivery_note/delivery_note.json | 4 +++- 7 files changed, 22 insertions(+), 19 deletions(-) diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.json b/erpnext/accounts/doctype/pos_invoice/pos_invoice.json index 19c6c8f3472..bff85872781 100644 --- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.json +++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.json @@ -622,6 +622,7 @@ "read_only": 1 }, { + "depends_on": "packed_items", "fieldname": "packing_list", "fieldtype": "Section Break", "label": "Packing List", @@ -629,6 +630,7 @@ "print_hide": 1 }, { + "depends_on": "packed_items", "fieldname": "packed_items", "fieldtype": "Table", "label": "Packed Items", @@ -1564,7 +1566,7 @@ "icon": "fa fa-file-text", "is_submittable": 1, "links": [], - "modified": "2021-08-24 18:19:20.728433", + "modified": "2021-08-27 20:12:57.306772", "modified_by": "Administrator", "module": "Accounts", "name": "POS Invoice", diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index 2f8de068840..48108a8271b 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -248,7 +248,7 @@ "depends_on": "customer", "fetch_from": "customer.customer_name", "fieldname": "customer_name", - "fieldtype": "Small Text", + "fieldtype": "Data", "hide_days": 1, "hide_seconds": 1, "in_global_search": 1, @@ -696,7 +696,6 @@ "hide_days": 1, "hide_seconds": 1, "label": "Scan Barcode", - "length": 1, "options": "Barcode" }, { @@ -728,6 +727,7 @@ "read_only": 1 }, { + "depends_on": "packed_items", "fieldname": "packing_list", "fieldtype": "Section Break", "hide_days": 1, @@ -737,6 +737,7 @@ "print_hide": 1 }, { + "depends_on": "packed_items", "fieldname": "packed_items", "fieldtype": "Table", "hide_days": 1, @@ -1061,7 +1062,6 @@ "hide_days": 1, "hide_seconds": 1, "label": "Apply Additional Discount On", - "length": 15, "options": "\nGrand Total\nNet Total", "print_hide": 1 }, @@ -1148,7 +1148,7 @@ { "description": "In Words will be visible once you save the Sales Invoice.", "fieldname": "base_in_words", - "fieldtype": "Small Text", + "fieldtype": "Data", "hide_days": 1, "hide_seconds": 1, "label": "In Words (Company Currency)", @@ -1208,7 +1208,7 @@ }, { "fieldname": "in_words", - "fieldtype": "Small Text", + "fieldtype": "Data", "hide_days": 1, "hide_seconds": 1, "label": "In Words", @@ -1561,7 +1561,6 @@ "hide_days": 1, "hide_seconds": 1, "label": "Print Language", - "length": 6, "print_hide": 1, "read_only": 1 }, @@ -1649,7 +1648,6 @@ "hide_seconds": 1, "in_standard_filter": 1, "label": "Status", - "length": 30, "no_copy": 1, "options": "\nDraft\nReturn\nCredit Note Issued\nSubmitted\nPaid\nUnpaid\nUnpaid and Discounted\nOverdue and Discounted\nOverdue\nCancelled\nInternal Transfer", "print_hide": 1, @@ -1709,7 +1707,6 @@ "hide_days": 1, "hide_seconds": 1, "label": "Is Opening Entry", - "length": 4, "oldfieldname": "is_opening", "oldfieldtype": "Select", "options": "No\nYes", @@ -1721,7 +1718,6 @@ "hide_days": 1, "hide_seconds": 1, "label": "C-Form Applicable", - "length": 4, "no_copy": 1, "options": "No\nYes", "print_hide": 1 @@ -2031,7 +2027,7 @@ "link_fieldname": "consolidated_invoice" } ], - "modified": "2021-08-25 15:46:05.279588", + "modified": "2021-08-27 20:13:40.456462", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice", diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json index 3eee5066f1e..dd88c2d8507 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.json +++ b/erpnext/buying/doctype/purchase_order/purchase_order.json @@ -1141,6 +1141,7 @@ "options": "Tax Withholding Category" }, { + "depends_on": "packed_items", "fieldname": "packed_items", "fieldtype": "Table", "label": "Bundle Items", @@ -1150,6 +1151,7 @@ { "collapsible": 1, "collapsible_depends_on": "packed_items", + "depends_on": "packed_items", "fieldname": "bundle_items_section", "fieldtype": "Section Break", "label": "Bundle Items", @@ -1161,7 +1163,7 @@ "idx": 105, "is_submittable": 1, "links": [], - "modified": "2021-08-27 20:05:54.869308", + "modified": "2021-08-27 20:11:23.509147", "modified_by": "Administrator", "module": "Buying", "name": "Purchase Order", diff --git a/erpnext/selling/doctype/quotation/quotation.json b/erpnext/selling/doctype/quotation/quotation.json index 7185bb94de7..43a44900fcb 100644 --- a/erpnext/selling/doctype/quotation/quotation.json +++ b/erpnext/selling/doctype/quotation/quotation.json @@ -930,6 +930,7 @@ "read_only": 1 }, { + "depends_on": "packed_items", "fieldname": "packed_items", "fieldtype": "Table", "label": "Bundle Items", @@ -939,6 +940,7 @@ { "collapsible": 1, "collapsible_depends_on": "packed_items", + "depends_on": "packed_items", "fieldname": "bundle_items_section", "fieldtype": "Section Break", "label": "Bundle Items", @@ -951,7 +953,7 @@ "is_submittable": 1, "links": [], "max_attachments": 1, - "modified": "2021-08-27 20:04:26.357378", + "modified": "2021-08-27 20:10:07.864951", "modified_by": "Administrator", "module": "Selling", "name": "Quotation", diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json index 6c4a4033ba4..212bbde123f 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.json +++ b/erpnext/selling/doctype/sales_order/sales_order.json @@ -1019,6 +1019,7 @@ { "collapsible": 1, "collapsible_depends_on": "packed_items", + "depends_on": "packed_items", "fieldname": "packing_list", "fieldtype": "Section Break", "hide_days": 1, @@ -1029,6 +1030,7 @@ "print_hide": 1 }, { + "depends_on": "packed_items", "fieldname": "packed_items", "fieldtype": "Table", "hide_days": 1, @@ -1511,7 +1513,7 @@ "idx": 105, "is_submittable": 1, "links": [], - "modified": "2021-08-27 02:45:54.968867", + "modified": "2021-08-27 20:11:57.748736", "modified_by": "Administrator", "module": "Selling", "name": "Sales Order", diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js index 26ac630a32b..f05477ce23d 100644 --- a/erpnext/selling/sales_common.js +++ b/erpnext/selling/sales_common.js @@ -90,10 +90,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ this.frm.toggle_display("customer_name", (this.frm.doc.customer_name && this.frm.doc.customer_name!==this.frm.doc.customer)); - if(this.frm.fields_dict.packed_items) { - var packing_list_exists = (this.frm.doc.packed_items || []).length; - this.frm.toggle_display("packing_list", packing_list_exists ? true : false); - } + this.toggle_editable_price_list_rate(); }, diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.json b/erpnext/stock/doctype/delivery_note/delivery_note.json index 958189614fd..fdc8763baa6 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.json +++ b/erpnext/stock/doctype/delivery_note/delivery_note.json @@ -543,6 +543,7 @@ { "collapsible": 1, "collapsible_depends_on": "packed_items", + "depends_on": "packed_items", "fieldname": "packing_list", "fieldtype": "Section Break", "label": "Packing List", @@ -551,6 +552,7 @@ "print_hide": 1 }, { + "depends_on": "packed_items", "fieldname": "packed_items", "fieldtype": "Table", "label": "Packed Items", @@ -1306,7 +1308,7 @@ "idx": 146, "is_submittable": 1, "links": [], - "modified": "2021-08-17 20:15:50.574966", + "modified": "2021-08-27 20:14:40.215231", "modified_by": "Administrator", "module": "Stock", "name": "Delivery Note", From 4ca150f4caad7806a1cabf5674fe42c5bebb1d41 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Mon, 30 Aug 2021 20:04:24 +0530 Subject: [PATCH 45/59] fix: Remove Bundle Items table --- .../doctype/purchase_order/purchase_order.js | 3 --- .../purchase_order/purchase_order.json | 22 +------------------ .../doctype/purchase_order/purchase_order.py | 3 --- 3 files changed, 1 insertion(+), 27 deletions(-) diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index 51adbe5e37b..233a9c87e59 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -28,9 +28,6 @@ frappe.ui.form.on("Purchase Order", { } }); - frm.set_df_property('packed_items', 'cannot_add_rows', true); - frm.set_df_property('packed_items', 'cannot_delete_rows', true); - }, company: function(frm) { diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json index dd88c2d8507..ef54538fcd4 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.json +++ b/erpnext/buying/doctype/purchase_order/purchase_order.json @@ -61,8 +61,6 @@ "set_warehouse", "items_section", "items", - "bundle_items_section", - "packed_items", "sb_last_purchase", "total_qty", "base_total", @@ -1139,31 +1137,13 @@ "fieldtype": "Link", "label": "Tax Withholding Category", "options": "Tax Withholding Category" - }, - { - "depends_on": "packed_items", - "fieldname": "packed_items", - "fieldtype": "Table", - "label": "Bundle Items", - "options": "Packed Item", - "print_hide": 1 - }, - { - "collapsible": 1, - "collapsible_depends_on": "packed_items", - "depends_on": "packed_items", - "fieldname": "bundle_items_section", - "fieldtype": "Section Break", - "label": "Bundle Items", - "options": "fa fa-suitcase", - "print_hide": 1 } ], "icon": "fa fa-file-text", "idx": 105, "is_submittable": 1, "links": [], - "modified": "2021-08-27 20:11:23.509147", + "modified": "2021-08-30 20:03:14.008804", "modified_by": "Administrator", "module": "Buying", "name": "Purchase Order", diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py index e7d422d9ccf..ca3bd90960c 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/purchase_order.py @@ -67,9 +67,6 @@ class PurchaseOrder(BuyingController): self.set_received_qty_for_drop_ship_items() validate_inter_company_party(self.doctype, self.supplier, self.company, self.inter_company_order_reference) - from erpnext.stock.doctype.packed_item.packed_item import make_packing_list - make_packing_list(self) - def validate_with_previous_doc(self): super(PurchaseOrder, self).validate_with_previous_doc({ "Supplier Quotation": { From 3c0883d69b8a4a98809e5ba3b828fbc2758013b8 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Mon, 30 Aug 2021 20:07:06 +0530 Subject: [PATCH 46/59] fix: Add Product Bundle field in Items table --- .../purchase_order_item/purchase_order_item.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json index 01526fc65a5..87cd57517e2 100644 --- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json +++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json @@ -10,6 +10,7 @@ "item_code", "supplier_part_no", "item_name", + "product_bundle", "column_break_4", "schedule_date", "expected_delivery_date", @@ -829,13 +830,20 @@ "label": "Production Plan Sub Assembly Item", "no_copy": 1, "read_only": 1 + }, + { + "fieldname": "product_bundle", + "fieldtype": "Link", + "label": "Product Bundle", + "options": "Product Bundle", + "read_only": 1 } ], "idx": 1, "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-08-27 01:35:37.755413", + "modified": "2021-08-30 20:06:26.712097", "modified_by": "Administrator", "module": "Buying", "name": "Purchase Order Item", From 890705221e9bcc6156c706eddcc335a1c181f6cb Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Tue, 31 Aug 2021 18:44:29 +0530 Subject: [PATCH 47/59] fix: Replace Product Bundles in the Items table with their child items --- .../doctype/sales_order/sales_order.py | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 5d44582aab4..ff459cb13f2 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -950,8 +950,56 @@ def make_purchase_order(source_name, selected_items=None, target_doc=None): "condition": lambda doc: doc.ordered_qty < doc.stock_qty and doc.item_code in items_to_map } }, target_doc, set_missing_values) + + doc.items = replace_product_bundles_with_bundle_items(doc.items, source_name) + return doc +def replace_product_bundles_with_bundle_items(items, sales_order_name): + updated_items = [] + + for item in items: + if is_product_bundle(item.item_code): + bundle_items = get_bundle_items(item.item_code, sales_order_name) + insert_bundle_items(updated_items, bundle_items, item, sales_order_name) + else: + updated_items.append(item) + + items = updated_items + + return items + +def is_product_bundle(item_code): + return frappe.db.exists('Product Bundle', item_code) + +def get_bundle_items(item_code, so_name): + return frappe.get_all( + 'Packed Item', + filters = { + 'parent': so_name, + 'parent_item': item_code + }, + fields = ['item_code', 'item_name', 'qty', 'rate', 'uom'] + ) + +def insert_bundle_items(updated_items, bundle_items, item, sales_order): + for bundle_item in bundle_items: + new_item = frappe.get_doc({ + 'doctype': 'Purchase Order Item', + 'item_code': bundle_item.item_code, + 'item_name': bundle_item.item_name, + 'product_bundle': item.item_code, + 'qty': bundle_item.qty, + 'rate': bundle_item.rate, + 'uom': bundle_item.uom, + 'schedule_date': item.schedule_date, + 'sales_order': sales_order, + 'expense_account': item.expense_account, + 'cost_center': item.cost_center + }) + + updated_items.append(new_item) + @frappe.whitelist() def make_work_orders(items, sales_order, company, project=None): '''Make Work Orders against the given Sales Order for the given `items`''' From d0b4aa75047c473ab177126672975a8c9e504e22 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Tue, 31 Aug 2021 20:31:22 +0530 Subject: [PATCH 48/59] fix: Map Packed Items to Items table of PO --- .../doctype/sales_order/sales_order.py | 75 ++++++++----------- 1 file changed, 32 insertions(+), 43 deletions(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index ff459cb13f2..f190081accf 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -947,59 +947,48 @@ def make_purchase_order(source_name, selected_items=None, target_doc=None): "pricing_rules" ], "postprocess": update_item, - "condition": lambda doc: doc.ordered_qty < doc.stock_qty and doc.item_code in items_to_map + "condition": lambda doc: doc.ordered_qty < doc.stock_qty and doc.item_code in items_to_map and not is_product_bundle(doc.item_code) + }, + "Packed Item": { + "doctype": "Purchase Order Item", + "field_map": [ + ["parent", "sales_order"], + ["uom", "uom"], + ["conversion_factor", "conversion_factor"], + ["parent_item", "product_bundle"], + ["rate", "rate"] + ], + "field_no_map": [ + "rate", + "price_list_rate", + "item_tax_template", + "discount_percentage", + "discount_amount", + "supplier", + "pricing_rules" + ], } }, target_doc, set_missing_values) - doc.items = replace_product_bundles_with_bundle_items(doc.items, source_name) - + set_delivery_date(doc.items, source_name) + return doc -def replace_product_bundles_with_bundle_items(items, sales_order_name): - updated_items = [] - +def set_delivery_date(items, sales_order): for item in items: - if is_product_bundle(item.item_code): - bundle_items = get_bundle_items(item.item_code, sales_order_name) - insert_bundle_items(updated_items, bundle_items, item, sales_order_name) - else: - updated_items.append(item) - - items = updated_items - - return items + if item.product_bundle: + item.schedule_date = frappe.get_value( + 'Sales Order Item', + { + 'parent': sales_order, + 'item_code': item.product_bundle + }, + 'delivery_date' + ) def is_product_bundle(item_code): return frappe.db.exists('Product Bundle', item_code) -def get_bundle_items(item_code, so_name): - return frappe.get_all( - 'Packed Item', - filters = { - 'parent': so_name, - 'parent_item': item_code - }, - fields = ['item_code', 'item_name', 'qty', 'rate', 'uom'] - ) - -def insert_bundle_items(updated_items, bundle_items, item, sales_order): - for bundle_item in bundle_items: - new_item = frappe.get_doc({ - 'doctype': 'Purchase Order Item', - 'item_code': bundle_item.item_code, - 'item_name': bundle_item.item_name, - 'product_bundle': item.item_code, - 'qty': bundle_item.qty, - 'rate': bundle_item.rate, - 'uom': bundle_item.uom, - 'schedule_date': item.schedule_date, - 'sales_order': sales_order, - 'expense_account': item.expense_account, - 'cost_center': item.cost_center - }) - - updated_items.append(new_item) - @frappe.whitelist() def make_work_orders(items, sales_order, company, project=None): '''Make Work Orders against the given Sales Order for the given `items`''' From 9e399ecc877cd09c4bc536ae08ef46168494b5a5 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 1 Sep 2021 02:33:53 +0530 Subject: [PATCH 49/59] fix: Test if Product Bundles are mapped properly on creating a Sales Order --- .../doctype/quotation/test_quotation.py | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/erpnext/selling/doctype/quotation/test_quotation.py b/erpnext/selling/doctype/quotation/test_quotation.py index 527a999aefa..0fc985f45b1 100644 --- a/erpnext/selling/doctype/quotation/test_quotation.py +++ b/erpnext/selling/doctype/quotation/test_quotation.py @@ -226,6 +226,36 @@ class TestQuotation(unittest.TestCase): expired_quotation.reload() self.assertEqual(expired_quotation.status, "Expired") + def test_product_bundle_mapping_on_creating_so(self): + from erpnext.stock.doctype.item.test_item import make_item + from erpnext.selling.doctype.product_bundle.test_product_bundle import make_product_bundle + from erpnext.selling.doctype.quotation.quotation import make_sales_order + + make_item("_Test Product Bundle", {"is_stock_item": 0}) + make_item("_Test Bundle Item 1", {"is_stock_item": 1}) + make_item("_Test Bundle Item 2", {"is_stock_item": 1}) + + make_product_bundle("_Test Product Bundle", + ["_Test Bundle Item 1", "_Test Bundle Item 2"]) + + quotation = make_quotation(item_code="_Test Product Bundle", qty=1, rate=100) + sales_order = make_sales_order(quotation.name) + + quotation_item = [quotation.items[0].item_code, quotation.items[0].rate, quotation.items[0].qty, quotation.items[0].amount] + so_item = [sales_order.items[0].item_code, sales_order.items[0].rate, sales_order.items[0].qty, sales_order.items[0].amount] + + self.assertEqual(quotation_item, so_item) + + quotation_packed_items = [ + [quotation.packed_items[0].parent_item, quotation.packed_items[0].item_code, quotation.packed_items[0].qty], + [quotation.packed_items[1].parent_item, quotation.packed_items[1].item_code, quotation.packed_items[1].qty] + ] + so_packed_items = [ + [sales_order.packed_items[0].parent_item, sales_order.packed_items[0].item_code, sales_order.packed_items[0].qty], + [sales_order.packed_items[1].parent_item, sales_order.packed_items[1].item_code, sales_order.packed_items[1].qty] + ] + + self.assertEqual(quotation_packed_items, so_packed_items) test_records = frappe.get_test_records('Quotation') From 39ff46afa89bf5063091e75b4d9104183108a8d2 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 1 Sep 2021 02:50:29 +0530 Subject: [PATCH 50/59] fix: Test Product Bundle price calculation --- .../doctype/quotation/test_quotation.py | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/erpnext/selling/doctype/quotation/test_quotation.py b/erpnext/selling/doctype/quotation/test_quotation.py index 0fc985f45b1..854260059c4 100644 --- a/erpnext/selling/doctype/quotation/test_quotation.py +++ b/erpnext/selling/doctype/quotation/test_quotation.py @@ -257,8 +257,56 @@ class TestQuotation(unittest.TestCase): self.assertEqual(quotation_packed_items, so_packed_items) + def test_product_bundle_price_calculation_when_calculate_bundle_price_is_unchecked(self): + from erpnext.stock.doctype.item.test_item import make_item + from erpnext.selling.doctype.product_bundle.test_product_bundle import make_product_bundle + + make_item("_Test Product Bundle", {"is_stock_item": 0}) + bundle_item1 = make_item("_Test Bundle Item 1", {"is_stock_item": 1}) + bundle_item2 = make_item("_Test Bundle Item 2", {"is_stock_item": 1}) + + make_product_bundle("_Test Product Bundle", + ["_Test Bundle Item 1", "_Test Bundle Item 2"]) + + bundle_item1.valuation_rate = 100 + bundle_item1.save() + + bundle_item2.valuation_rate = 200 + bundle_item2.save() + + quotation = make_quotation(item_code="_Test Product Bundle", qty=2, rate=100) + self.assertEqual(quotation.items[0].amount, 200) + + def test_product_bundle_price_calculation_when_calculate_bundle_price_is_checked(self): + from erpnext.stock.doctype.item.test_item import make_item + from erpnext.selling.doctype.product_bundle.test_product_bundle import make_product_bundle + + make_item("_Test Product Bundle", {"is_stock_item": 0}) + make_item("_Test Bundle Item 1", {"is_stock_item": 1}) + make_item("_Test Bundle Item 2", {"is_stock_item": 1}) + + make_product_bundle("_Test Product Bundle", + ["_Test Bundle Item 1", "_Test Bundle Item 2"]) + + enable_calculate_bundle_price() + + quotation = make_quotation(item_code="_Test Product Bundle", qty=2, rate=100, do_not_submit=1) + quotation.packed_items[0].rate = 100 + quotation.packed_items[1].rate = 200 + quotation.save() + + self.assertEqual(quotation.items[0].amount, 600) + self.assertEqual(quotation.items[0].rate, 300) + + enable_calculate_bundle_price(enable=0) + test_records = frappe.get_test_records('Quotation') +def enable_calculate_bundle_price(enable=1): + selling_settings = frappe.get_doc("Selling Settings") + selling_settings.editable_bundle_item_rates = enable + selling_settings.save() + def get_quotation_dict(party_name=None, item_code=None): if not party_name: party_name = '_Test Customer' From c757198d8b9e09b2d0c203af31001fb441817133 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 1 Sep 2021 15:11:08 +0530 Subject: [PATCH 51/59] fix: Make Rate read-only by default --- erpnext/stock/doctype/packed_item/packed_item.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/packed_item/packed_item.json b/erpnext/stock/doctype/packed_item/packed_item.json index 6f0f527d139..830d5469bf0 100644 --- a/erpnext/stock/doctype/packed_item/packed_item.json +++ b/erpnext/stock/doctype/packed_item/packed_item.json @@ -224,14 +224,15 @@ "fieldtype": "Currency", "in_list_view": 1, "label": "Rate", - "print_hide": 1 + "print_hide": 1, + "read_only": 1 } ], "idx": 1, "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-08-27 01:20:55.308822", + "modified": "2021-09-01 15:10:29.646399", "modified_by": "Administrator", "module": "Stock", "name": "Packed Item", From 361605a2b6993097688442a27fe55cef30b32519 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 1 Sep 2021 15:13:29 +0530 Subject: [PATCH 52/59] fix: Uncheck read-only for Packed Items table --- erpnext/selling/doctype/sales_order/sales_order.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json index 212bbde123f..85282ca1a07 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.json +++ b/erpnext/selling/doctype/sales_order/sales_order.json @@ -1037,8 +1037,7 @@ "hide_seconds": 1, "label": "Packed Items", "options": "Packed Item", - "print_hide": 1, - "read_only": 1 + "print_hide": 1 }, { "fieldname": "payment_schedule_section", @@ -1513,7 +1512,7 @@ "idx": 105, "is_submittable": 1, "links": [], - "modified": "2021-08-27 20:11:57.748736", + "modified": "2021-09-01 15:12:24.115483", "modified_by": "Administrator", "module": "Selling", "name": "Sales Order", From 4538071e0d459fce2c90a04e171df3502e0e4334 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 1 Sep 2021 15:20:40 +0530 Subject: [PATCH 53/59] fix: Remove Add Row and Delete Row options for Packed Items table --- erpnext/accounts/doctype/sales_invoice/sales_invoice.js | 3 +++ erpnext/selling/doctype/sales_order/sales_order.js | 3 +++ 2 files changed, 6 insertions(+) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index 7427f381aba..f59f5748f35 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -566,6 +566,9 @@ frappe.ui.form.on('Sales Invoice', { frm.add_fetch('payment_term', 'invoice_portion', 'invoice_portion'); frm.add_fetch('payment_term', 'description', 'description'); + frm.set_df_property('packed_items', 'cannot_add_rows', true); + frm.set_df_property('packed_items', 'cannot_delete_rows', true); + frm.set_query("account_for_change_amount", function() { return { filters: { diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js index e3b41e66fbc..1961371d0b8 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.js +++ b/erpnext/selling/doctype/sales_order/sales_order.js @@ -43,6 +43,9 @@ frappe.ui.form.on("Sales Order", { } } }); + + frm.set_df_property('packed_items', 'cannot_add_rows', true); + frm.set_df_property('packed_items', 'cannot_delete_rows', true); }, refresh: function(frm) { if(frm.doc.docstatus === 1 && frm.doc.status !== 'Closed' From b5ef69dd344e212c066261c6cac139d85ceb7cd0 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 1 Sep 2021 15:36:07 +0530 Subject: [PATCH 54/59] fix: Set Product Bundle's Delivery Dates in SO as Bundle Items' Delivery Dates in PO --- .../doctype/sales_order/sales_order.py | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index f190081accf..5d59aa1870f 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -975,16 +975,21 @@ def make_purchase_order(source_name, selected_items=None, target_doc=None): return doc def set_delivery_date(items, sales_order): + delivery_dates = frappe.get_all( + 'Sales Order Item', + filters = { + 'parent': sales_order + }, + fields = ['delivery_date', 'item_code'] + ) + + delivery_by_item = frappe._dict() + for date in delivery_dates: + delivery_by_item[date.item_code] = date.delivery_date + for item in items: if item.product_bundle: - item.schedule_date = frappe.get_value( - 'Sales Order Item', - { - 'parent': sales_order, - 'item_code': item.product_bundle - }, - 'delivery_date' - ) + item.schedule_date = delivery_by_item[item.product_bundle] def is_product_bundle(item_code): return frappe.db.exists('Product Bundle', item_code) From 758a23eff71e289ae34f7beb644e3124e58adfed Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 1 Sep 2021 16:00:59 +0530 Subject: [PATCH 55/59] fix: Remove Rate from field_no_map --- erpnext/selling/doctype/sales_order/sales_order.py | 1 - 1 file changed, 1 deletion(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 5d59aa1870f..47ebfe90d31 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -959,7 +959,6 @@ def make_purchase_order(source_name, selected_items=None, target_doc=None): ["rate", "rate"] ], "field_no_map": [ - "rate", "price_list_rate", "item_tax_template", "discount_percentage", From 17bf32d8dcb3ada5c120733a8f84a456e7a047b9 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 1 Sep 2021 16:06:47 +0530 Subject: [PATCH 56/59] fix: Add Product Bundle field in Items table --- .../purchase_invoice_item/purchase_invoice_item.json | 12 ++++++++++-- .../purchase_receipt_item/purchase_receipt_item.json | 10 +++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json index 51e5c1a6a9a..eab98a7e3fd 100644 --- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json +++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json @@ -8,6 +8,7 @@ "engine": "InnoDB", "field_order": [ "item_code", + "product_bundle", "col_break1", "item_name", "description_section", @@ -857,12 +858,19 @@ "fieldtype": "Link", "label": "Discount Account", "options": "Account" + }, + { + "fieldname": "product_bundle", + "fieldtype": "Link", + "label": "Product Bundle", + "options": "Product Bundle", + "read_only": 1 } ], "idx": 1, "istable": 1, "links": [], - "modified": "2021-08-12 20:14:45.506639", + "modified": "2021-09-01 16:04:03.538643", "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice Item", @@ -870,4 +878,4 @@ "permissions": [], "sort_field": "modified", "sort_order": "DESC" -} \ No newline at end of file +} diff --git a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json index 82cc98e7f75..3efa66e02ed 100644 --- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json +++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json @@ -10,6 +10,7 @@ "barcode", "section_break_2", "item_code", + "product_bundle", "supplier_part_no", "column_break_2", "item_name", @@ -956,12 +957,19 @@ "no_copy": 1, "print_hide": 1, "read_only": 1 + }, + { + "fieldname": "product_bundle", + "fieldtype": "Link", + "label": "Product Bundle", + "options": "Product Bundle", + "read_only": 1 } ], "idx": 1, "istable": 1, "links": [], - "modified": "2021-03-29 04:17:00.336298", + "modified": "2021-09-01 16:02:40.338597", "modified_by": "Administrator", "module": "Stock", "name": "Purchase Receipt Item", From debffbfb2d0bfa6ef8e1e764efb1b8e29c5f2ea8 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Thu, 2 Sep 2021 20:27:15 +0530 Subject: [PATCH 57/59] fix: Trim trailing whitespaces --- erpnext/selling/doctype/sales_order/sales_order.py | 6 +++--- .../selling/doctype/selling_settings/selling_settings.py | 2 +- erpnext/selling/sales_common.js | 2 +- erpnext/stock/doctype/packed_item/packed_item.py | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 47ebfe90d31..b4e70472b93 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -970,15 +970,15 @@ def make_purchase_order(source_name, selected_items=None, target_doc=None): }, target_doc, set_missing_values) set_delivery_date(doc.items, source_name) - + return doc def set_delivery_date(items, sales_order): delivery_dates = frappe.get_all( - 'Sales Order Item', + 'Sales Order Item', filters = { 'parent': sales_order - }, + }, fields = ['delivery_date', 'item_code'] ) diff --git a/erpnext/selling/doctype/selling_settings/selling_settings.py b/erpnext/selling/doctype/selling_settings/selling_settings.py index b54559ad288..92394e68ac0 100644 --- a/erpnext/selling/doctype/selling_settings/selling_settings.py +++ b/erpnext/selling/doctype/selling_settings/selling_settings.py @@ -36,7 +36,7 @@ class SellingSettings(Document): def toggle_editable_rate_for_bundle_items(self): editable_bundle_item_rates = cint(self.editable_bundle_item_rates) - + make_property_setter("Packed Item", "rate", "read_only", not(editable_bundle_item_rates), "Check", validate_fields_for_doctype=False) def set_default_customer_group_and_territory(self): diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js index f05477ce23d..091c22271e6 100644 --- a/erpnext/selling/sales_common.js +++ b/erpnext/selling/sales_common.js @@ -90,7 +90,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ this.frm.toggle_display("customer_name", (this.frm.doc.customer_name && this.frm.doc.customer_name!==this.frm.doc.customer)); - + this.toggle_editable_price_list_rate(); }, diff --git a/erpnext/stock/doctype/packed_item/packed_item.py b/erpnext/stock/doctype/packed_item/packed_item.py index 4f1a67597d9..34fe797547c 100644 --- a/erpnext/stock/doctype/packed_item/packed_item.py +++ b/erpnext/stock/doctype/packed_item/packed_item.py @@ -128,7 +128,7 @@ def update_product_bundle_price(doc, parent_items): # for the last product bundle if doc.get("packed_items"): update_parent_item_price(doc, parent_items[parent_items_index][0], bundle_price) - + def update_parent_item_price(doc, parent_item_code, bundle_price): parent_item_doc = doc.get('items', {'item_code': parent_item_code})[0] From 115fb944c2535509d035f13d2eb31903407cb2f5 Mon Sep 17 00:00:00 2001 From: Saqib Date: Fri, 3 Sep 2021 11:06:20 +0530 Subject: [PATCH 58/59] fix: undo unintentional changes --- .../doctype/sales_invoice/sales_invoice.json | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index 48108a8271b..b89be991f2b 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -248,7 +248,7 @@ "depends_on": "customer", "fetch_from": "customer.customer_name", "fieldname": "customer_name", - "fieldtype": "Data", + "fieldtype": "Small Text", "hide_days": 1, "hide_seconds": 1, "in_global_search": 1, @@ -696,6 +696,7 @@ "hide_days": 1, "hide_seconds": 1, "label": "Scan Barcode", + "length": 1, "options": "Barcode" }, { @@ -1062,6 +1063,7 @@ "hide_days": 1, "hide_seconds": 1, "label": "Apply Additional Discount On", + "length": 15, "options": "\nGrand Total\nNet Total", "print_hide": 1 }, @@ -1148,7 +1150,7 @@ { "description": "In Words will be visible once you save the Sales Invoice.", "fieldname": "base_in_words", - "fieldtype": "Data", + "fieldtype": "Small Text", "hide_days": 1, "hide_seconds": 1, "label": "In Words (Company Currency)", @@ -1208,7 +1210,7 @@ }, { "fieldname": "in_words", - "fieldtype": "Data", + "fieldtype": "Small Text", "hide_days": 1, "hide_seconds": 1, "label": "In Words", @@ -1561,6 +1563,7 @@ "hide_days": 1, "hide_seconds": 1, "label": "Print Language", + "length": 6, "print_hide": 1, "read_only": 1 }, @@ -1648,6 +1651,7 @@ "hide_seconds": 1, "in_standard_filter": 1, "label": "Status", + "length": 30, "no_copy": 1, "options": "\nDraft\nReturn\nCredit Note Issued\nSubmitted\nPaid\nUnpaid\nUnpaid and Discounted\nOverdue and Discounted\nOverdue\nCancelled\nInternal Transfer", "print_hide": 1, @@ -1707,6 +1711,7 @@ "hide_days": 1, "hide_seconds": 1, "label": "Is Opening Entry", + "length": 4, "oldfieldname": "is_opening", "oldfieldtype": "Select", "options": "No\nYes", @@ -1718,6 +1723,7 @@ "hide_days": 1, "hide_seconds": 1, "label": "C-Form Applicable", + "length": 4, "no_copy": 1, "options": "No\nYes", "print_hide": 1 From 0228db1e61d4947cf49d94c6a93f0d713beabea8 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Fri, 3 Sep 2021 12:26:41 +0530 Subject: [PATCH 59/59] fix: south africa vat patch failure (#27325) * fix: south africa vat patch failure (#27323) reload doc is necessary on new doctypes (cherry picked from commit d1fe060e4afb96324492beca77c69698cb32a085) # Conflicts: # erpnext/patches/v13_0/add_custom_field_for_south_africa.py * fix: resolve conflicts Co-authored-by: Ankush Menat --- erpnext/patches/v13_0/add_custom_field_for_south_africa.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/erpnext/patches/v13_0/add_custom_field_for_south_africa.py b/erpnext/patches/v13_0/add_custom_field_for_south_africa.py index 73ff1cad5b6..b65c94b7210 100644 --- a/erpnext/patches/v13_0/add_custom_field_for_south_africa.py +++ b/erpnext/patches/v13_0/add_custom_field_for_south_africa.py @@ -1,8 +1,8 @@ # Copyright (c) 2020, Frappe and Contributors # License: GNU General Public License v3. See license.txt -from __future__ import unicode_literals import frappe + from erpnext.regional.south_africa.setup import make_custom_fields, add_permissions def execute(): @@ -10,5 +10,8 @@ def execute(): if not company: return + frappe.reload_doc('regional', 'doctype', 'south_africa_vat_settings') + frappe.reload_doc('accounts', 'doctype', 'south_africa_vat_account') + make_custom_fields() add_permissions()