From 33185e0a3b7ad8197283a5e40c601640b7f02c19 Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Wed, 13 Mar 2024 04:29:12 +0000 Subject: [PATCH 01/12] chore(release): Bumped to Version 15.17.0 # [15.17.0](https://github.com/frappe/erpnext/compare/v15.16.2...v15.17.0) (2024-03-13) ### Bug Fixes * **accounts:** Allow setting Number of new Cost Center (backport [#40212](https://github.com/frappe/erpnext/issues/40212)) ([#40314](https://github.com/frappe/erpnext/issues/40314)) ([7001e0a](https://github.com/frappe/erpnext/commit/7001e0a8208c0d9d03981267e7d8489e8395cab0)) * advance paid amount and ledger entries against SO/PO ([6a5a941](https://github.com/frappe/erpnext/commit/6a5a941a5ac0fa1b7469b46f793aa71cba2c42b7)) * barcode field on line item not working (backport [#40381](https://github.com/frappe/erpnext/issues/40381)) ([#40384](https://github.com/frappe/erpnext/issues/40384)) ([9ce68de](https://github.com/frappe/erpnext/commit/9ce68deff589ce929e4459d86ed18c9d41c2d37f)) * batch no not copied while making Material Consumption entry (backport [#40290](https://github.com/frappe/erpnext/issues/40290)) ([#40300](https://github.com/frappe/erpnext/issues/40300)) ([6d1c144](https://github.com/frappe/erpnext/commit/6d1c144a6682562ee2c03f6df40aa59cb51372b3)) * Blanket order rate getting changed on converting to order ([d8c6eb0](https://github.com/frappe/erpnext/commit/d8c6eb0bf2699947e5301461fda3c8681fca83bf)) * conditionally apply `is_group` filter in accounting dimension query (backport [#40414](https://github.com/frappe/erpnext/issues/40414)) ([#40416](https://github.com/frappe/erpnext/issues/40416)) ([40752c1](https://github.com/frappe/erpnext/commit/40752c1f5cdfc50ccc22a5e322f004b5bacd36fe)) * decimal issue while making the stock entry (backport [#40394](https://github.com/frappe/erpnext/issues/40394)) ([#40397](https://github.com/frappe/erpnext/issues/40397)) ([91af7c0](https://github.com/frappe/erpnext/commit/91af7c033aa3fc69146bd073d6d583e9e5ca50aa)) * error message wording ([#40403](https://github.com/frappe/erpnext/issues/40403)) ([2a40808](https://github.com/frappe/erpnext/commit/2a40808b057a84fc7589b7e910cba0348792cc45)) * Filter for projects in Sales Cycle ([173b3b8](https://github.com/frappe/erpnext/commit/173b3b85f617f37109468a852f116e2e4e88f80a)) * get_user_default_as_list args order ([44ff607](https://github.com/frappe/erpnext/commit/44ff607dcddc96825ff8610b81f3915772261260)) * if input manualy material request on WO the material_request_item is not set so validate WO give error (backport [#40180](https://github.com/frappe/erpnext/issues/40180)) ([#40421](https://github.com/frappe/erpnext/issues/40421)) ([a5e6763](https://github.com/frappe/erpnext/commit/a5e6763be593280bd1b4cfa6de81624532947839)) * incorrect advance paid in Sales/Purchase Order ([6832908](https://github.com/frappe/erpnext/commit/6832908e92048462359e3755f7b5a2b9215de21a)) * incorrect work order status (backport [#40407](https://github.com/frappe/erpnext/issues/40407)) ([#40411](https://github.com/frappe/erpnext/issues/40411)) ([605132a](https://github.com/frappe/erpnext/commit/605132a31c14b624399cbe1f021ca2355abb0020)) * load ignored doctype and include Mode of Payment Account ([#40334](https://github.com/frappe/erpnext/issues/40334)) ([5fac500](https://github.com/frappe/erpnext/commit/5fac50036a10c67efd92fcc31de3e08bbc772347)) * MR Default Supplier search query (backport [#40273](https://github.com/frappe/erpnext/issues/40273)) ([#40351](https://github.com/frappe/erpnext/issues/40351)) ([a195dd3](https://github.com/frappe/erpnext/commit/a195dd3c1f8a49b0d81bfe9248cc1b4d12ac165e)) * negative stock error for the batch (backport [#40389](https://github.com/frappe/erpnext/issues/40389)) ([#40391](https://github.com/frappe/erpnext/issues/40391)) ([478b988](https://github.com/frappe/erpnext/commit/478b9882900bf706811bab5eeb8c5c6d75665231)) * not able to cancel purchase receipt for old subcontracting flow (backport [#40298](https://github.com/frappe/erpnext/issues/40298)) ([#40302](https://github.com/frappe/erpnext/issues/40302)) ([e0e80f7](https://github.com/frappe/erpnext/commit/e0e80f7eedffe8e49248ef0d3e5ae8a1b1c91321)) * qc created for raw materials during manufacture entry (backport [#40408](https://github.com/frappe/erpnext/issues/40408)) ([#40413](https://github.com/frappe/erpnext/issues/40413)) ([f932265](https://github.com/frappe/erpnext/commit/f932265218f766090a6e21c8072e968266f9dd0e)) * recursion issue while submitting work order (backport [#40400](https://github.com/frappe/erpnext/issues/40400)) ([#40402](https://github.com/frappe/erpnext/issues/40402)) ([d6e87f3](https://github.com/frappe/erpnext/commit/d6e87f3f1748e702bf6c7f4600776705dc4a7117)) * Sender email in process statements of accounts ([953f640](https://github.com/frappe/erpnext/commit/953f64091ae1d9ff8f04f704fc0d8cf7bb613333)) * **Shipment Parcel:** make length, width and height non-mandatory ([1476196](https://github.com/frappe/erpnext/commit/14761969660eb8ed1101191748bd94f22051fbfd)) * stock ledger balance qty for the batch (backport [#40274](https://github.com/frappe/erpnext/issues/40274)) ([#40301](https://github.com/frappe/erpnext/issues/40301)) ([62aefce](https://github.com/frappe/erpnext/commit/62aefcef04b2e15ad51e50953a0e8e56b27c39db)) * use serial batch fields for subcontracting receipt (backport [#40311](https://github.com/frappe/erpnext/issues/40311)) ([#40315](https://github.com/frappe/erpnext/issues/40315)) ([4b15c00](https://github.com/frappe/erpnext/commit/4b15c00b11ee9ed2271ef55d72982de436106f34)) * use serial/batch field for rejected items (backport [#40327](https://github.com/frappe/erpnext/issues/40327)) ([#40329](https://github.com/frappe/erpnext/issues/40329)) ([7ca7242](https://github.com/frappe/erpnext/commit/7ca72423b962a80fe7bf3660ed8f9ec4b4a2a60a)) * Use serial/batch fields for delivery note return (backport [#40374](https://github.com/frappe/erpnext/issues/40374)) ([#40376](https://github.com/frappe/erpnext/issues/40376)) ([32660ab](https://github.com/frappe/erpnext/commit/32660abdc849fe5c0409f4be95aac6f969812e63)) ### Features * add recursion qty field in promotional scheme ([5f4b23d](https://github.com/frappe/erpnext/commit/5f4b23d4afedeb76ad239f15212e0469366f2e49)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 4bee7c55e17..f3898d3082a 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -3,7 +3,7 @@ import inspect import frappe -__version__ = "15.16.2" +__version__ = "15.17.0" def get_default_company(user=None): From 18957d7cc4cf11927b0421cff2dcb3103baf7d89 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 11 Mar 2024 14:02:05 +0530 Subject: [PATCH 02/12] refactor: checkbox to toggle always standalone credit note (cherry picked from commit 2cefe2a20eddf96929d4112db1a082645a5beeef) # Conflicts: # erpnext/accounts/doctype/sales_invoice/sales_invoice.json --- .../doctype/sales_invoice/sales_invoice.json | 26 ++++++++++++++++++- .../doctype/sales_invoice/sales_invoice.py | 5 +++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index f2094874e0e..7cb9a4abfa7 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -25,6 +25,7 @@ "is_consolidated", "is_return", "return_against", + "update_outstanding_for_self", "update_billed_amount_in_sales_order", "update_billed_amount_in_delivery_note", "is_debit_note", @@ -2162,6 +2163,25 @@ "fieldname": "update_billed_amount_in_delivery_note", "fieldtype": "Check", "label": "Update Billed Amount in Delivery Note" +<<<<<<< HEAD +======= + }, + { + "default": "0", + "depends_on": "loyalty_program", + "fieldname": "dont_create_loyalty_points", + "fieldtype": "Check", + "label": "Don't Create Loyalty Points", + "no_copy": 1 + }, + { + "default": "1", + "depends_on": "eval: doc.is_return && doc.return_against", + "description": "Credit Note will update it's own outstanding amount, even if \"Return Against\" is specified.", + "fieldname": "update_outstanding_for_self", + "fieldtype": "Check", + "label": "Update Outstanding for Self" +>>>>>>> 2cefe2a20e (refactor: checkbox to toggle always standalone credit note) } ], "icon": "fa fa-file-text", @@ -2174,7 +2194,11 @@ "link_fieldname": "consolidated_invoice" } ], +<<<<<<< HEAD "modified": "2023-11-23 16:56:29.679499", +======= + "modified": "2024-03-11 14:20:34.874192", +>>>>>>> 2cefe2a20e (refactor: checkbox to toggle always standalone credit note) "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice", @@ -2229,4 +2253,4 @@ "title_field": "title", "track_changes": 1, "track_seen": 1 -} \ No newline at end of file +} diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 1343b39352c..8bcfaeeb554 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -220,6 +220,7 @@ class SalesInvoice(SellingController): unrealized_profit_loss_account: DF.Link | None update_billed_amount_in_delivery_note: DF.Check update_billed_amount_in_sales_order: DF.Check + update_outstanding_for_self: DF.Check update_stock: DF.Check use_company_roundoff_cost_center: DF.Check write_off_account: DF.Link | None @@ -1241,7 +1242,9 @@ class SalesInvoice(SellingController): "debit_in_account_currency": base_grand_total if self.party_account_currency == self.company_currency else grand_total, - "against_voucher": self.name, + "against_voucher": self.name + if self.is_return and self.return_against and self.update_outstanding_for_self + else self.return_against, "against_voucher_type": self.doctype, "cost_center": self.cost_center, "project": self.project, From 9ccc22ca6102552703e73bde5f1544d84e5a3bad Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 11 Mar 2024 14:09:51 +0530 Subject: [PATCH 03/12] chore: update popup message (cherry picked from commit adf13a19c468ca39162f9acea47fe5e45a36bd97) # Conflicts: # erpnext/controllers/accounts_controller.py --- erpnext/controllers/accounts_controller.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 301d0e20cc3..033ef1df61d 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -218,15 +218,19 @@ class AccountsController(TransactionBase): ) if self.get("is_return") and self.get("return_against") and not self.get("is_pos"): - # if self.get("is_return") and self.get("return_against"): document_type = "Credit Note" if self.doctype == "Sales Invoice" else "Debit Note" frappe.msgprint( _( - "{0} will be treated as a standalone {0}. Post creation use {1} tool to reconcile against {2}." + "{0} will be treated as a standalone {0}. If you want {1}'s outstanding to be updated, uncheck {2} checkbox.

Or you can use {3} tool to reconcile against {1} later." ).format( document_type, +<<<<<<< HEAD get_link_to_form("Payment Reconciliation", "Payment Reconciliation"), +======= +>>>>>>> adf13a19c4 (chore: update popup message) get_link_to_form(self.doctype, self.get("return_against")), + frappe.bold("Update Outstanding for Self"), + get_link_to_form("Payment Reconciliation"), ) ) From 006971ecc65aa76526d2b39cc15649bce6778c27 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 11 Mar 2024 14:41:36 +0530 Subject: [PATCH 04/12] refactor: checkbox in purchase invoice (cherry picked from commit 767f2157e6f2977b73399f1d77fecb2e87d3471d) --- .../doctype/purchase_invoice/purchase_invoice.json | 11 ++++++++++- .../doctype/purchase_invoice/purchase_invoice.py | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json index 313a314ee26..d6e606f73b5 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json @@ -22,6 +22,7 @@ "is_paid", "is_return", "return_against", + "update_outstanding_for_self", "update_billed_amount_in_purchase_order", "update_billed_amount_in_purchase_receipt", "apply_tds", @@ -1622,13 +1623,21 @@ "fieldtype": "Link", "label": "Supplier Group", "options": "Supplier Group" + }, + { + "default": "1", + "depends_on": "eval: doc.is_return && doc.return_against", + "description": "Debit Note will update it's own outstanding amount, even if \"Return Against\" is specified.", + "fieldname": "update_outstanding_for_self", + "fieldtype": "Check", + "label": "Update Outstanding for Self" } ], "icon": "fa fa-file-text", "idx": 204, "is_submittable": 1, "links": [], - "modified": "2024-02-25 11:20:28.366808", + "modified": "2024-03-11 14:46:30.298184", "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice", diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 18ecd91d728..5b8f7fc7b37 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -216,6 +216,7 @@ class PurchaseInvoice(BuyingController): unrealized_profit_loss_account: DF.Link | None update_billed_amount_in_purchase_order: DF.Check update_billed_amount_in_purchase_receipt: DF.Check + update_outstanding_for_self: DF.Check update_stock: DF.Check use_company_roundoff_cost_center: DF.Check use_transaction_date_exchange_rate: DF.Check From b56fe0e8009f651384c1d352f403d15403dfa7b7 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 11 Mar 2024 14:49:28 +0530 Subject: [PATCH 05/12] refactor: post ledger entries based on toggle (cherry picked from commit 77aac6f5716cf852b1f4781589e6c6c560bf4b43) --- .../accounts/doctype/purchase_invoice/purchase_invoice.py | 6 +++++- erpnext/accounts/doctype/sales_invoice/sales_invoice.py | 8 +++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 5b8f7fc7b37..ee3ec82ea89 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -829,6 +829,10 @@ class PurchaseInvoice(BuyingController): ) if grand_total and not self.is_internal_transfer(): + against_voucher = self.name + if self.is_return and self.return_against and not self.update_outstanding_for_self: + against_voucher = self.return_against + # Did not use base_grand_total to book rounding loss gle gl_entries.append( self.get_gl_dict( @@ -842,7 +846,7 @@ class PurchaseInvoice(BuyingController): "credit_in_account_currency": base_grand_total if self.party_account_currency == self.company_currency else grand_total, - "against_voucher": self.name, + "against_voucher": against_voucher, "against_voucher_type": self.doctype, "project": self.project, "cost_center": self.cost_center, diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 8bcfaeeb554..02a61d1cd9c 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -1229,6 +1229,10 @@ class SalesInvoice(SellingController): ) if grand_total and not self.is_internal_transfer(): + against_voucher = self.name + if self.is_return and self.return_against and not self.update_outstanding_for_self: + against_voucher = self.return_against + # Did not use base_grand_total to book rounding loss gle gl_entries.append( self.get_gl_dict( @@ -1242,9 +1246,7 @@ class SalesInvoice(SellingController): "debit_in_account_currency": base_grand_total if self.party_account_currency == self.company_currency else grand_total, - "against_voucher": self.name - if self.is_return and self.return_against and self.update_outstanding_for_self - else self.return_against, + "against_voucher": against_voucher, "against_voucher_type": self.doctype, "cost_center": self.cost_center, "project": self.project, From 95093ba7cdd2f8a5f5ad9bd6695e3e4436d6e20a Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 12 Mar 2024 16:05:50 +0530 Subject: [PATCH 06/12] chore: patch for updating flag in Cr/Dr notes (cherry picked from commit 849f47889498bb8c6cbf237dad711fbc0475ef93) # Conflicts: # erpnext/patches.txt --- erpnext/patches.txt | 4 ++ .../v14_0/update_flag_for_return_invoices.py | 62 +++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 erpnext/patches/v14_0/update_flag_for_return_invoices.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index d5c0a4e80e4..67d4693fb5a 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -353,7 +353,11 @@ erpnext.patches.v14_0.update_zero_asset_quantity_field execute:frappe.db.set_single_value("Buying Settings", "project_update_frequency", "Each Transaction") erpnext.patches.v14_0.update_total_asset_cost_field erpnext.patches.v14_0.create_accounting_dimensions_in_reconciliation_tool +<<<<<<< HEAD erpnext.patches.v15_0.allow_on_submit_dimensions_for_repostable_doctypes +======= +erpnext.patches.v14_0.update_flag_for_return_invoices +>>>>>>> 849f478894 (chore: patch for updating flag in Cr/Dr notes) # below migration patch should always run last erpnext.patches.v14_0.migrate_gl_to_payment_ledger erpnext.stock.doctype.delivery_note.patches.drop_unused_return_against_index # 2023-12-20 diff --git a/erpnext/patches/v14_0/update_flag_for_return_invoices.py b/erpnext/patches/v14_0/update_flag_for_return_invoices.py new file mode 100644 index 00000000000..feb43beacf8 --- /dev/null +++ b/erpnext/patches/v14_0/update_flag_for_return_invoices.py @@ -0,0 +1,62 @@ +from frappe import qb + + +def execute(): + # Set "update_outstanding_for_self" flag in Credit/Debit Notes + # Fetch Credit/Debit notes that does have 'return_against' but still post ledger entries against themselves. + + gle = qb.DocType("GL Entry") + + # Use hardcoded 'creation' date to isolate Credit/Debit notes created post v14 backport + # https://github.com/frappe/erpnext/pull/39497 + creation_date = "2024-01-25" + + si = qb.DocType("Sales Invoice") + if cr_notes := ( + qb.from_(si) + .select(si.name) + .where( + (si.creation.gte(creation_date)) + & (si.docstatus == 1) + & (si.is_return == True) + & (si.return_against.notnull()) + ) + .run() + ): + cr_notes = [x[0] for x in cr_notes] + if docs_that_require_update := ( + qb.from_(gle) + .select(gle.voucher_no) + .distinct() + .where((gle.voucher_no.isin(cr_notes)) & (gle.voucher_no == gle.against_voucher)) + .run() + ): + docs_that_require_update = [x[0] for x in docs_that_require_update] + qb.update(si).set(si.update_outstanding_for_self, True).where( + si.name.isin(docs_that_require_update) + ).run() + + pi = qb.DocType("Purchase Invoice") + if dr_notes := ( + qb.from_(pi) + .select(pi.name) + .where( + (pi.creation.gte(creation_date)) + & (pi.docstatus == 1) + & (pi.is_return == True) + & (pi.return_against.notnull()) + ) + .run() + ): + dr_notes = [x[0] for x in dr_notes] + if docs_that_require_update := ( + qb.from_(gle) + .select(gle.voucher_no) + .distinct() + .where((gle.voucher_no.isin(dr_notes)) & (gle.voucher_no == gle.against_voucher)) + .run() + ): + docs_that_require_update = [x[0] for x in docs_that_require_update] + qb.update(pi).set(pi.update_outstanding_for_self, True).where( + pi.name.isin(docs_that_require_update) + ).run() From 19763ce54500262f680c1a16347f04c6e8949f55 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Wed, 13 Mar 2024 09:55:23 +0530 Subject: [PATCH 07/12] refactor: make AR/AP report aware of always standalone cr/dr notes (cherry picked from commit 4d0c2d8e8226e4ba093d6d19f975743a1023aaa1) --- .../report/accounts_receivable/accounts_receivable.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py index 92d9755897c..6ed6ca22e63 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py @@ -690,7 +690,12 @@ class ReceivablePayableReport(object): def get_return_entries(self): doctype = "Sales Invoice" if self.account_type == "Receivable" else "Purchase Invoice" - filters = {"is_return": 1, "docstatus": 1, "company": self.filters.company} + filters = { + "is_return": 1, + "docstatus": 1, + "company": self.filters.company, + "update_outstanding_for_self": 0, + } or_filters = {} for party_type in self.party_type: party_field = scrub(party_type) From ed7a115511977adf5d5fe8c8d2e229143a10293c Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Wed, 13 Mar 2024 10:14:21 +0530 Subject: [PATCH 08/12] test: cr note flag to update self (cherry picked from commit ce3b1f09f51f28a8e3733020c70c0e381a2dc8c3) --- .../test_accounts_receivable.py | 69 ++++++++++++++++++- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py index 6ff81be0ab7..a0f8af5d419 100644 --- a/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py @@ -62,7 +62,7 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase): pe.insert() pe.submit() - def create_credit_note(self, docname): + def create_credit_note(self, docname, do_not_submit=False): credit_note = create_sales_invoice( company=self.company, customer=self.customer, @@ -72,6 +72,7 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase): cost_center=self.cost_center, is_return=1, return_against=docname, + do_not_submit=do_not_submit, ) return credit_note @@ -149,7 +150,9 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase): ) # check invoice grand total, invoiced, paid and outstanding column's value after credit note - self.create_credit_note(si.name) + cr_note = self.create_credit_note(si.name, do_not_submit=True) + cr_note.update_outstanding_for_self = False + cr_note.save().submit() report = execute(filters) expected_data_after_credit_note = [100, 0, 0, 40, -40, self.debit_to] @@ -167,6 +170,68 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase): ], ) + def test_cr_note_flag_to_update_self(self): + filters = { + "company": self.company, + "report_date": today(), + "range1": 30, + "range2": 60, + "range3": 90, + "range4": 120, + "show_remarks": True, + } + + # check invoice grand total and invoiced column's value for 3 payment terms + si = self.create_sales_invoice(no_payment_schedule=True) + name = si.name + + report = execute(filters) + + expected_data = [100, 100, "No Remarks"] + + self.assertEqual(len(report[1]), 1) + row = report[1][0] + self.assertEqual(expected_data, [row.invoice_grand_total, row.invoiced, row.remarks]) + + # check invoice grand total, invoiced, paid and outstanding column's value after payment + self.create_payment_entry(si.name) + report = execute(filters) + + expected_data_after_payment = [100, 100, 40, 60] + self.assertEqual(len(report[1]), 1) + row = report[1][0] + self.assertEqual( + expected_data_after_payment, + [row.invoice_grand_total, row.invoiced, row.paid, row.outstanding], + ) + + # check invoice grand total, invoiced, paid and outstanding column's value after credit note + cr_note = self.create_credit_note(si.name, do_not_submit=True) + cr_note.posting_date = add_days(today(), 1) + cr_note.update_outstanding_for_self = True + cr_note.save().submit() + report = execute(filters) + + expected_data_after_credit_note = [ + [100.0, 100.0, 40.0, 0.0, 60.0, self.debit_to], + [0, 0, 100.0, 0.0, -100.0, self.debit_to], + ] + self.assertEqual(len(report[1]), 2) + for i in range(2): + row = report[1][i - 1] + # row = report[1][0] + self.assertEqual( + expected_data_after_credit_note[i - 1], + [ + row.invoice_grand_total, + row.invoiced, + row.paid, + row.credit_note, + row.outstanding, + row.party_account, + ], + ) + def test_payment_againt_po_in_receivable_report(self): """ Payments made against Purchase Order will show up as outstanding amount From e07f9e6754a5b3744585026cdb4e1503682225a5 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Wed, 13 Mar 2024 11:03:56 +0530 Subject: [PATCH 09/12] chore: better popup message (cherry picked from commit 445d2acf5071f2376bee992b5eb6aff71910f562) # Conflicts: # erpnext/controllers/accounts_controller.py --- erpnext/controllers/accounts_controller.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 033ef1df61d..ea529005051 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -218,6 +218,7 @@ class AccountsController(TransactionBase): ) if self.get("is_return") and self.get("return_against") and not self.get("is_pos"): +<<<<<<< HEAD document_type = "Credit Note" if self.doctype == "Sales Invoice" else "Debit Note" frappe.msgprint( _( @@ -231,8 +232,20 @@ class AccountsController(TransactionBase): get_link_to_form(self.doctype, self.get("return_against")), frappe.bold("Update Outstanding for Self"), get_link_to_form("Payment Reconciliation"), +======= + if self.get("update_outstanding_for_self"): + document_type = "Credit Note" if self.doctype == "Sales Invoice" else "Debit Note" + frappe.msgprint( + _( + "We can see {0} is made against {1}. If you want {1}'s outstanding to be updated, uncheck '{2}' checkbox.

Or you can use {3} tool to reconcile against {1} later." + ).format( + frappe.bold(document_type), + get_link_to_form(self.doctype, self.get("return_against")), + frappe.bold("Update Outstanding for Self"), + get_link_to_form("Payment Reconciliation"), + ) +>>>>>>> 445d2acf50 (chore: better popup message) ) - ) pos_check_field = "is_pos" if self.doctype == "Sales Invoice" else "is_paid" if cint(self.allocate_advances_automatically) and not cint(self.get(pos_check_field)): From 9ffb4c5ca9f1564a1004a4f8f74eb9b7f5fc3b55 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Wed, 13 Mar 2024 17:53:02 +0530 Subject: [PATCH 10/12] chore: resolve conflicts --- .../doctype/sales_invoice/sales_invoice.json | 15 --------------- erpnext/controllers/accounts_controller.py | 18 +----------------- erpnext/patches.txt | 3 --- 3 files changed, 1 insertion(+), 35 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index 7cb9a4abfa7..8fd897bddf1 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -2163,16 +2163,6 @@ "fieldname": "update_billed_amount_in_delivery_note", "fieldtype": "Check", "label": "Update Billed Amount in Delivery Note" -<<<<<<< HEAD -======= - }, - { - "default": "0", - "depends_on": "loyalty_program", - "fieldname": "dont_create_loyalty_points", - "fieldtype": "Check", - "label": "Don't Create Loyalty Points", - "no_copy": 1 }, { "default": "1", @@ -2181,7 +2171,6 @@ "fieldname": "update_outstanding_for_self", "fieldtype": "Check", "label": "Update Outstanding for Self" ->>>>>>> 2cefe2a20e (refactor: checkbox to toggle always standalone credit note) } ], "icon": "fa fa-file-text", @@ -2194,11 +2183,7 @@ "link_fieldname": "consolidated_invoice" } ], -<<<<<<< HEAD - "modified": "2023-11-23 16:56:29.679499", -======= "modified": "2024-03-11 14:20:34.874192", ->>>>>>> 2cefe2a20e (refactor: checkbox to toggle always standalone credit note) "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice", diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index ea529005051..fe3c5d7a836 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -218,21 +218,6 @@ class AccountsController(TransactionBase): ) if self.get("is_return") and self.get("return_against") and not self.get("is_pos"): -<<<<<<< HEAD - document_type = "Credit Note" if self.doctype == "Sales Invoice" else "Debit Note" - frappe.msgprint( - _( - "{0} will be treated as a standalone {0}. If you want {1}'s outstanding to be updated, uncheck {2} checkbox.

Or you can use {3} tool to reconcile against {1} later." - ).format( - document_type, -<<<<<<< HEAD - get_link_to_form("Payment Reconciliation", "Payment Reconciliation"), -======= ->>>>>>> adf13a19c4 (chore: update popup message) - get_link_to_form(self.doctype, self.get("return_against")), - frappe.bold("Update Outstanding for Self"), - get_link_to_form("Payment Reconciliation"), -======= if self.get("update_outstanding_for_self"): document_type = "Credit Note" if self.doctype == "Sales Invoice" else "Debit Note" frappe.msgprint( @@ -242,9 +227,8 @@ class AccountsController(TransactionBase): frappe.bold(document_type), get_link_to_form(self.doctype, self.get("return_against")), frappe.bold("Update Outstanding for Self"), - get_link_to_form("Payment Reconciliation"), + get_link_to_form("Payment Reconciliation", "Payment Reconciliation"), ) ->>>>>>> 445d2acf50 (chore: better popup message) ) pos_check_field = "is_pos" if self.doctype == "Sales Invoice" else "is_paid" diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 67d4693fb5a..c024c86c5e5 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -353,11 +353,8 @@ erpnext.patches.v14_0.update_zero_asset_quantity_field execute:frappe.db.set_single_value("Buying Settings", "project_update_frequency", "Each Transaction") erpnext.patches.v14_0.update_total_asset_cost_field erpnext.patches.v14_0.create_accounting_dimensions_in_reconciliation_tool -<<<<<<< HEAD erpnext.patches.v15_0.allow_on_submit_dimensions_for_repostable_doctypes -======= erpnext.patches.v14_0.update_flag_for_return_invoices ->>>>>>> 849f478894 (chore: patch for updating flag in Cr/Dr notes) # below migration patch should always run last erpnext.patches.v14_0.migrate_gl_to_payment_ledger erpnext.stock.doctype.delivery_note.patches.drop_unused_return_against_index # 2023-12-20 From 057e43330fe1b24bd8ed8de8251f8844972325f1 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Thu, 14 Mar 2024 13:19:45 +0530 Subject: [PATCH 11/12] fix(test): manually filter row and assert --- .../test_accounts_receivable.py | 52 ++++++++++++------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py index a0f8af5d419..de49139adc1 100644 --- a/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py @@ -182,8 +182,10 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase): } # check invoice grand total and invoiced column's value for 3 payment terms - si = self.create_sales_invoice(no_payment_schedule=True) - name = si.name + si = self.create_sales_invoice(no_payment_schedule=True, do_not_submit=True) + si.set_posting_time = True + si.posting_date = add_days(today(), -1) + si.save().submit() report = execute(filters) @@ -207,30 +209,42 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase): # check invoice grand total, invoiced, paid and outstanding column's value after credit note cr_note = self.create_credit_note(si.name, do_not_submit=True) - cr_note.posting_date = add_days(today(), 1) cr_note.update_outstanding_for_self = True cr_note.save().submit() report = execute(filters) expected_data_after_credit_note = [ - [100.0, 100.0, 40.0, 0.0, 60.0, self.debit_to], - [0, 0, 100.0, 0.0, -100.0, self.debit_to], + [100.0, 100.0, 40.0, 0.0, 60.0, si.name], + [0, 0, 100.0, 0.0, -100.0, cr_note.name], ] self.assertEqual(len(report[1]), 2) - for i in range(2): - row = report[1][i - 1] - # row = report[1][0] - self.assertEqual( - expected_data_after_credit_note[i - 1], - [ - row.invoice_grand_total, - row.invoiced, - row.paid, - row.credit_note, - row.outstanding, - row.party_account, - ], - ) + si_row = [ + [ + row.invoice_grand_total, + row.invoiced, + row.paid, + row.credit_note, + row.outstanding, + row.voucher_no, + ] + for row in report[1] + if row.voucher_no == si.name + ][0] + + cr_note_row = [ + [ + row.invoice_grand_total, + row.invoiced, + row.paid, + row.credit_note, + row.outstanding, + row.voucher_no, + ] + for row in report[1] + if row.voucher_no == cr_note.name + ][0] + self.assertEqual(expected_data_after_credit_note[0], si_row) + self.assertEqual(expected_data_after_credit_note[1], cr_note_row) def test_payment_againt_po_in_receivable_report(self): """ From 436e03096160f84ddaf2c9641a9d120214f1f87b Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Thu, 14 Mar 2024 09:17:23 +0000 Subject: [PATCH 12/12] chore(release): Bumped to Version 15.17.1 ## [15.17.1](https://github.com/frappe/erpnext/compare/v15.17.0...v15.17.1) (2024-03-14) ### Bug Fixes * **test:** manually filter row and assert ([057e433](https://github.com/frappe/erpnext/commit/057e43330fe1b24bd8ed8de8251f8844972325f1)) --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index f3898d3082a..0ca6ab7ad47 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -3,7 +3,7 @@ import inspect import frappe -__version__ = "15.17.0" +__version__ = "15.17.1" def get_default_company(user=None):