From b169558885f01b6d798c3ac455789af7f3b92e91 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 14 Sep 2021 11:37:12 +0530 Subject: [PATCH] feat: Merge POS invoices based on customer group --- .../pos_invoice_merge_log.js | 7 +++- .../pos_invoice_merge_log.json | 21 +++++++++- .../pos_invoice_merge_log.py | 12 +++++- .../doctype/sales_invoice/sales_invoice.py | 4 +- erpnext/hooks.py | 2 +- erpnext/patches.txt | 1 + ...e_accounting_dimensions_in_pos_doctypes.py | 42 +++++++++++++++++++ 7 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 erpnext/patches/v13_0/create_accounting_dimensions_in_pos_doctypes.py diff --git a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.js b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.js index 2f8081b95ce..23c3ea3e610 100644 --- a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.js +++ b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.js @@ -4,7 +4,7 @@ frappe.ui.form.on('POS Invoice Merge Log', { setup: function(frm) { frm.set_query("pos_invoice", "pos_invoices", doc => { - return{ + return { filters: { 'docstatus': 1, 'customer': doc.customer, @@ -12,5 +12,10 @@ frappe.ui.form.on('POS Invoice Merge Log', { } } }); + }, + + merger_invoices_based_on: function(frm) { + frm.set_value('customer', ''); + frm.set_value('customer_group', ''); } }); diff --git a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.json b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.json index da2984f05af..d7620870780 100644 --- a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.json +++ b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.json @@ -6,9 +6,11 @@ "engine": "InnoDB", "field_order": [ "posting_date", - "customer", + "merge_invoices_based_on", "column_break_3", "pos_closing_entry", + "customer", + "customer_group", "section_break_3", "pos_invoices", "references_section", @@ -88,12 +90,27 @@ "fieldtype": "Link", "label": "POS Closing Entry", "options": "POS Closing Entry" + }, + { + "fieldname": "merge_invoices_based_on", + "fieldtype": "Select", + "label": "Merge Invoices Based On", + "options": "Customer\nCustomer Group", + "reqd": 1 + }, + { + "depends_on": "eval:doc.merge_invoices_based_on == 'Customer Group'", + "fieldname": "customer_group", + "fieldtype": "Link", + "label": "Customer Group", + "mandatory_depends_on": "eval:doc.merge_invoices_based_on == 'Customer Group'", + "options": "Customer Group" } ], "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2020-12-01 11:53:57.267579", + "modified": "2021-09-14 11:17:19.001142", "modified_by": "Administrator", "module": "Accounts", "name": "POS Invoice Merge Log", diff --git a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py index e50d437ba6a..4c8be6fa961 100644 --- a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py +++ b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py @@ -21,6 +21,9 @@ class POSInvoiceMergeLog(Document): self.validate_pos_invoice_status() def validate_customer(self): + if self.merge_invoices_based_on == 'Customer Group': + return + for d in self.pos_invoices: if d.customer != self.customer: frappe.throw(_("Row #{}: POS Invoice {} is not against customer {}").format(d.idx, d.pos_invoice, self.customer)) @@ -122,7 +125,7 @@ class POSInvoiceMergeLog(Document): found = False for i in items: if (i.item_code == item.item_code and not i.serial_no and not i.batch_no and - i.uom == item.uom and i.net_rate == item.net_rate): + i.uom == item.uom and i.net_rate == item.net_rate and i.warehouse == item.warehouse): found = True i.qty = i.qty + item.qty @@ -170,6 +173,11 @@ class POSInvoiceMergeLog(Document): invoice.discount_amount = 0.0 invoice.taxes_and_charges = None invoice.ignore_pricing_rule = 1 + invoice.customer = self.customer + + if self.merge_invoices_based_on == 'Customer Group': + invoice.flags.ignore_pos_profile = True + invoice.pos_profile = '' return invoice @@ -226,7 +234,7 @@ def get_all_unconsolidated_invoices(): return pos_invoices def get_invoice_customer_map(pos_invoices): - # pos_invoice_customer_map = { 'Customer 1': [{}, {}, {}], 'Custoemr 2' : [{}] } + # pos_invoice_customer_map = { 'Customer 1': [{}, {}, {}], 'Customer 2' : [{}] } pos_invoice_customer_map = {} for invoice in pos_invoices: customer = invoice.get('customer') diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 9e295d5ae54..de1d90aaca6 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -483,8 +483,8 @@ class SalesInvoice(SellingController): if not self.account_for_change_amount: self.account_for_change_amount = frappe.get_cached_value('Company', self.company, 'default_cash_account') - from erpnext.stock.get_item_details import get_pos_profile_item_details, get_pos_profile - if not self.pos_profile: + from erpnext.stock.get_item_details import get_pos_profile, get_pos_profile_item_details + if not self.pos_profile and not self.flags.ignore_pos_profile: pos_profile = get_pos_profile(self.company) or {} if not pos_profile: return diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 2385b7cbade..08acea9d444 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -429,7 +429,7 @@ accounting_dimension_doctypes = ["GL Entry", "Sales Invoice", "Purchase Invoice" "Purchase Receipt Item", "Stock Entry Detail", "Payment Entry Deduction", "Sales Taxes and Charges", "Purchase Taxes and Charges", "Shipping Rule", "Landed Cost Item", "Asset Value Adjustment", "Loyalty Program", "Fee Schedule", "Fee Structure", "Stock Reconciliation", "Travel Request", "Fees", "POS Profile", "Opening Invoice Creation Tool", "Opening Invoice Creation Tool Item", "Subscription", - "Subscription Plan" + "Subscription Plan", "POS Invoice", "POS Invoice Item" ] regional_overrides = { diff --git a/erpnext/patches.txt b/erpnext/patches.txt index aeca7df802e..5f4dbc9c00d 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -305,3 +305,4 @@ erpnext.patches.v13_0.add_custom_field_for_south_africa #2 erpnext.patches.v13_0.rename_discharge_ordered_date_in_ip_record erpnext.patches.v13_0.set_operation_time_based_on_operating_cost erpnext.patches.v13_0.validate_options_for_data_field +erpnext.patches.v13_0.create_accounting_dimensions_in_pos_doctypes diff --git a/erpnext/patches/v13_0/create_accounting_dimensions_in_pos_doctypes.py b/erpnext/patches/v13_0/create_accounting_dimensions_in_pos_doctypes.py new file mode 100644 index 00000000000..c02661fd3e4 --- /dev/null +++ b/erpnext/patches/v13_0/create_accounting_dimensions_in_pos_doctypes.py @@ -0,0 +1,42 @@ +import frappe +from frappe.custom.doctype.custom_field.custom_field import create_custom_field + + +def execute(): + frappe.reload_doc('accounts', 'doctype', 'accounting_dimension') + accounting_dimensions = frappe.db.sql("""select fieldname, label, document_type, disabled from + `tabAccounting Dimension`""", as_dict=1) + + if not accounting_dimensions: + return + + count = 1 + for d in accounting_dimensions: + + if count%2 == 0: + insert_after_field = 'dimension_col_break' + else: + insert_after_field = 'accounting_dimensions_section' + + for doctype in ["POS Invoice", "POS Invoice Item"]: + + field = frappe.db.get_value("Custom Field", {"dt": doctype, "fieldname": d.fieldname}) + + if field: + continue + meta = frappe.get_meta(doctype, cached=False) + fieldnames = [d.fieldname for d in meta.get("fields")] + + df = { + "fieldname": d.fieldname, + "label": d.label, + "fieldtype": "Link", + "options": d.document_type, + "insert_after": insert_after_field + } + + if df['fieldname'] not in fieldnames: + create_custom_field(doctype, df) + frappe.clear_cache(doctype=doctype) + + count += 1