From 684290233f4f2741e7a018b4b006180e185b5350 Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Tue, 27 Jun 2023 16:49:28 +0530 Subject: [PATCH 01/14] feat: add voucher-wise balance report logic (cherry picked from commit 5d726ef0377dc1fadc9857cb4b39828dc731a709) --- .../report/voucher_wise_balance/__init__.py | 0 .../voucher_wise_balance.js | 28 ++++++++ .../voucher_wise_balance.json | 33 ++++++++++ .../voucher_wise_balance.py | 66 +++++++++++++++++++ 4 files changed, 127 insertions(+) create mode 100644 erpnext/accounts/report/voucher_wise_balance/__init__.py create mode 100644 erpnext/accounts/report/voucher_wise_balance/voucher_wise_balance.js create mode 100644 erpnext/accounts/report/voucher_wise_balance/voucher_wise_balance.json create mode 100644 erpnext/accounts/report/voucher_wise_balance/voucher_wise_balance.py diff --git a/erpnext/accounts/report/voucher_wise_balance/__init__.py b/erpnext/accounts/report/voucher_wise_balance/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/report/voucher_wise_balance/voucher_wise_balance.js b/erpnext/accounts/report/voucher_wise_balance/voucher_wise_balance.js new file mode 100644 index 00000000000..0c148f85fb8 --- /dev/null +++ b/erpnext/accounts/report/voucher_wise_balance/voucher_wise_balance.js @@ -0,0 +1,28 @@ +// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.query_reports["Voucher-wise Balance"] = { + "filters": [ + { + "fieldname": "company", + "label": __("Company"), + "fieldtype": "Link", + "options": "Company" + }, + { + "fieldname":"from_date", + "label": __("From Date"), + "fieldtype": "Date", + "default": frappe.datetime.add_months(frappe.datetime.get_today(), -1), + "width": "60px" + }, + { + "fieldname":"to_date", + "label": __("To Date"), + "fieldtype": "Date", + "default": frappe.datetime.get_today(), + "width": "60px" + }, + ] +}; diff --git a/erpnext/accounts/report/voucher_wise_balance/voucher_wise_balance.json b/erpnext/accounts/report/voucher_wise_balance/voucher_wise_balance.json new file mode 100644 index 00000000000..434e5a3b257 --- /dev/null +++ b/erpnext/accounts/report/voucher_wise_balance/voucher_wise_balance.json @@ -0,0 +1,33 @@ +{ + "add_total_row": 0, + "columns": [], + "creation": "2023-06-27 16:40:15.109554", + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "filters": [], + "idx": 0, + "is_standard": "Yes", + "json": "{}", + "letter_head": "LetterHead", + "modified": "2023-06-27 16:40:32.493725", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Voucher-wise Balance", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "GL Entry", + "report_name": "Voucher-wise Balance", + "report_type": "Script Report", + "roles": [ + { + "role": "Accounts User" + }, + { + "role": "Accounts Manager" + }, + { + "role": "Auditor" + } + ] +} \ No newline at end of file diff --git a/erpnext/accounts/report/voucher_wise_balance/voucher_wise_balance.py b/erpnext/accounts/report/voucher_wise_balance/voucher_wise_balance.py new file mode 100644 index 00000000000..cbe25495854 --- /dev/null +++ b/erpnext/accounts/report/voucher_wise_balance/voucher_wise_balance.py @@ -0,0 +1,66 @@ +# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +import frappe +from frappe import _ +from frappe.query_builder.functions import Sum + + +def execute(filters=None): + columns = get_columns() + data = get_data(filters) + return columns, data + + +def get_columns(): + return [ + {"label": _("Voucher Type"), "fieldname": "voucher_type", "width": 300}, + { + "label": _("Voucher No"), + "fieldname": "voucher_no", + "fieldtype": "Dynamic Link", + "options": "voucher_type", + "width": 300, + }, + { + "fieldname": "debit", + "label": _("Debit"), + "fieldtype": "Currency", + "options": "currency", + "width": 300, + }, + { + "fieldname": "credit", + "label": _("Credit"), + "fieldtype": "Currency", + "options": "currency", + "width": 300, + }, + ] + + +def get_data(filters): + gle = frappe.qb.DocType("GL Entry") + query = ( + frappe.qb.from_(gle) + .select( + gle.voucher_type, gle.voucher_no, Sum(gle.debit).as_("debit"), Sum(gle.credit).as_("credit") + ) + .groupby(gle.voucher_no) + ) + query = apply_filters(query, filters, gle) + gl_entries = query.run(as_dict=True, debug=True) + unmatched = [entry for entry in gl_entries if entry.debit != entry.credit] + return unmatched + + +def apply_filters(query, filters, gle): + if filters.get("company"): + query = query.where(gle.company == filters.company) + if filters.get("voucher_type"): + query = query.where(gle.voucher_type == filters.voucher_type) + if filters.get("from_date"): + query = query.where(gle.posting_date >= filters.from_date) + if filters.get("to_date"): + query = query.where(gle.posting_date <= filters.to_date) + return query From 646440fd5539b31062b4363c15d3393c004f1b17 Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Tue, 27 Jun 2023 21:59:35 +0530 Subject: [PATCH 02/14] fix: remove debug flag from sql (cherry picked from commit 6b9f9f9b0e0a49ee15820c77ffe4de99605786ff) --- .../report/voucher_wise_balance/voucher_wise_balance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/report/voucher_wise_balance/voucher_wise_balance.py b/erpnext/accounts/report/voucher_wise_balance/voucher_wise_balance.py index cbe25495854..5ab3611b9af 100644 --- a/erpnext/accounts/report/voucher_wise_balance/voucher_wise_balance.py +++ b/erpnext/accounts/report/voucher_wise_balance/voucher_wise_balance.py @@ -49,7 +49,7 @@ def get_data(filters): .groupby(gle.voucher_no) ) query = apply_filters(query, filters, gle) - gl_entries = query.run(as_dict=True, debug=True) + gl_entries = query.run(as_dict=True) unmatched = [entry for entry in gl_entries if entry.debit != entry.credit] return unmatched From a880bdec5ea9f10d34f19b9e35eda6d0eb42180e Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 29 Jun 2023 13:30:29 +0530 Subject: [PATCH 03/14] chore: update translations (#35905) chore: update translations chore: update translations (cherry picked from commit 1d1103f39c173509f0bd3ba04c1c142db27b4e80) Co-authored-by: RJPvT <48353029+RJPvT@users.noreply.github.com> --- erpnext/translations/nl.csv | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/translations/nl.csv b/erpnext/translations/nl.csv index b559c694094..b65f22334c7 100644 --- a/erpnext/translations/nl.csv +++ b/erpnext/translations/nl.csv @@ -875,7 +875,7 @@ Donor,schenker, Donor Type information.,Donor Type informatie., Donor information.,Donorinformatie., Download JSON,JSON downloaden, -Draft,Droogte, +Draft,Concept, Drop Ship,Drop Ship, Drug,drug, Due / Reference Date cannot be after {0},Verval- / Referentiedatum kan niet na {0} zijn, @@ -4279,7 +4279,7 @@ Failed to setup defaults for country {0}. Please contact support@erpnext.com,Kan Row #{0}: Item {1} is not a Serialized/Batched Item. It cannot have a Serial No/Batch No against it.,Rij # {0}: artikel {1} is geen geserialiseerd / batch artikel. Het kan geen serienummer / batchnummer hebben., Please set {0},Stel {0} in, Please set {0},Stel {0} in,supplier -Draft,Droogte,"docstatus,=,0" +Draft,Concept,"docstatus,=,0" Cancelled,Geannuleerd,"docstatus,=,2" Please setup Instructor Naming System in Education > Education Settings,Stel het instructeursysteem in onder onderwijs> onderwijsinstellingen, Please set Naming Series for {0} via Setup > Settings > Naming Series,Stel Naming Series in op {0} via Instellingen> Instellingen> Naming Series, @@ -8191,7 +8191,7 @@ Actual Batch Quantity,Werkelijke batchhoeveelheid, Prevdoc DocType,Prevdoc DocType, Parent Detail docname,Bovenliggende Detail docname, "Generate packing slips for packages to be delivered. Used to notify package number, package contents and its weight.","Genereren van pakbonnen voor pakketten te leveren. Gebruikt voor pakket nummer, inhoud van de verpakking en het gewicht te melden.", -Indicates that the package is a part of this delivery (Only Draft),Geeft aan dat het pakket een onderdeel is van deze levering (alleen ontwerp), +Indicates that the package is a part of this delivery (Only Draft),Geeft aan dat het pakket een onderdeel is van deze levering (alleen concept), MAT-PAC-.YYYY.-,MAT-PAC-.YYYY.-, From Package No.,Van Pakket No, Identification of the package for the delivery (for print),Identificatie van het pakket voor de levering (voor afdrukken), From 6f50ad685e6e4b838608cac0709f08dd95d459f7 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 29 Jun 2023 22:16:53 +0530 Subject: [PATCH 04/14] feat: allow the partial return of components against SCO (backport #35935) (#35938) * fix: don't update SCO status to closed until full return (cherry picked from commit 2f6d56dd6280d08ad2e3bcf7fac44419d9976e9c) * fix: reduce return qty while calculating transferred qty (cherry picked from commit 2a60884abc367a46779b1577e8f0397d1f60f3fd) # Conflicts: # erpnext/controllers/subcontracting_controller.py * chore: `conflicts` --------- Co-authored-by: s-aga-r --- .../controllers/subcontracting_controller.py | 75 ++++++++++--------- .../subcontracting_order.py | 5 +- 2 files changed, 43 insertions(+), 37 deletions(-) diff --git a/erpnext/controllers/subcontracting_controller.py b/erpnext/controllers/subcontracting_controller.py index 1e9c4dc8478..566135d75b9 100644 --- a/erpnext/controllers/subcontracting_controller.py +++ b/erpnext/controllers/subcontracting_controller.py @@ -169,45 +169,50 @@ class SubcontractingController(StockController): self.qty_to_be_received[(row.item_code, row.parent)] += row.qty def __get_transferred_items(self): - fields = [f"`tabStock Entry`.`{self.subcontract_data.order_field}`"] - alias_dict = { - "item_code": "rm_item_code", - "subcontracted_item": "main_item_code", - "basic_rate": "rate", - } + se = frappe.qb.DocType("Stock Entry") + se_detail = frappe.qb.DocType("Stock Entry Detail") - child_table_fields = [ - "item_code", - "item_name", - "description", - "qty", - "basic_rate", - "amount", - "serial_no", - "uom", - "subcontracted_item", - "stock_uom", - "batch_no", - "conversion_factor", - "s_warehouse", - "t_warehouse", - "item_group", - self.subcontract_data.rm_detail_field, - ] + query = ( + frappe.qb.from_(se) + .inner_join(se_detail) + .on(se.name == se_detail.parent) + .select( + se[self.subcontract_data.order_field], + se_detail.item_code.as_("rm_item_code"), + se_detail.item_name, + se_detail.description, + ( + frappe.qb.terms.Case() + .when(((se.purpose == "Material Transfer") & (se.is_return == 1)), -1 * se_detail.qty) + .else_(se_detail.qty) + ).as_("qty"), + se_detail.basic_rate.as_("rate"), + se_detail.amount, + se_detail.serial_no, + se_detail.uom, + se_detail.subcontracted_item.as_("main_item_code"), + se_detail.stock_uom, + se_detail.batch_no, + se_detail.conversion_factor, + se_detail.s_warehouse, + se_detail.t_warehouse, + se_detail.item_group, + se_detail[self.subcontract_data.rm_detail_field], + ) + .where( + (se.docstatus == 1) + & (se[self.subcontract_data.order_field].isin(self.subcontract_orders)) + & ( + (se.purpose == "Send to Subcontractor") + | ((se.purpose == "Material Transfer") & (se.is_return == 1)) + ) + ) + ) if self.backflush_based_on == "BOM": - child_table_fields.append("original_item") + query = query.select(se_detail.original_item) - for field in child_table_fields: - fields.append(f"`tabStock Entry Detail`.`{field}` As {alias_dict.get(field, field)}") - - filters = [ - ["Stock Entry", "docstatus", "=", 1], - ["Stock Entry", "purpose", "=", "Send to Subcontractor"], - ["Stock Entry", self.subcontract_data.order_field, "in", self.subcontract_orders], - ] - - return frappe.get_all("Stock Entry", fields=fields, filters=filters) + return query.run(as_dict=True) def __set_alternative_item_details(self, row): if row.get("original_item"): diff --git a/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py b/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py index 39197332c1c..0b14d4d9f50 100644 --- a/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py +++ b/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py @@ -163,9 +163,10 @@ class SubcontractingOrder(SubcontractingController): elif self.per_received > 0 and self.per_received < 100: status = "Partially Received" for item in self.supplied_items: - if item.returned_qty: - status = "Closed" + if not item.returned_qty or (item.supplied_qty - item.consumed_qty - item.returned_qty) > 0: break + else: + status = "Closed" else: total_required_qty = total_supplied_qty = 0 for item in self.supplied_items: From 8de1d8663f67fb491f07f10ecef31e429538dda8 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 1 Jul 2023 10:42:33 +0530 Subject: [PATCH 05/14] fix: project filtering based on company in P&L Report (#35943) * fix: project filtering in P&L Report (cherry picked from commit 904ca746a69e3e53fd8469fadac56d18d5af9e27) * fix: show projects with no company value set (cherry picked from commit ce252a0d45918f9cb03626bad9521e92df2be260) * fix: make company field mandatory in project doctype (cherry picked from commit 84d4888f5fcd8ff98e308b501b63f28d890dd861) --------- Co-authored-by: Gursheen Anand --- .../profit_and_loss_statement/profit_and_loss_statement.js | 6 ++++-- erpnext/projects/doctype/project/project.json | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js index 1c461efbcd3..298d83894c6 100644 --- a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js +++ b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js @@ -14,8 +14,10 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() { "label": __("Project"), "fieldtype": "MultiSelectList", get_data: function(txt) { - return frappe.db.get_link_options('Project', txt); - } + return frappe.db.get_link_options('Project', txt, { + company: frappe.query_report.get_filter_value("company") + }); + }, }, { "fieldname": "include_default_book_entries", diff --git a/erpnext/projects/doctype/project/project.json b/erpnext/projects/doctype/project/project.json index ba7aa850825..8238af0ad16 100644 --- a/erpnext/projects/doctype/project/project.json +++ b/erpnext/projects/doctype/project/project.json @@ -289,7 +289,8 @@ "fieldtype": "Link", "label": "Company", "options": "Company", - "remember_last_selected_value": 1 + "remember_last_selected_value": 1, + "reqd": 1 }, { "fieldname": "column_break_28", From a485e4e802d48c10e59205b111bd3e04c2fccc09 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 1 Jul 2023 18:13:46 +0530 Subject: [PATCH 06/14] fix: Expense Account filter in Sales Invoice (#35944) fix: Expense Account filter in Sales Invoice (#35944) (cherry picked from commit d54f52474af27d129fc1bcbb166933bf0fc94fbc) Co-authored-by: Deepesh Garg --- .../accounts/doctype/sales_invoice/sales_invoice.js | 13 ------------- erpnext/public/js/controllers/transaction.js | 4 +++- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index 8cb29505eb2..66cf87761d9 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -670,19 +670,6 @@ frappe.ui.form.on('Sales Invoice', { } } - // expense account - frm.fields_dict['items'].grid.get_field('expense_account').get_query = function(doc) { - if (erpnext.is_perpetual_inventory_enabled(doc.company)) { - return { - filters: { - 'report_type': 'Profit and Loss', - 'company': doc.company, - "is_group": 0 - } - } - } - } - // discount account frm.fields_dict['items'].grid.get_field('discount_account').get_query = function(doc) { return { diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 26dd13c3e3f..cfbb54ab2d0 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -182,7 +182,9 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe this.frm.set_query("expense_account", "items", function(doc) { return { filters: { - "company": doc.company + "company": doc.company, + "report_type": "Profit and Loss", + "is_group": 0 } }; }); From c0c693d8b0faf42089314cf43f4fc117f45de4b4 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Sat, 1 Jul 2023 11:30:46 +0530 Subject: [PATCH 07/14] fix: reposting has not changed valuation rate --- .../purchase_receipt/test_purchase_receipt.py | 115 ++++++++++++++++++ erpnext/stock/stock_ledger.py | 6 + 2 files changed, 121 insertions(+) diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py index 7965864cd43..222483327d1 100644 --- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -1797,6 +1797,121 @@ class TestPurchaseReceipt(FrappeTestCase): self.assertEqual(abs(data["stock_value_difference"]), 400.00) + def test_purchase_receipt_with_backdated_landed_cost_voucher(self): + from erpnext.controllers.sales_and_purchase_return import make_return_doc + from erpnext.stock.doctype.landed_cost_voucher.test_landed_cost_voucher import ( + create_landed_cost_voucher, + ) + from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry + + item_code = "_Test Purchase Item With Landed Cost" + create_item(item_code) + + warehouse = create_warehouse("_Test Purchase Warehouse With Landed Cost") + warehouse1 = create_warehouse("_Test Purchase Warehouse With Landed Cost 1") + warehouse2 = create_warehouse("_Test Purchase Warehouse With Landed Cost 2") + warehouse3 = create_warehouse("_Test Purchase Warehouse With Landed Cost 3") + + pr = make_purchase_receipt( + item_code=item_code, + warehouse=warehouse, + posting_date=add_days(today(), -10), + posting_time="10:59:59", + qty=100, + rate=275.00, + ) + + pr_return = make_return_doc("Purchase Receipt", pr.name) + pr_return.posting_date = add_days(today(), -9) + pr_return.items[0].qty = 2 * -1 + pr_return.items[0].received_qty = 2 * -1 + pr_return.submit() + + ste1 = make_stock_entry( + purpose="Material Transfer", + posting_date=add_days(today(), -8), + source=warehouse, + target=warehouse1, + item_code=item_code, + qty=20, + company=pr.company, + ) + + ste1.reload() + self.assertEqual(ste1.items[0].valuation_rate, 275.00) + + ste2 = make_stock_entry( + purpose="Material Transfer", + posting_date=add_days(today(), -7), + source=warehouse, + target=warehouse2, + item_code=item_code, + qty=20, + company=pr.company, + ) + + ste2.reload() + self.assertEqual(ste2.items[0].valuation_rate, 275.00) + + ste3 = make_stock_entry( + purpose="Material Transfer", + posting_date=add_days(today(), -6), + source=warehouse, + target=warehouse3, + item_code=item_code, + qty=20, + company=pr.company, + ) + + ste3.reload() + self.assertEqual(ste3.items[0].valuation_rate, 275.00) + + ste4 = make_stock_entry( + purpose="Material Transfer", + posting_date=add_days(today(), -5), + source=warehouse1, + target=warehouse, + item_code=item_code, + qty=20, + company=pr.company, + ) + + ste4.reload() + self.assertEqual(ste4.items[0].valuation_rate, 275.00) + + ste5 = make_stock_entry( + purpose="Material Transfer", + posting_date=add_days(today(), -4), + source=warehouse, + target=warehouse1, + item_code=item_code, + qty=20, + company=pr.company, + ) + + ste5.reload() + self.assertEqual(ste5.items[0].valuation_rate, 275.00) + + create_landed_cost_voucher("Purchase Receipt", pr.name, pr.company, charges=2500 * -1) + + pr.reload() + valuation_rate = pr.items[0].valuation_rate + + ste1.reload() + self.assertEqual(ste1.items[0].valuation_rate, valuation_rate) + + ste2.reload() + self.assertEqual(ste2.items[0].valuation_rate, valuation_rate) + + ste3.reload() + self.assertEqual(ste3.items[0].valuation_rate, valuation_rate) + + ste4.reload() + self.assertEqual(ste4.items[0].valuation_rate, valuation_rate) + + ste5.reload() + self.assertEqual(ste5.items[0].valuation_rate, valuation_rate) + def prepare_data_for_internal_transfer(): from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index 9c399168175..e0de9913f08 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -513,6 +513,7 @@ class update_entries_after(object): def update_distinct_item_warehouses(self, dependant_sle): key = (dependant_sle.item_code, dependant_sle.warehouse) val = frappe._dict({"sle": dependant_sle}) + if key not in self.distinct_item_warehouses: self.distinct_item_warehouses[key] = val self.new_items_found = True @@ -524,6 +525,9 @@ class update_entries_after(object): val.sle_changed = True self.distinct_item_warehouses[key] = val self.new_items_found = True + elif self.distinct_item_warehouses[key].get("reposting_status"): + self.distinct_item_warehouses[key] = val + self.new_items_found = True def process_sle(self, sle): from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos @@ -1255,6 +1259,8 @@ def get_sle_by_voucher_detail_no(voucher_detail_no, excluded_sle=None): [ "item_code", "warehouse", + "actual_qty", + "qty_after_transaction", "posting_date", "posting_time", "timestamp(posting_date, posting_time) as timestamp", From a974091678fdeef31e970e6da0d0308a2d2d716a Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 3 Jul 2023 10:23:36 +0530 Subject: [PATCH 08/14] feat: add method for ordered quantity in supplier scorecard (backport #35930) (#35968) feat: add method for ordered quantity in supplier scorecard (#35930) fix: add method for getting ordered quantity in the supplier scorecard variable. Co-authored-by: vishnu (cherry picked from commit e05b33a6c23cf9d21ec687a383cf937bc5767ad9) Co-authored-by: Vishnu VS --- .../supplier_scorecard/supplier_scorecard.py | 5 +++++ .../supplier_scorecard_variable.py | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.py b/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.py index 486bf23e909..58da8512951 100644 --- a/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.py +++ b/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.py @@ -329,6 +329,11 @@ def make_default_records(): "variable_label": "Total Shipments", "path": "get_total_shipments", }, + { + "param_name": "total_ordered", + "variable_label": "Total Ordered", + "path": "get_ordered_qty", + }, ] install_standing_docs = [ { diff --git a/erpnext/buying/doctype/supplier_scorecard_variable/supplier_scorecard_variable.py b/erpnext/buying/doctype/supplier_scorecard_variable/supplier_scorecard_variable.py index fb8819eaf81..4080d1fde09 100644 --- a/erpnext/buying/doctype/supplier_scorecard_variable/supplier_scorecard_variable.py +++ b/erpnext/buying/doctype/supplier_scorecard_variable/supplier_scorecard_variable.py @@ -7,6 +7,7 @@ import sys import frappe from frappe import _ from frappe.model.document import Document +from frappe.query_builder.functions import Sum from frappe.utils import getdate @@ -422,6 +423,23 @@ def get_total_shipments(scorecard): return data +def get_ordered_qty(scorecard): + """Returns the total number of ordered quantity (based on Purchase Orders)""" + + po = frappe.qb.DocType("Purchase Order") + + return ( + frappe.qb.from_(po) + .select(Sum(po.total_qty)) + .where( + (po.supplier == scorecard.supplier) + & (po.docstatus == 1) + & (po.transaction_date >= scorecard.get("start_date")) + & (po.transaction_date <= scorecard.get("end_date")) + ) + ).run(as_list=True)[0][0] or 0 + + def get_rfq_total_number(scorecard): """Gets the total number of RFQs sent to supplier""" supplier = frappe.get_doc("Supplier", scorecard.supplier) From c330f476802fd2ced925ebf17da79e46a3bdf4f4 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 3 Jul 2023 16:38:08 +0530 Subject: [PATCH 09/14] fix: Update no copy for received_qty field (#35965) * fix: Update no copy for received_qty field (#35965) (cherry picked from commit 544885925480bcaea382357600f22d7c134ab6f2) # Conflicts: # erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json # erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json * chore: resolve conflicts * chore: resolve conflicts --------- Co-authored-by: Deepesh Garg --- .../doctype/purchase_invoice_item/purchase_invoice_item.json | 5 +++-- .../doctype/purchase_receipt_item/purchase_receipt_item.json | 5 +++-- 2 files changed, 6 insertions(+), 4 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 1fa7e7f3fc7..f8c1975863e 100644 --- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json +++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json @@ -176,6 +176,7 @@ "fieldname": "received_qty", "fieldtype": "Float", "label": "Received Qty", + "no_copy": 1, "read_only": 1 }, { @@ -880,7 +881,7 @@ "idx": 1, "istable": 1, "links": [], - "modified": "2022-11-29 13:01:20.438217", + "modified": "2023-07-02 18:39:41.495723", "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice Item", @@ -890,4 +891,4 @@ "sort_field": "modified", "sort_order": "DESC", "states": [] -} \ 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 cd320fdfcd0..98d6154f22e 100644 --- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json +++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json @@ -206,6 +206,7 @@ "fieldname": "received_qty", "fieldtype": "Float", "label": "Received Quantity", + "no_copy": 1, "oldfieldname": "received_qty", "oldfieldtype": "Currency", "print_hide": 1, @@ -1021,7 +1022,7 @@ "idx": 1, "istable": 1, "links": [], - "modified": "2023-02-28 15:43:04.470104", + "modified": "2023-07-02 18:40:48.152637", "modified_by": "Administrator", "module": "Stock", "name": "Purchase Receipt Item", @@ -1032,4 +1033,4 @@ "sort_field": "modified", "sort_order": "DESC", "states": [] -} \ No newline at end of file +} From 2e2c23aa0fc9b4d56e805c8a4cefd71efdb4c38b Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Fri, 23 Jun 2023 14:50:14 +0530 Subject: [PATCH 10/14] fix: get base grand total while pulling reference details in PE (cherry picked from commit 9e73af891d9ff514521a2b4613aab938ef74437f) --- erpnext/accounts/doctype/payment_entry/payment_entry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index 6e6505fd6dd..371e8138567 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -1735,7 +1735,7 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre if not total_amount: if party_account_currency == company_currency: # for handling cases that don't have multi-currency (base field) - total_amount = ref_doc.get("grand_total") or ref_doc.get("base_grand_total") + total_amount = ref_doc.get("base_grand_total") or ref_doc.get("grand_total") exchange_rate = 1 else: total_amount = ref_doc.get("grand_total") From 3d1942571dd36372bb3b89caa796bc305546786e Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Fri, 23 Jun 2023 16:35:44 +0530 Subject: [PATCH 11/14] test: test reference details response (cherry picked from commit 9655d786428467c5ce27f556612f9bf1ea5f802c) --- .../payment_entry/test_payment_entry.py | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py index 278b12f6595..ae2625b6539 100644 --- a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py @@ -11,6 +11,7 @@ from frappe.utils import flt, nowdate from erpnext.accounts.doctype.payment_entry.payment_entry import ( InvalidPaymentEntry, get_payment_entry, + get_reference_details, ) from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import ( make_purchase_invoice, @@ -1037,6 +1038,29 @@ class TestPaymentEntry(FrappeTestCase): self.assertRaises(frappe.ValidationError, pe_draft.submit) + def test_details_update_on_reference_table(self): + so = make_sales_order( + customer="_Test Customer USD", currency="USD", qty=1, rate=100, do_not_submit=True + ) + so.conversion_rate = 50 + so.submit() + pe = get_payment_entry("Sales Order", so.name) + pe.references.clear() + pe.paid_from = "Debtors - _TC" + pe.paid_from_account_currency = "INR" + pe.source_exchange_rate = 50 + pe.save() + + ref_details = get_reference_details(so.doctype, so.name, pe.paid_from_account_currency) + expected_response = { + "total_amount": 5000.0, + "outstanding_amount": 5000.0, + "exchange_rate": 1.0, + "due_date": None, + "bill_no": None, + } + self.assertDictEqual(ref_details, expected_response) + def create_payment_entry(**args): payment_entry = frappe.new_doc("Payment Entry") From 13f3ebf915ba36b10b6d616d5a942307b9b71b66 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 4 Jul 2023 16:22:17 +0530 Subject: [PATCH 12/14] fix: Netherlands - Grootboekschema COA structure (#35991) fix: Netherlands - Grootboekschema COA structure (#35991) fix: Netherlands - Grootboekschema coa structure (cherry picked from commit 2f169575e9603009a4473bf14c2d36a006bf829e) Co-authored-by: Deepesh Garg --- .../verified/nl_grootboekschema.json | 784 +++++++++--------- 1 file changed, 393 insertions(+), 391 deletions(-) diff --git a/erpnext/accounts/doctype/account/chart_of_accounts/verified/nl_grootboekschema.json b/erpnext/accounts/doctype/account/chart_of_accounts/verified/nl_grootboekschema.json index 58b91227f79..9fb47bb02dd 100644 --- a/erpnext/accounts/doctype/account/chart_of_accounts/verified/nl_grootboekschema.json +++ b/erpnext/accounts/doctype/account/chart_of_accounts/verified/nl_grootboekschema.json @@ -2,75 +2,13 @@ "country_code": "nl", "name": "Netherlands - Grootboekschema", "tree": { - "FABRIKAGEREKENINGEN": { - "is_group": 1, - "root_type": "Expense" - }, "FINANCIELE REKENINGEN, KORTLOPENDE VORDERINGEN EN SCHULDEN": { "Bank": { "RABO Bank": { "account_type": "Bank" }, "account_type": "Bank" - }, - "KORTLOPENDE SCHULDEN": { - "Af te dragen Btw-verlegd": { - "account_type": "Tax" - }, - "Afdracht loonheffing": {}, - "Btw af te dragen hoog": { - "account_type": "Tax" - }, - "Btw af te dragen laag": { - "account_type": "Tax" - }, - "Btw af te dragen overig": { - "account_type": "Tax" - }, - "Btw oude jaren": { - "account_type": "Tax" - }, - "Btw te vorderen hoog": { - "account_type": "Tax" - }, - "Btw te vorderen laag": { - "account_type": "Tax" - }, - "Btw te vorderen overig": { - "account_type": "Tax" - }, - "Btw-afdracht": { - "account_type": "Tax" - }, - "Crediteuren": { - "account_type": "Payable" - }, - "Dividend": {}, - "Dividendbelasting": {}, - "Energiekosten 1": {}, - "Investeringsaftrek": {}, - "Loonheffing": {}, - "Overige te betalen posten": {}, - "Pensioenpremies 1": {}, - "Premie WIR": {}, - "Rekening-courant inkoopvereniging": {}, - "Rente": {}, - "Sociale lasten 1": {}, - "Stock Recieved niet gefactureerd": { - "account_type": "Stock Received But Not Billed" - }, - "Tanti\u00e8mes 1": {}, - "Te vorderen Btw-verlegd": { - "account_type": "Tax" - }, - "Telefoon/telefax 1": {}, - "Termijnen onderh. werk": {}, - "Vakantiedagen": {}, - "Vakantiegeld 1": {}, - "Vakantiezegels": {}, - "Vennootschapsbelasting": {}, - "Vooruit ontvangen bedr.": {} - }, + }, "LIQUIDE MIDDELEN": { "ABN-AMRO bank": {}, "Bankbetaalkaarten": {}, @@ -91,6 +29,110 @@ }, "account_type": "Cash" }, + "TUSSENREKENINGEN": { + "Betaalwijze cadeaubonnen": { + "account_type": "Cash" + }, + "Betaalwijze chipknip": { + "account_type": "Cash" + }, + "Betaalwijze contant": { + "account_type": "Cash" + }, + "Betaalwijze pin": { + "account_type": "Cash" + }, + "Inkopen Nederland hoog": { + "account_type": "Cash" + }, + "Inkopen Nederland laag": { + "account_type": "Cash" + }, + "Inkopen Nederland onbelast": { + "account_type": "Cash" + }, + "Inkopen Nederland overig": { + "account_type": "Cash" + }, + "Inkopen Nederland verlegd": { + "account_type": "Cash" + }, + "Inkopen binnen EU hoog": { + "account_type": "Cash" + }, + "Inkopen binnen EU laag": { + "account_type": "Cash" + }, + "Inkopen binnen EU overig": { + "account_type": "Cash" + }, + "Inkopen buiten EU hoog": { + "account_type": "Cash" + }, + "Inkopen buiten EU laag": { + "account_type": "Cash" + }, + "Inkopen buiten EU overig": { + "account_type": "Cash" + }, + "Kassa 1": { + "account_type": "Cash" + }, + "Kassa 2": { + "account_type": "Cash" + }, + "Netto lonen": { + "account_type": "Cash" + }, + "Tegenrekening Inkopen": { + "account_type": "Cash" + }, + "Tussenrek. autom. betalingen": { + "account_type": "Cash" + }, + "Tussenrek. autom. loonbetalingen": { + "account_type": "Cash" + }, + "Tussenrek. cadeaubonbetalingen": { + "account_type": "Cash" + }, + "Tussenrekening balans": { + "account_type": "Cash" + }, + "Tussenrekening chipknip": { + "account_type": "Cash" + }, + "Tussenrekening correcties": { + "account_type": "Cash" + }, + "Tussenrekening pin": { + "account_type": "Cash" + }, + "Vraagposten": { + "account_type": "Cash" + }, + "VOORRAAD GRONDSTOFFEN, HULPMATERIALEN EN HANDELSGOEDEREN": { + "Emballage": {}, + "Gereed product 1": {}, + "Gereed product 2": {}, + "Goederen 1": {}, + "Goederen 2": {}, + "Goederen in consignatie": {}, + "Goederen onderweg": {}, + "Grondstoffen 1": {}, + "Grondstoffen 2": {}, + "Halffabrikaten 1": {}, + "Halffabrikaten 2": {}, + "Hulpstoffen 1": {}, + "Hulpstoffen 2": {}, + "Kantoorbenodigdheden": {}, + "Onderhanden werk": {}, + "Verpakkingsmateriaal": {}, + "Zegels": {}, + "root_type": "Asset" + }, + "root_type": "Asset" + }, "VORDERINGEN": { "Debiteuren": { "account_type": "Receivable" @@ -104,278 +146,299 @@ "Voorziening dubieuze debiteuren": {} }, "root_type": "Asset" - }, - "INDIRECTE KOSTEN": { + }, + "KORTLOPENDE SCHULDEN": { + "Af te dragen Btw-verlegd": { + "account_type": "Tax" + }, + "Afdracht loonheffing": {}, + "Btw af te dragen hoog": { + "account_type": "Tax" + }, + "Btw af te dragen laag": { + "account_type": "Tax" + }, + "Btw af te dragen overig": { + "account_type": "Tax" + }, + "Btw oude jaren": { + "account_type": "Tax" + }, + "Btw te vorderen hoog": { + "account_type": "Tax" + }, + "Btw te vorderen laag": { + "account_type": "Tax" + }, + "Btw te vorderen overig": { + "account_type": "Tax" + }, + "Btw-afdracht": { + "account_type": "Tax" + }, + "Crediteuren": { + "account_type": "Payable" + }, + "Dividend": {}, + "Dividendbelasting": {}, + "Energiekosten 1": {}, + "Investeringsaftrek": {}, + "Loonheffing": {}, + "Overige te betalen posten": {}, + "Pensioenpremies 1": {}, + "Premie WIR": {}, + "Rekening-courant inkoopvereniging": {}, + "Rente": {}, + "Sociale lasten 1": {}, + "Stock Recieved niet gefactureerd": { + "account_type": "Stock Received But Not Billed" + }, + "Tanti\u00e8mes 1": {}, + "Te vorderen Btw-verlegd": { + "account_type": "Tax" + }, + "Telefoon/telefax 1": {}, + "Termijnen onderh. werk": {}, + "Vakantiedagen": {}, + "Vakantiegeld 1": {}, + "Vakantiezegels": {}, + "Vennootschapsbelasting": {}, + "Vooruit ontvangen bedr.": {}, + "is_group": 1, + "root_type": "Liability" + }, + "FABRIKAGEREKENINGEN": { "is_group": 1, - "root_type": "Expense" - }, - "KOSTENREKENINGEN": { - "AFSCHRIJVINGEN": { - "Aanhangwagens": {}, - "Aankoopkosten": {}, - "Aanloopkosten": {}, - "Auteursrechten": {}, - "Bedrijfsgebouwen": {}, - "Bedrijfsinventaris": { + "root_type": "Expense", + "INDIRECTE KOSTEN": { + "is_group": 1, + "root_type": "Expense" + }, + "KOSTENREKENINGEN": { + "AFSCHRIJVINGEN": { + "Aanhangwagens": {}, + "Aankoopkosten": {}, + "Aanloopkosten": {}, + "Auteursrechten": {}, + "Bedrijfsgebouwen": {}, + "Bedrijfsinventaris": { + "account_type": "Depreciation" + }, + "Drankvergunningen": {}, + "Fabrieksinventaris": { + "account_type": "Depreciation" + }, + "Gebouwen": {}, + "Gereedschappen": {}, + "Goodwill": {}, + "Grondverbetering": {}, + "Heftrucks": {}, + "Kantine-inventaris": {}, + "Kantoorinventaris": { + "account_type": "Depreciation" + }, + "Kantoormachines": {}, + "Licenties": {}, + "Machines 1": {}, + "Magazijninventaris": {}, + "Octrooien": {}, + "Ontwikkelingskosten": {}, + "Pachtersinvestering": {}, + "Parkeerplaats": {}, + "Personenauto's": { + "account_type": "Depreciation" + }, + "Rijwielen en bromfietsen": {}, + "Tonnagevergunningen": {}, + "Verbouwingen": {}, + "Vergunningen": {}, + "Voorraadverschillen": {}, + "Vrachtauto's": {}, + "Winkels": {}, + "Woon-winkelhuis": {}, "account_type": "Depreciation" }, - "Drankvergunningen": {}, - "Fabrieksinventaris": { - "account_type": "Depreciation" + "ALGEMENE KOSTEN": { + "Accountantskosten": {}, + "Advieskosten": {}, + "Assuranties 1": {}, + "Bankkosten": {}, + "Juridische kosten": {}, + "Overige algemene kosten": {}, + "Toev. Ass. eigen risico": {} }, - "Gebouwen": {}, - "Gereedschappen": {}, - "Goodwill": {}, - "Grondverbetering": {}, - "Heftrucks": {}, - "Kantine-inventaris": {}, - "Kantoorinventaris": { - "account_type": "Depreciation" + "BEDRIJFSKOSTEN": { + "Assuranties 2": {}, + "Energie (krachtstroom)": {}, + "Gereedschappen 1": {}, + "Hulpmaterialen 1": {}, + "Huur inventaris": {}, + "Huur machines": {}, + "Leasing invent.operational": {}, + "Leasing mach. operational": {}, + "Onderhoud inventaris": {}, + "Onderhoud machines": {}, + "Ophalen/vervoer afval": {}, + "Overige bedrijfskosten": {} }, - "Kantoormachines": {}, - "Licenties": {}, - "Machines 1": {}, - "Magazijninventaris": {}, - "Octrooien": {}, - "Ontwikkelingskosten": {}, - "Pachtersinvestering": {}, - "Parkeerplaats": {}, - "Personenauto's": { - "account_type": "Depreciation" + "FINANCIERINGSKOSTEN 1": { + "Overige rentebaten": {}, + "Overige rentelasten": {}, + "Rente bankkrediet": {}, + "Rente huurkoopcontracten": {}, + "Rente hypotheek": {}, + "Rente leasecontracten": {}, + "Rente lening o/g": {}, + "Rente lening u/g": {} }, - "Rijwielen en bromfietsen": {}, - "Tonnagevergunningen": {}, - "Verbouwingen": {}, - "Vergunningen": {}, - "Voorraadverschillen": {}, - "Vrachtauto's": {}, - "Winkels": {}, - "Woon-winkelhuis": {}, - "account_type": "Depreciation" - }, - "ALGEMENE KOSTEN": { - "Accountantskosten": {}, - "Advieskosten": {}, - "Assuranties 1": {}, - "Bankkosten": {}, - "Juridische kosten": {}, - "Overige algemene kosten": {}, - "Toev. Ass. eigen risico": {} - }, - "BEDRIJFSKOSTEN": { - "Assuranties 2": {}, - "Energie (krachtstroom)": {}, - "Gereedschappen 1": {}, - "Hulpmaterialen 1": {}, - "Huur inventaris": {}, - "Huur machines": {}, - "Leasing invent.operational": {}, - "Leasing mach. operational": {}, - "Onderhoud inventaris": {}, - "Onderhoud machines": {}, - "Ophalen/vervoer afval": {}, - "Overige bedrijfskosten": {} - }, - "FINANCIERINGSKOSTEN 1": { - "Overige rentebaten": {}, - "Overige rentelasten": {}, - "Rente bankkrediet": {}, - "Rente huurkoopcontracten": {}, - "Rente hypotheek": {}, - "Rente leasecontracten": {}, - "Rente lening o/g": {}, - "Rente lening u/g": {} - }, - "HUISVESTINGSKOSTEN": { - "Assurantie onroerend goed": {}, - "Belastingen onr. Goed": {}, - "Energiekosten": {}, - "Groot onderhoud onr. Goed": {}, - "Huur": {}, - "Huurwaarde woongedeelte": {}, - "Onderhoud onroerend goed": {}, - "Ontvangen huren": {}, - "Overige huisvestingskosten": {}, - "Pacht": {}, - "Schoonmaakkosten": {}, - "Toevoeging egalisatieres. Groot onderhoud": {} - }, - "KANTOORKOSTEN": { - "Administratiekosten": {}, - "Contributies/abonnementen": {}, - "Huur kantoorapparatuur": {}, - "Internetaansluiting": {}, - "Kantoorbenodigdh./drukw.": {}, - "Onderhoud kantoorinvent.": {}, - "Overige kantoorkosten": {}, - "Porti": {}, - "Telefoon/telefax": {} - }, - "OVERIGE BATEN EN LASTEN": { - "Betaalde schadevergoed.": {}, - "Boekverlies vaste activa": {}, - "Boekwinst van vaste activa": {}, - "K.O. regeling OB": {}, - "Kasverschillen": {}, - "Kosten loonbelasting": {}, - "Kosten omzetbelasting": {}, - "Nadelige koersverschillen": {}, - "Naheffing bedrijfsver.": {}, - "Ontvangen schadevergoed.": {}, - "Overige baten": {}, - "Overige lasten": {}, - "Voordelige koersverschil.": {} - }, - "PERSONEELSKOSTEN": { - "Autokostenvergoeding": {}, - "Bedrijfskleding": {}, - "Belastingvrije uitkeringen": {}, - "Bijzondere beloningen": {}, - "Congressen, seminars en symposia": {}, - "Gereedschapsgeld": {}, - "Geschenken personeel": {}, - "Gratificaties": {}, - "Inhouding pensioenpremies": {}, - "Inhouding sociale lasten": {}, - "Kantinekosten": {}, - "Lonen en salarissen": {}, - "Loonwerk": {}, - "Managementvergoedingen": {}, - "Opleidingskosten": {}, - "Oprenting stamrechtverpl.": {}, - "Overhevelingstoeslag": {}, - "Overige kostenverg.": {}, - "Overige personeelskosten": {}, - "Overige uitkeringen": {}, - "Pensioenpremies": {}, - "Provisie 1": {}, - "Reiskosten": {}, - "Rijwielvergoeding": {}, - "Sociale lasten": {}, - "Tanti\u00e8mes": {}, - "Thuiswerkers": {}, - "Toev. Backservice pens.verpl.": {}, - "Toevoeging pensioenverpl.": {}, - "Uitkering ziekengeld": {}, - "Uitzendkrachten": {}, - "Vakantiebonnen": {}, - "Vakantiegeld": {}, - "Vergoeding studiekosten": {}, - "Wervingskosten personeel": {} - }, - "VERKOOPKOSTEN": { - "Advertenties": {}, - "Afschrijving dubieuze deb.": {}, - "Beurskosten": {}, - "Etalagekosten": {}, - "Exportkosten": {}, - "Kascorrecties": {}, - "Overige verkoopkosten": {}, - "Provisie": {}, - "Reclame": {}, - "Reis en verblijfkosten": {}, - "Relatiegeschenken": {}, - "Representatiekosten": {}, - "Uitgaande vrachten": {}, - "Veilingkosten": {}, - "Verpakkingsmateriaal 1": {}, - "Websitekosten": {} - }, - "VERVOERSKOSTEN": { - "Assuranties auto's": {}, - "Brandstoffen": {}, - "Leasing auto's": {}, - "Onderhoud personenauto's": {}, - "Onderhoud vrachtauto's": {}, - "Overige vervoerskosten": {}, - "Priv\u00e9-gebruik auto's": {}, - "Wegenbelasting": {} - }, - "root_type": "Expense" - }, - "TUSSENREKENINGEN": { - "Betaalwijze cadeaubonnen": { - "account_type": "Cash" - }, - "Betaalwijze chipknip": { - "account_type": "Cash" - }, - "Betaalwijze contant": { - "account_type": "Cash" - }, - "Betaalwijze pin": { - "account_type": "Cash" - }, - "Inkopen Nederland hoog": { - "account_type": "Cash" - }, - "Inkopen Nederland laag": { - "account_type": "Cash" - }, - "Inkopen Nederland onbelast": { - "account_type": "Cash" - }, - "Inkopen Nederland overig": { - "account_type": "Cash" - }, - "Inkopen Nederland verlegd": { - "account_type": "Cash" - }, - "Inkopen binnen EU hoog": { - "account_type": "Cash" - }, - "Inkopen binnen EU laag": { - "account_type": "Cash" - }, - "Inkopen binnen EU overig": { - "account_type": "Cash" - }, - "Inkopen buiten EU hoog": { - "account_type": "Cash" - }, - "Inkopen buiten EU laag": { - "account_type": "Cash" - }, - "Inkopen buiten EU overig": { - "account_type": "Cash" - }, - "Kassa 1": { - "account_type": "Cash" - }, - "Kassa 2": { - "account_type": "Cash" - }, - "Netto lonen": { - "account_type": "Cash" - }, - "Tegenrekening Inkopen": { - "account_type": "Cash" - }, - "Tussenrek. autom. betalingen": { - "account_type": "Cash" - }, - "Tussenrek. autom. loonbetalingen": { - "account_type": "Cash" - }, - "Tussenrek. cadeaubonbetalingen": { - "account_type": "Cash" - }, - "Tussenrekening balans": { - "account_type": "Cash" - }, - "Tussenrekening chipknip": { - "account_type": "Cash" - }, - "Tussenrekening correcties": { - "account_type": "Cash" - }, - "Tussenrekening pin": { - "account_type": "Cash" - }, - "Vraagposten": { - "account_type": "Cash" - }, - "root_type": "Asset" + "HUISVESTINGSKOSTEN": { + "Assurantie onroerend goed": {}, + "Belastingen onr. Goed": {}, + "Energiekosten": {}, + "Groot onderhoud onr. Goed": {}, + "Huur": {}, + "Huurwaarde woongedeelte": {}, + "Onderhoud onroerend goed": {}, + "Ontvangen huren": {}, + "Overige huisvestingskosten": {}, + "Pacht": {}, + "Schoonmaakkosten": {}, + "Toevoeging egalisatieres. Groot onderhoud": {} + }, + "KANTOORKOSTEN": { + "Administratiekosten": {}, + "Contributies/abonnementen": {}, + "Huur kantoorapparatuur": {}, + "Internetaansluiting": {}, + "Kantoorbenodigdh./drukw.": {}, + "Onderhoud kantoorinvent.": {}, + "Overige kantoorkosten": {}, + "Porti": {}, + "Telefoon/telefax": {} + }, + "OVERIGE BATEN EN LASTEN": { + "Betaalde schadevergoed.": {}, + "Boekverlies vaste activa": {}, + "Boekwinst van vaste activa": {}, + "K.O. regeling OB": {}, + "Kasverschillen": {}, + "Kosten loonbelasting": {}, + "Kosten omzetbelasting": {}, + "Nadelige koersverschillen": {}, + "Naheffing bedrijfsver.": {}, + "Ontvangen schadevergoed.": {}, + "Overige baten": {}, + "Overige lasten": {}, + "Voordelige koersverschil.": {} + }, + "PERSONEELSKOSTEN": { + "Autokostenvergoeding": {}, + "Bedrijfskleding": {}, + "Belastingvrije uitkeringen": {}, + "Bijzondere beloningen": {}, + "Congressen, seminars en symposia": {}, + "Gereedschapsgeld": {}, + "Geschenken personeel": {}, + "Gratificaties": {}, + "Inhouding pensioenpremies": {}, + "Inhouding sociale lasten": {}, + "Kantinekosten": {}, + "Lonen en salarissen": {}, + "Loonwerk": {}, + "Managementvergoedingen": {}, + "Opleidingskosten": {}, + "Oprenting stamrechtverpl.": {}, + "Overhevelingstoeslag": {}, + "Overige kostenverg.": {}, + "Overige personeelskosten": {}, + "Overige uitkeringen": {}, + "Pensioenpremies": {}, + "Provisie 1": {}, + "Reiskosten": {}, + "Rijwielvergoeding": {}, + "Sociale lasten": {}, + "Tanti\u00e8mes": {}, + "Thuiswerkers": {}, + "Toev. Backservice pens.verpl.": {}, + "Toevoeging pensioenverpl.": {}, + "Uitkering ziekengeld": {}, + "Uitzendkrachten": {}, + "Vakantiebonnen": {}, + "Vakantiegeld": {}, + "Vergoeding studiekosten": {}, + "Wervingskosten personeel": {} + }, + "VERKOOPKOSTEN": { + "Advertenties": {}, + "Afschrijving dubieuze deb.": {}, + "Beurskosten": {}, + "Etalagekosten": {}, + "Exportkosten": {}, + "Kascorrecties": {}, + "Overige verkoopkosten": {}, + "Provisie": {}, + "Reclame": {}, + "Reis en verblijfkosten": {}, + "Relatiegeschenken": {}, + "Representatiekosten": {}, + "Uitgaande vrachten": {}, + "Veilingkosten": {}, + "Verpakkingsmateriaal 1": {}, + "Websitekosten": {} + }, + "VERVOERSKOSTEN": { + "Assuranties auto's": {}, + "Brandstoffen": {}, + "Leasing auto's": {}, + "Onderhoud personenauto's": {}, + "Onderhoud vrachtauto's": {}, + "Overige vervoerskosten": {}, + "Priv\u00e9-gebruik auto's": {}, + "Wegenbelasting": {} + }, + "VOORRAAD GEREED PRODUCT EN ONDERHANDEN WERK": { + "Betalingskort. crediteuren": {}, + "Garantiekosten": {}, + "Hulpmaterialen": {}, + "Inkomende vrachten": { + "account_type": "Expenses Included In Valuation" + }, + "Inkoop import buiten EU hoog": {}, + "Inkoop import buiten EU laag": {}, + "Inkoop import buiten EU overig": {}, + "Inkoopbonussen": {}, + "Inkoopkosten": {}, + "Inkoopprovisie": {}, + "Inkopen BTW verlegd": {}, + "Inkopen EU hoog tarief": {}, + "Inkopen EU laag tarief": {}, + "Inkopen EU overig": {}, + "Inkopen hoog": {}, + "Inkopen laag": {}, + "Inkopen nul": {}, + "Inkopen overig": {}, + "Invoerkosten": {}, + "Kosten inkoopvereniging": {}, + "Kostprijs omzet grondstoffen": { + "account_type": "Cost of Goods Sold" + }, + "Kostprijs omzet handelsgoederen": {}, + "Onttrekking uitgev.garantie": {}, + "Priv\u00e9-gebruik goederen": {}, + "Stock aanpassing": { + "account_type": "Stock Adjustment" + }, + "Tegenrekening inkoop": {}, + "Toev. Voorz. incour. grondst.": {}, + "Toevoeging garantieverpl.": {}, + "Toevoeging voorz. incour. handelsgoed.": {}, + "Uitbesteed werk": {}, + "Voorz. Incourourant grondst.": {}, + "Voorz.incour. handelsgoed.": {}, + "root_type": "Expense" + }, + "root_type": "Expense" + } }, "VASTE ACTIVA, EIGEN VERMOGEN, LANGLOPEND VREEMD VERMOGEN EN VOORZIENINGEN": { "EIGEN VERMOGEN": { @@ -602,7 +665,7 @@ "account_type": "Equity" } }, - "root_type": "Asset" + "root_type": "Equity" }, "VERKOOPRESULTATEN": { "Diensten fabric. 0% niet-EU": {}, @@ -627,67 +690,6 @@ "Verleende Kredietbep. fabricage": {}, "Verleende Kredietbep. handel": {}, "root_type": "Income" - }, - "VOORRAAD GEREED PRODUCT EN ONDERHANDEN WERK": { - "Betalingskort. crediteuren": {}, - "Garantiekosten": {}, - "Hulpmaterialen": {}, - "Inkomende vrachten": { - "account_type": "Expenses Included In Valuation" - }, - "Inkoop import buiten EU hoog": {}, - "Inkoop import buiten EU laag": {}, - "Inkoop import buiten EU overig": {}, - "Inkoopbonussen": {}, - "Inkoopkosten": {}, - "Inkoopprovisie": {}, - "Inkopen BTW verlegd": {}, - "Inkopen EU hoog tarief": {}, - "Inkopen EU laag tarief": {}, - "Inkopen EU overig": {}, - "Inkopen hoog": {}, - "Inkopen laag": {}, - "Inkopen nul": {}, - "Inkopen overig": {}, - "Invoerkosten": {}, - "Kosten inkoopvereniging": {}, - "Kostprijs omzet grondstoffen": { - "account_type": "Cost of Goods Sold" - }, - "Kostprijs omzet handelsgoederen": {}, - "Onttrekking uitgev.garantie": {}, - "Priv\u00e9-gebruik goederen": {}, - "Stock aanpassing": { - "account_type": "Stock Adjustment" - }, - "Tegenrekening inkoop": {}, - "Toev. Voorz. incour. grondst.": {}, - "Toevoeging garantieverpl.": {}, - "Toevoeging voorz. incour. handelsgoed.": {}, - "Uitbesteed werk": {}, - "Voorz. Incourourant grondst.": {}, - "Voorz.incour. handelsgoed.": {}, - "root_type": "Expense" - }, - "VOORRAAD GRONDSTOFFEN, HULPMATERIALEN EN HANDELSGOEDEREN": { - "Emballage": {}, - "Gereed product 1": {}, - "Gereed product 2": {}, - "Goederen 1": {}, - "Goederen 2": {}, - "Goederen in consignatie": {}, - "Goederen onderweg": {}, - "Grondstoffen 1": {}, - "Grondstoffen 2": {}, - "Halffabrikaten 1": {}, - "Halffabrikaten 2": {}, - "Hulpstoffen 1": {}, - "Hulpstoffen 2": {}, - "Kantoorbenodigdheden": {}, - "Onderhanden werk": {}, - "Verpakkingsmateriaal": {}, - "Zegels": {}, - "root_type": "Asset" } } } \ No newline at end of file From 47c6d9099b4a449865a8ba9e2e4820ba4d7c71be Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Tue, 4 Jul 2023 17:41:30 +0530 Subject: [PATCH 13/14] feat(accounts): standardize additional columns implementation for sales/purchase reports (#36000) (cherry picked from commit 30e4052a76d41e84617506ecfd143a6a8e6df567) --- .../item_wise_purchase_register.py | 49 +++++++---------- .../item_wise_sales_register.py | 53 +++++++------------ .../purchase_register/purchase_register.py | 28 +++++----- .../report/sales_register/sales_register.py | 52 ++++++++---------- erpnext/accounts/report/utils.py | 31 ++++++++++- 5 files changed, 99 insertions(+), 114 deletions(-) diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py index 6fdb2f337c0..050e6bc5d2f 100644 --- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py +++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py @@ -15,20 +15,21 @@ from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register i get_group_by_conditions, get_tax_accounts, ) +from erpnext.accounts.report.utils import get_query_columns, get_values_for_columns def execute(filters=None): return _execute(filters) -def _execute(filters=None, additional_table_columns=None, additional_query_columns=None): +def _execute(filters=None, additional_table_columns=None): if not filters: filters = {} columns = get_columns(additional_table_columns, filters) company_currency = erpnext.get_company_currency(filters.company) - item_list = get_items(filters, additional_query_columns) + item_list = get_items(filters, get_query_columns(additional_table_columns)) aii_account_map = get_aii_accounts() if item_list: itemised_tax, tax_columns = get_tax_accounts( @@ -79,28 +80,20 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum "posting_date": d.posting_date, "supplier": d.supplier, "supplier_name": d.supplier_name, + **get_values_for_columns(additional_table_columns, d), + "credit_to": d.credit_to, + "mode_of_payment": d.mode_of_payment, + "project": d.project, + "company": d.company, + "purchase_order": d.purchase_order, + "purchase_receipt": purchase_receipt, + "expense_account": expense_account, + "stock_qty": d.stock_qty, + "stock_uom": d.stock_uom, + "rate": d.base_net_amount / d.stock_qty if d.stock_qty else d.base_net_amount, + "amount": d.base_net_amount, } - if additional_query_columns: - for col in additional_query_columns: - row.update({col: d.get(col)}) - - row.update( - { - "credit_to": d.credit_to, - "mode_of_payment": d.mode_of_payment, - "project": d.project, - "company": d.company, - "purchase_order": d.purchase_order, - "purchase_receipt": purchase_receipt, - "expense_account": expense_account, - "stock_qty": d.stock_qty, - "stock_uom": d.stock_uom, - "rate": d.base_net_amount / d.stock_qty if d.stock_qty else d.base_net_amount, - "amount": d.base_net_amount, - } - ) - total_tax = 0 for tax in tax_columns: item_tax = itemised_tax.get(d.name, {}).get(tax, {}) @@ -317,11 +310,6 @@ def get_conditions(filters): def get_items(filters, additional_query_columns): conditions = get_conditions(filters) - if additional_query_columns: - additional_query_columns = ", " + ", ".join(additional_query_columns) - else: - additional_query_columns = "" - return frappe.db.sql( """ select @@ -340,11 +328,10 @@ def get_items(filters, additional_query_columns): from `tabPurchase Invoice`, `tabPurchase Invoice Item`, `tabItem` where `tabPurchase Invoice`.name = `tabPurchase Invoice Item`.`parent` and `tabItem`.name = `tabPurchase Invoice Item`.`item_code` and - `tabPurchase Invoice`.docstatus = 1 %s + `tabPurchase Invoice`.docstatus = 1 {1} """.format( - additional_query_columns - ) - % (conditions), + additional_query_columns, conditions + ), filters, as_dict=1, ) diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py index bd7d02e0430..4d24dd90762 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py @@ -9,6 +9,7 @@ from frappe.utils import cstr, flt from frappe.utils.xlsxutils import handle_html from erpnext.accounts.report.sales_register.sales_register import get_mode_of_payments +from erpnext.accounts.report.utils import get_query_columns, get_values_for_columns from erpnext.selling.report.item_wise_sales_history.item_wise_sales_history import ( get_customer_details, ) @@ -18,19 +19,14 @@ def execute(filters=None): return _execute(filters) -def _execute( - filters=None, - additional_table_columns=None, - additional_query_columns=None, - additional_conditions=None, -): +def _execute(filters=None, additional_table_columns=None, additional_conditions=None): if not filters: filters = {} columns = get_columns(additional_table_columns, filters) company_currency = frappe.get_cached_value("Company", filters.get("company"), "default_currency") - item_list = get_items(filters, additional_query_columns, additional_conditions) + item_list = get_items(filters, get_query_columns(additional_table_columns), additional_conditions) if item_list: itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency) @@ -79,30 +75,22 @@ def _execute( "customer": d.customer, "customer_name": customer_record.customer_name, "customer_group": customer_record.customer_group, + **get_values_for_columns(additional_table_columns, d), + "debit_to": d.debit_to, + "mode_of_payment": ", ".join(mode_of_payments.get(d.parent, [])), + "territory": d.territory, + "project": d.project, + "company": d.company, + "sales_order": d.sales_order, + "delivery_note": d.delivery_note, + "income_account": d.unrealized_profit_loss_account + if d.is_internal_customer == 1 + else d.income_account, + "cost_center": d.cost_center, + "stock_qty": d.stock_qty, + "stock_uom": d.stock_uom, } - if additional_query_columns: - for col in additional_query_columns: - row.update({col: d.get(col)}) - - row.update( - { - "debit_to": d.debit_to, - "mode_of_payment": ", ".join(mode_of_payments.get(d.parent, [])), - "territory": d.territory, - "project": d.project, - "company": d.company, - "sales_order": d.sales_order, - "delivery_note": d.delivery_note, - "income_account": d.unrealized_profit_loss_account - if d.is_internal_customer == 1 - else d.income_account, - "cost_center": d.cost_center, - "stock_qty": d.stock_qty, - "stock_uom": d.stock_uom, - } - ) - if d.stock_uom != d.uom and d.stock_qty: row.update({"rate": (d.base_net_rate * d.qty) / d.stock_qty, "amount": d.base_net_amount}) else: @@ -394,11 +382,6 @@ def get_group_by_conditions(filters, doctype): def get_items(filters, additional_query_columns, additional_conditions=None): conditions = get_conditions(filters, additional_conditions) - if additional_query_columns: - additional_query_columns = ", " + ", ".join(additional_query_columns) - else: - additional_query_columns = "" - return frappe.db.sql( """ select @@ -424,7 +407,7 @@ def get_items(filters, additional_query_columns, additional_conditions=None): `tabItem`.name = `tabSales Invoice Item`.`item_code` and `tabSales Invoice`.docstatus = 1 {1} """.format( - additional_query_columns or "", conditions + additional_query_columns, conditions ), filters, as_dict=1, diff --git a/erpnext/accounts/report/purchase_register/purchase_register.py b/erpnext/accounts/report/purchase_register/purchase_register.py index a05d581207c..69827aca694 100644 --- a/erpnext/accounts/report/purchase_register/purchase_register.py +++ b/erpnext/accounts/report/purchase_register/purchase_register.py @@ -10,17 +10,18 @@ from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import ( get_accounting_dimensions, get_dimension_with_children, ) +from erpnext.accounts.report.utils import get_query_columns, get_values_for_columns def execute(filters=None): return _execute(filters) -def _execute(filters=None, additional_table_columns=None, additional_query_columns=None): +def _execute(filters=None, additional_table_columns=None): if not filters: filters = {} - invoice_list = get_invoices(filters, additional_query_columns) + invoice_list = get_invoices(filters, get_query_columns(additional_table_columns)) columns, expense_accounts, tax_accounts, unrealized_profit_loss_accounts = get_columns( invoice_list, additional_table_columns ) @@ -47,13 +48,12 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum purchase_receipt = list(set(invoice_po_pr_map.get(inv.name, {}).get("purchase_receipt", []))) project = list(set(invoice_po_pr_map.get(inv.name, {}).get("project", []))) - row = [inv.name, inv.posting_date, inv.supplier, inv.supplier_name] - - if additional_query_columns: - for col in additional_query_columns: - row.append(inv.get(col)) - - row += [ + row = [ + inv.name, + inv.posting_date, + inv.supplier, + inv.supplier_name, + *get_values_for_columns(additional_table_columns, inv).values(), supplier_details.get(inv.supplier), # supplier_group inv.tax_id, inv.credit_to, @@ -244,9 +244,6 @@ def get_conditions(filters): def get_invoices(filters, additional_query_columns): - if additional_query_columns: - additional_query_columns = ", " + ", ".join(additional_query_columns) - conditions = get_conditions(filters) return frappe.db.sql( """ @@ -255,11 +252,10 @@ def get_invoices(filters, additional_query_columns): remarks, base_net_total, base_grand_total, outstanding_amount, mode_of_payment {0} from `tabPurchase Invoice` - where docstatus = 1 %s + where docstatus = 1 {1} order by posting_date desc, name desc""".format( - additional_query_columns or "" - ) - % conditions, + additional_query_columns, conditions + ), filters, as_dict=1, ) diff --git a/erpnext/accounts/report/sales_register/sales_register.py b/erpnext/accounts/report/sales_register/sales_register.py index b333901d7b3..291c7d976e4 100644 --- a/erpnext/accounts/report/sales_register/sales_register.py +++ b/erpnext/accounts/report/sales_register/sales_register.py @@ -11,17 +11,18 @@ from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import ( get_accounting_dimensions, get_dimension_with_children, ) +from erpnext.accounts.report.utils import get_query_columns, get_values_for_columns def execute(filters=None): return _execute(filters) -def _execute(filters, additional_table_columns=None, additional_query_columns=None): +def _execute(filters, additional_table_columns=None): if not filters: filters = frappe._dict({}) - invoice_list = get_invoices(filters, additional_query_columns) + invoice_list = get_invoices(filters, get_query_columns(additional_table_columns)) columns, income_accounts, tax_accounts, unrealized_profit_loss_accounts = get_columns( invoice_list, additional_table_columns ) @@ -54,30 +55,22 @@ def _execute(filters, additional_table_columns=None, additional_query_columns=No "posting_date": inv.posting_date, "customer": inv.customer, "customer_name": inv.customer_name, + **get_values_for_columns(additional_table_columns, inv), + "customer_group": inv.get("customer_group"), + "territory": inv.get("territory"), + "tax_id": inv.get("tax_id"), + "receivable_account": inv.debit_to, + "mode_of_payment": ", ".join(mode_of_payments.get(inv.name, [])), + "project": inv.project, + "owner": inv.owner, + "remarks": inv.remarks, + "sales_order": ", ".join(sales_order), + "delivery_note": ", ".join(delivery_note), + "cost_center": ", ".join(cost_center), + "warehouse": ", ".join(warehouse), + "currency": company_currency, } - if additional_query_columns: - for col in additional_query_columns: - row.update({col: inv.get(col)}) - - row.update( - { - "customer_group": inv.get("customer_group"), - "territory": inv.get("territory"), - "tax_id": inv.get("tax_id"), - "receivable_account": inv.debit_to, - "mode_of_payment": ", ".join(mode_of_payments.get(inv.name, [])), - "project": inv.project, - "owner": inv.owner, - "remarks": inv.remarks, - "sales_order": ", ".join(sales_order), - "delivery_note": ", ".join(delivery_note), - "cost_center": ", ".join(cost_center), - "warehouse": ", ".join(warehouse), - "currency": company_currency, - } - ) - # map income values base_net_total = 0 for income_acc in income_accounts: @@ -402,9 +395,6 @@ def get_conditions(filters): def get_invoices(filters, additional_query_columns): - if additional_query_columns: - additional_query_columns = ", " + ", ".join(additional_query_columns) - conditions = get_conditions(filters) return frappe.db.sql( """ @@ -413,10 +403,10 @@ def get_invoices(filters, additional_query_columns): base_net_total, base_grand_total, base_rounded_total, outstanding_amount, is_internal_customer, represents_company, company {0} from `tabSales Invoice` - where docstatus = 1 %s order by posting_date desc, name desc""".format( - additional_query_columns or "" - ) - % conditions, + where docstatus = 1 {1} + order by posting_date desc, name desc""".format( + additional_query_columns, conditions + ), filters, as_dict=1, ) diff --git a/erpnext/accounts/report/utils.py b/erpnext/accounts/report/utils.py index 97cc1c4a130..781481bd0d2 100644 --- a/erpnext/accounts/report/utils.py +++ b/erpnext/accounts/report/utils.py @@ -1,5 +1,5 @@ import frappe -from frappe.utils import flt, formatdate, get_datetime_str +from frappe.utils import flt, formatdate, get_datetime_str, get_table_name from erpnext import get_company_currency, get_default_company from erpnext.accounts.doctype.fiscal_year.fiscal_year import get_from_and_to_date @@ -151,3 +151,32 @@ def get_invoiced_item_gross_margin( result = sum(d.gross_profit for d in result) return result + + +def get_query_columns(report_columns): + if not report_columns: + return "" + + columns = [] + for column in report_columns: + fieldname = column["fieldname"] + + if doctype := column.get("_doctype"): + columns.append(f"`{get_table_name(doctype)}`.`{fieldname}`") + else: + columns.append(fieldname) + + return ", " + ", ".join(columns) + + +def get_values_for_columns(report_columns, report_row): + values = {} + + if not report_columns: + return values + + for column in report_columns: + fieldname = column["fieldname"] + values[fieldname] = report_row.get(fieldname) + + return values From 937e1fb0245af291789ccd88f168d0402d9a00d8 Mon Sep 17 00:00:00 2001 From: Anand Baburajan Date: Tue, 4 Jul 2023 19:06:58 +0530 Subject: [PATCH 14/14] fix: handle loan_repayment's posting_date datetime in bank_clearance_summary report (#36004) --- .../report/bank_clearance_summary/bank_clearance_summary.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/report/bank_clearance_summary/bank_clearance_summary.py b/erpnext/accounts/report/bank_clearance_summary/bank_clearance_summary.py index 2d68bb70b83..cb7445546f1 100644 --- a/erpnext/accounts/report/bank_clearance_summary/bank_clearance_summary.py +++ b/erpnext/accounts/report/bank_clearance_summary/bank_clearance_summary.py @@ -152,5 +152,5 @@ def get_entries(filters): return sorted( journal_entries + payment_entries + loan_disbursements + loan_repayments, - key=lambda k: k[2] or getdate(nowdate()), + key=lambda k: k[2].strftime("%H%M%S") or getdate(nowdate()), )