From 500deff3e9e695d6cc80320d8bce4fad0739a91d Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 3 Jan 2025 13:19:34 +0100 Subject: [PATCH 01/32] feat: validate discount date in payment schedule (backport #44646) (#44727) Co-authored-by: barredterra <14891507+barredterra@users.noreply.github.com> --- erpnext/controllers/accounts_controller.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index f9c875477b9..19df2d0489c 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -2353,6 +2353,7 @@ class AccountsController(TransactionBase): return for d in self.get("payment_schedule"): + d.validate_from_to_dates("discount_date", "due_date") if self.doctype == "Sales Order" and getdate(d.due_date) < getdate(self.transaction_date): frappe.throw( _("Row {0}: Due Date in the Payment Terms table cannot be before Posting Date").format( From 03b06fc3ff1ab13956f53841c0f7b601a3703a57 Mon Sep 17 00:00:00 2001 From: Sanket322 Date: Mon, 30 Dec 2024 17:56:17 +0530 Subject: [PATCH 02/32] fix: add monthly distributation and write query in qb (cherry picked from commit 27195c7c9640b06eb548a8505dd6f83e623d552d) --- erpnext/accounts/doctype/budget/budget.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/erpnext/accounts/doctype/budget/budget.py b/erpnext/accounts/doctype/budget/budget.py index 145480138d6..fa711e2edbf 100644 --- a/erpnext/accounts/doctype/budget/budget.py +++ b/erpnext/accounts/doctype/budget/budget.py @@ -490,13 +490,19 @@ def get_actual_expense(args): def get_accumulated_monthly_budget(monthly_distribution, posting_date, fiscal_year, annual_budget): distribution = {} if monthly_distribution: - for d in frappe.db.sql( - """select mdp.month, mdp.percentage_allocation - from `tabMonthly Distribution Percentage` mdp, `tabMonthly Distribution` md - where mdp.parent=md.name and md.fiscal_year=%s""", - fiscal_year, - as_dict=1, - ): + mdp = frappe.qb.DocType("Monthly Distribution Percentage") + md = frappe.qb.DocType("Monthly Distribution") + + query = ( + frappe.qb.from_(mdp) + .join(md) + .on(mdp.parent == md.name) + .select(mdp.month, mdp.percentage_allocation) + .where(md.fiscal_year == fiscal_year) + .where(md.name == monthly_distribution) + ) + + for d in query.run(as_dict=True): distribution.setdefault(d.month, d.percentage_allocation) dt = frappe.get_cached_value("Fiscal Year", fiscal_year, "year_start_date") From 2e67a3341228207bcdde6132d9faecbf77661674 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 31 Dec 2024 17:04:37 +0530 Subject: [PATCH 03/32] refactor: store result in variable before enumeration helps to inspect result while debugging (cherry picked from commit b60bd17d1ddc9cc61d9fba44eb495bec174d66b2) --- erpnext/accounts/doctype/budget/budget.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/budget/budget.py b/erpnext/accounts/doctype/budget/budget.py index fa711e2edbf..2f2b549cf46 100644 --- a/erpnext/accounts/doctype/budget/budget.py +++ b/erpnext/accounts/doctype/budget/budget.py @@ -493,16 +493,17 @@ def get_accumulated_monthly_budget(monthly_distribution, posting_date, fiscal_ye mdp = frappe.qb.DocType("Monthly Distribution Percentage") md = frappe.qb.DocType("Monthly Distribution") - query = ( + res = ( frappe.qb.from_(mdp) .join(md) .on(mdp.parent == md.name) .select(mdp.month, mdp.percentage_allocation) .where(md.fiscal_year == fiscal_year) .where(md.name == monthly_distribution) + .run(as_dict=True) ) - for d in query.run(as_dict=True): + for d in res: distribution.setdefault(d.month, d.percentage_allocation) dt = frappe.get_cached_value("Fiscal Year", fiscal_year, "year_start_date") From cfa062df861481f0ef8d4d97bee85192c69fdadc Mon Sep 17 00:00:00 2001 From: Joseph Mania <60258622+maniamartial@users.noreply.github.com> Date: Sat, 4 Jan 2025 02:53:41 +0300 Subject: [PATCH 04/32] refactor: phone number field when channel is phone on Payment Request (#44949) Co-authored-by: maniamartial --- .../doctype/payment_request/payment_request.json | 16 ++++++++++++++-- .../doctype/payment_request/payment_request.py | 2 ++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/payment_request/payment_request.json b/erpnext/accounts/doctype/payment_request/payment_request.json index 2eef429cd3a..5a19a080484 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.json +++ b/erpnext/accounts/doctype/payment_request/payment_request.json @@ -58,7 +58,9 @@ "payment_account", "payment_channel", "payment_order", - "amended_from" + "amended_from", + "column_break_iiuv", + "phone_number" ], "fields": [ { @@ -376,6 +378,7 @@ "read_only": 1 }, { + "depends_on": "eval: doc.payment_channel==\"Phone\"", "fetch_from": "payment_gateway_account.payment_channel", "fieldname": "payment_channel", "fieldtype": "Select", @@ -429,13 +432,22 @@ "fieldtype": "Data", "label": "Party Name", "read_only": 1 + }, + { + "fieldname": "column_break_iiuv", + "fieldtype": "Column Break" + }, + { + "fieldname": "phone_number", + "fieldtype": "Data", + "label": "Phone Number" } ], "in_create": 1, "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2024-10-23 12:23:40.117336", + "modified": "2024-12-27 21:29:10.361894", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Request", diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py index 61bb2932d2b..f84f094e464 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.py +++ b/erpnext/accounts/doctype/payment_request/payment_request.py @@ -224,6 +224,7 @@ class PaymentRequest(Document): sender=self.email_to, currency=self.currency, payment_gateway=self.payment_gateway, + phone_number=self.phone_number, ) controller.validate_transaction_currency(self.currency) @@ -635,6 +636,7 @@ def make_payment_request(**args): "party": args.get("party") or ref_doc.get("customer"), "bank_account": bank_account, "party_name": args.get("party_name") or ref_doc.get("customer_name"), + "phone_number": args.get("phone_number") if args.get("phone_number") else None, } ) From c924feb0d0ad206423fc959b83ce4aa948ece592 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Sat, 4 Jan 2025 12:58:07 +0530 Subject: [PATCH 05/32] fix: consider expired batches in stock reco (cherry picked from commit f51c9f578c04965a856de9da78e0a24cf33620f0) --- .../stock/doctype/stock_reconciliation/stock_reconciliation.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py index 12773a5555d..9e23270ca71 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -1093,6 +1093,7 @@ class StockReconciliation(StockController): posting_date=doc.posting_date, posting_time=doc.posting_time, ignore_voucher_nos=[doc.voucher_no], + for_stock_levels=True, ) or 0 ) * -1 From 9daabfca8a3dc4d940d02bf218cfd02605dbde0f Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Sat, 4 Jan 2025 19:59:19 +0530 Subject: [PATCH 06/32] fix: invoice against purchase receipt with returned quantity (cherry picked from commit d5babf4237661a11787db69e41001d6099e785c2) # Conflicts: # erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py --- .../purchase_invoice/test_purchase_invoice.py | 49 +++++++++++++++++++ .../purchase_receipt/purchase_receipt.py | 3 ++ 2 files changed, 52 insertions(+) diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index 76fbfd2f4e2..b07dbc3bcbf 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -2494,6 +2494,55 @@ class TestPurchaseInvoice(FrappeTestCase, StockTestMixin): self.assertEqual(len(actual), 3) self.assertEqual(expected, actual) +<<<<<<< HEAD +======= + def test_last_purchase_rate(self): + item = create_item("_Test Item For Last Purchase Rate from PI", is_stock_item=1) + pi1 = make_purchase_invoice(item_code=item.item_code, qty=10, rate=100) + item.reload() + self.assertEqual(item.last_purchase_rate, 100) + + pi2 = make_purchase_invoice(item_code=item.item_code, qty=10, rate=200) + item.reload() + self.assertEqual(item.last_purchase_rate, 200) + + pi2.cancel() + item.reload() + self.assertEqual(item.last_purchase_rate, 100) + + pi1.cancel() + item.reload() + self.assertEqual(item.last_purchase_rate, 0) + + def test_invoice_against_returned_pr(self): + from erpnext.stock.doctype.item.test_item import make_item + from erpnext.stock.doctype.purchase_receipt.purchase_receipt import ( + make_purchase_invoice as make_purchase_invoice_from_pr, + ) + from erpnext.stock.doctype.purchase_receipt.purchase_receipt import ( + make_purchase_return_against_rejected_warehouse, + ) + + item = make_item("_Test Item For Invoice Against Returned PR", properties={"is_stock_item": 1}).name + + original_value = frappe.db.get_single_value( + "Buying Settings", "bill_for_rejected_quantity_in_purchase_invoice" + ) + frappe.db.set_single_value("Buying Settings", "bill_for_rejected_quantity_in_purchase_invoice", 0) + + pr = make_purchase_receipt(item_code=item, qty=5, rejected_qty=5, rate=100) + pr_return = make_purchase_return_against_rejected_warehouse(pr.name) + pr_return.submit() + + pi = make_purchase_invoice_from_pr(pr.name) + pi.save() + self.assertEqual(pi.items[0].qty, 5.0) + + frappe.db.set_single_value( + "Buying Settings", "bill_for_rejected_quantity_in_purchase_invoice", original_value + ) + +>>>>>>> d5babf4237 (fix: invoice against purchase receipt with returned quantity) def set_advance_flag(company, flag, default_account): frappe.db.set_value( diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index 22d7012cc8b..44e0145ea6c 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -1183,6 +1183,9 @@ def make_purchase_invoice(source_name, target_doc=None, args=None): return pending_qty, 0 returned_qty = flt(returned_qty_map.get(item_row.name, 0)) + if item_row.rejected_qty and returned_qty: + returned_qty -= item_row.rejected_qty + if returned_qty: if returned_qty >= pending_qty: pending_qty = 0 From 90b8860a40804a650c07ded8752eeeac7c89e7c4 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Sun, 5 Jan 2025 16:24:15 +0530 Subject: [PATCH 07/32] chore: fix conflicts --- .../purchase_invoice/test_purchase_invoice.py | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index b07dbc3bcbf..4d62c0d354d 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -2494,26 +2494,6 @@ class TestPurchaseInvoice(FrappeTestCase, StockTestMixin): self.assertEqual(len(actual), 3) self.assertEqual(expected, actual) -<<<<<<< HEAD -======= - def test_last_purchase_rate(self): - item = create_item("_Test Item For Last Purchase Rate from PI", is_stock_item=1) - pi1 = make_purchase_invoice(item_code=item.item_code, qty=10, rate=100) - item.reload() - self.assertEqual(item.last_purchase_rate, 100) - - pi2 = make_purchase_invoice(item_code=item.item_code, qty=10, rate=200) - item.reload() - self.assertEqual(item.last_purchase_rate, 200) - - pi2.cancel() - item.reload() - self.assertEqual(item.last_purchase_rate, 100) - - pi1.cancel() - item.reload() - self.assertEqual(item.last_purchase_rate, 0) - def test_invoice_against_returned_pr(self): from erpnext.stock.doctype.item.test_item import make_item from erpnext.stock.doctype.purchase_receipt.purchase_receipt import ( @@ -2542,7 +2522,6 @@ class TestPurchaseInvoice(FrappeTestCase, StockTestMixin): "Buying Settings", "bill_for_rejected_quantity_in_purchase_invoice", original_value ) ->>>>>>> d5babf4237 (fix: invoice against purchase receipt with returned quantity) def set_advance_flag(company, flag, default_account): frappe.db.set_value( From 8874f4a9e44ea249a11c9c2b7ca55c06a7602ef1 Mon Sep 17 00:00:00 2001 From: venkat102 Date: Thu, 2 Jan 2025 16:10:12 +0530 Subject: [PATCH 08/32] fix: ignore currency validation while canceling the voucher (cherry picked from commit 15d488b9aa97cf91aa7ac97b1870e4f5cd49acc8) --- erpnext/accounts/doctype/gl_entry/gl_entry.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py index d9d7807a561..c77a201ab51 100644 --- a/erpnext/accounts/doctype/gl_entry/gl_entry.py +++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py @@ -275,6 +275,9 @@ class GLEntry(Document): validate_account_party_type(self) def validate_currency(self): + if self.is_cancelled: + return + company_currency = erpnext.get_company_currency(self.company) account_currency = get_account_currency(self.account) From 0f1c6ff1c9ca7e6a573b94ccc21789b3616951bb Mon Sep 17 00:00:00 2001 From: venkat102 Date: Thu, 2 Jan 2025 17:27:34 +0530 Subject: [PATCH 09/32] fix: ignore party account validation while canceling the voucher (cherry picked from commit 49885f8eae8c95e1b319c4e48ca64005ffa5b93d) --- erpnext/accounts/party.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py index 3033b8ad087..396c814dff6 100644 --- a/erpnext/accounts/party.py +++ b/erpnext/accounts/party.py @@ -760,6 +760,9 @@ def validate_party_frozen_disabled(party_type, party_name): def validate_account_party_type(self): + if self.is_cancelled: + return + if self.party_type and self.party: account_type = frappe.get_cached_value("Account", self.account, "account_type") if account_type and (account_type not in ["Receivable", "Payable"]): From 9ecafdc6807846be6d739cfedbe9401765d1b5a4 Mon Sep 17 00:00:00 2001 From: mahsem <137205921+mahsem@users.noreply.github.com> Date: Sun, 29 Dec 2024 14:15:52 +0100 Subject: [PATCH 10/32] fix: Hold_to_On_Hold (cherry picked from commit 92b1f314ef12686ab17639fd9d4c83877b898a83) --- erpnext/support/web_form/issues/issues.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/support/web_form/issues/issues.json b/erpnext/support/web_form/issues/issues.json index f3834c73a7c..c8a374ecc5b 100644 --- a/erpnext/support/web_form/issues/issues.json +++ b/erpnext/support/web_form/issues/issues.json @@ -54,7 +54,7 @@ "label": "Status", "max_length": 0, "max_value": 0, - "options": "Open\nReplied\nHold\nClosed", + "options": "Open\nReplied\nOn Hold\nClosed", "read_only": 1, "reqd": 0, "show_in_filter": 1 From 622bfa6633cf9b9ac7423811d04e42249b96d30a Mon Sep 17 00:00:00 2001 From: creative-paramu Date: Fri, 27 Dec 2024 17:54:20 +0530 Subject: [PATCH 11/32] fix: Bank Reconciliation Statement Report Company Filter (cherry picked from commit 50c92034ba2267562ed7f5fdb312ddb57155c96d) --- .../bank_reconciliation_statement.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.py b/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.py index c7dba16492e..bfc2f2d56ff 100644 --- a/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.py +++ b/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.py @@ -142,7 +142,8 @@ def get_journal_entries(filters): where jvd.parent = jv.name and jv.docstatus=1 and jvd.account = %(account)s and jv.posting_date <= %(report_date)s and ifnull(jv.clearance_date, '4000-01-01') > %(report_date)s - and ifnull(jv.is_opening, 'No') = 'No'""", + and ifnull(jv.is_opening, 'No') = 'No' + and jv.company = %(company)s """, filters, as_dict=1, ) @@ -163,6 +164,7 @@ def get_payment_entries(filters): (paid_from=%(account)s or paid_to=%(account)s) and docstatus=1 and posting_date <= %(report_date)s and ifnull(clearance_date, '4000-01-01') > %(report_date)s + and company = %(company)s """, filters, as_dict=1, @@ -181,6 +183,7 @@ def get_pos_entries(filters): sip.account=%(account)s and si.docstatus=1 and sip.parent = si.name and account.name = sip.account and si.posting_date <= %(report_date)s and ifnull(sip.clearance_date, '4000-01-01') > %(report_date)s + and si.company = %(company)s order by si.posting_date ASC, si.name DESC """, From 3194807a41212c18d2b1578ad91143c54ba5b415 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Sat, 4 Jan 2025 17:22:16 +0530 Subject: [PATCH 12/32] fix: Alternative Items button in Work Order (cherry picked from commit e28382afc1c7799918de79a5806b0cacea37ef5c) --- .../doctype/work_order/work_order.js | 54 +++++++++++-------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/erpnext/manufacturing/doctype/work_order/work_order.js b/erpnext/manufacturing/doctype/work_order/work_order.js index df72b1e6b51..fe4768955ec 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order.js +++ b/erpnext/manufacturing/doctype/work_order/work_order.js @@ -1,6 +1,12 @@ // Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors // For license information, please see license.txt +frappe.ui.form.on("Work Order Item", { + allow_alternative_item(frm, cdt, cdn) { + frm.trigger("allow_alternative_item"); + }, +}); + frappe.ui.form.on("Work Order", { setup: function (frm) { frm.custom_make_buttons = { @@ -130,6 +136,32 @@ frappe.ui.form.on("Work Order", { ); }, + allow_alternative_item: function (frm) { + let has_alternative = false; + if (frm.doc.required_items) { + has_alternative = frm.doc.required_items.find((i) => i.allow_alternative_item === 1); + } + + if (frm.doc.allow_alternative_item && frm.doc.docstatus == 0 && has_alternative) { + frm.add_custom_button(__("Alternate Item"), () => { + erpnext.utils.select_alternate_items({ + frm: frm, + child_docname: "required_items", + warehouse_field: "source_warehouse", + child_doctype: "Work Order Item", + original_item_field: "original_item", + condition: (d) => { + if (d.allow_alternative_item) { + return true; + } + }, + }); + }); + } else { + frm.remove_custom_button(__("Alternate Item")); + } + }, + refresh: function (frm) { erpnext.toggle_naming_series(); erpnext.work_order.set_custom_buttons(frm); @@ -163,26 +195,6 @@ frappe.ui.form.on("Work Order", { } } - if (frm.doc.required_items && frm.doc.allow_alternative_item) { - const has_alternative = frm.doc.required_items.find((i) => i.allow_alternative_item === 1); - if (frm.doc.docstatus == 0 && has_alternative) { - frm.add_custom_button(__("Alternate Item"), () => { - erpnext.utils.select_alternate_items({ - frm: frm, - child_docname: "required_items", - warehouse_field: "source_warehouse", - child_doctype: "Work Order Item", - original_item_field: "original_item", - condition: (d) => { - if (d.allow_alternative_item) { - return true; - } - }, - }); - }); - } - } - if (frm.doc.status == "Completed") { if (frm.doc.__onload.backflush_raw_materials_based_on == "Material Transferred for Manufacture") { frm.add_custom_button( @@ -618,7 +630,7 @@ erpnext.work_order = { set_custom_buttons: function (frm) { var doc = frm.doc; - if (doc.status !== "Closed") { + if (doc.docstatus === 1 && doc.status !== "Closed") { frm.add_custom_button( __("Close"), function () { From 642b89782d5d1a2d53c12ed192e2e3dd62e65365 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Mon, 6 Jan 2025 11:22:06 +0530 Subject: [PATCH 13/32] fix: Alternative Item button dissapearing on Save event (cherry picked from commit b8838bd9b9845aa14b6cd756b1238ab6646bb3bd) --- .../manufacturing/doctype/work_order/work_order.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/erpnext/manufacturing/doctype/work_order/work_order.js b/erpnext/manufacturing/doctype/work_order/work_order.js index fe4768955ec..6da3d803358 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order.js +++ b/erpnext/manufacturing/doctype/work_order/work_order.js @@ -1,12 +1,6 @@ // Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors // For license information, please see license.txt -frappe.ui.form.on("Work Order Item", { - allow_alternative_item(frm, cdt, cdn) { - frm.trigger("allow_alternative_item"); - }, -}); - frappe.ui.form.on("Work Order", { setup: function (frm) { frm.custom_make_buttons = { @@ -142,7 +136,7 @@ frappe.ui.form.on("Work Order", { has_alternative = frm.doc.required_items.find((i) => i.allow_alternative_item === 1); } - if (frm.doc.allow_alternative_item && frm.doc.docstatus == 0 && has_alternative) { + if (frm.doc.allow_alternative_item && frm.doc.docstatus === 0 && has_alternative) { frm.add_custom_button(__("Alternate Item"), () => { erpnext.utils.select_alternate_items({ frm: frm, @@ -222,6 +216,7 @@ frappe.ui.form.on("Work Order", { } frm.trigger("add_custom_button_to_return_components"); + frm.trigger("allow_alternative_item"); }, add_custom_button_to_return_components: function (frm) { @@ -552,6 +547,9 @@ frappe.ui.form.on("Work Order", { }); frappe.ui.form.on("Work Order Item", { + allow_alternative_item(frm) { + frm.trigger("allow_alternative_item"); + }, source_warehouse: function (frm, cdt, cdn) { var row = locals[cdt][cdn]; if (!row.item_code) { From 89155f529e757296ad4ff97dee6fe54b3a090cb4 Mon Sep 17 00:00:00 2001 From: sokumon Date: Mon, 6 Jan 2025 12:26:06 +0530 Subject: [PATCH 14/32] fix: show new button in coa if create access (cherry picked from commit 3125bc8a16cff321cbaa9516cb3076fc61b581ca) --- .../accounts/doctype/account/account_tree.js | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/erpnext/accounts/doctype/account/account_tree.js b/erpnext/accounts/doctype/account/account_tree.js index 49d5396c0f3..a61fcb4f530 100644 --- a/erpnext/accounts/doctype/account/account_tree.js +++ b/erpnext/accounts/doctype/account/account_tree.js @@ -237,19 +237,22 @@ frappe.treeview_settings["Account"] = { }, post_render: function (treeview) { frappe.treeview_settings["Account"].treeview["tree"] = treeview.tree; - treeview.page.set_primary_action( - __("New"), - function () { - let root_company = treeview.page.fields_dict.root_company.get_value(); - - if (root_company) { - frappe.throw(__("Please add the account to root level Company - {0}"), [root_company]); - } else { - treeview.new_node(); - } - }, - "add" - ); + if (treeview.can_create) { + treeview.page.set_primary_action( + __("New"), + function () { + let root_company = treeview.page.fields_dict.root_company.get_value(); + if (root_company) { + frappe.throw(__("Please add the account to root level Company - {0}"), [ + root_company, + ]); + } else { + treeview.new_node(); + } + }, + "add" + ); + } }, toolbar: [ { From 452dffab48cedcf44949caaf2036084196b6522e Mon Sep 17 00:00:00 2001 From: diptanilsaha Date: Tue, 31 Dec 2024 13:22:18 +0530 Subject: [PATCH 15/32] fix: load price list rate for pos search term (cherry picked from commit 4b6cae156e2ece905158eaa649a9812d92bc87dd) --- .../selling/page/point_of_sale/point_of_sale.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.py b/erpnext/selling/page/point_of_sale/point_of_sale.py index 206e51bbc5a..f00b7d0fc55 100644 --- a/erpnext/selling/page/point_of_sale/point_of_sale.py +++ b/erpnext/selling/page/point_of_sale/point_of_sale.py @@ -58,13 +58,17 @@ def search_by_term(search_term, warehouse, price_list): item_stock_qty = item_stock_qty // item.get("conversion_factor", 1) item.update({"actual_qty": item_stock_qty}) + price_filters = { + "price_list": price_list, + "item_code": item_code, + } + + if batch_no: + price_filters["batch_no"] = batch_no + price = frappe.get_list( doctype="Item Price", - filters={ - "price_list": price_list, - "item_code": item_code, - "batch_no": batch_no, - }, + filters=price_filters, fields=["uom", "currency", "price_list_rate", "batch_no"], ) From 59af144e298dbdb0ae5dbd4281bc0b2a1e9f615b Mon Sep 17 00:00:00 2001 From: diptanilsaha Date: Tue, 31 Dec 2024 14:55:01 +0530 Subject: [PATCH 16/32] fix: load search term price with customer default price list (cherry picked from commit 2beb485d7753e8b0cf399cf9025ea349a5857a3e) --- erpnext/selling/page/point_of_sale/pos_item_selector.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/erpnext/selling/page/point_of_sale/pos_item_selector.js b/erpnext/selling/page/point_of_sale/pos_item_selector.js index 9882c2d201e..909d1bb9c2d 100644 --- a/erpnext/selling/page/point_of_sale/pos_item_selector.js +++ b/erpnext/selling/page/point_of_sale/pos_item_selector.js @@ -328,13 +328,16 @@ erpnext.PointOfSale.ItemSelector = class { } filter_items({ search_term = "" } = {}) { + const selling_price_list = this.events.get_frm().doc.selling_price_list; + if (search_term) { search_term = search_term.toLowerCase(); // memoize this.search_index = this.search_index || {}; - if (this.search_index[search_term]) { - const items = this.search_index[search_term]; + this.search_index[selling_price_list] = this.search_index[selling_price_list] || {}; + if (this.search_index[selling_price_list][search_term]) { + const items = this.search_index[selling_price_list][search_term]; this.items = items; this.render_item_list(items); this.auto_add_item && this.items.length == 1 && this.add_filtered_item_to_cart(); @@ -346,7 +349,7 @@ erpnext.PointOfSale.ItemSelector = class { // eslint-disable-next-line no-unused-vars const { items, serial_no, batch_no, barcode } = message; if (search_term && !barcode) { - this.search_index[search_term] = items; + this.search_index[selling_price_list][search_term] = items; } this.items = items; this.render_item_list(items); From 01254da4e06b6e0114ecfc56e89aacdf5bab027b Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 15:01:23 +0530 Subject: [PATCH 17/32] fix: update customer contact details on pos (backport #45071) (#45106) fix: update customer contact details on pos (#45071) * fix: update customer contact details on pos * refactor: removed console log statement (cherry picked from commit d79e5612484a547cbe6828476d60a87a815568fd) Co-authored-by: Diptanil Saha --- erpnext/selling/page/point_of_sale/pos_item_cart.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/erpnext/selling/page/point_of_sale/pos_item_cart.js b/erpnext/selling/page/point_of_sale/pos_item_cart.js index 325f7b258a9..28cb1aef339 100644 --- a/erpnext/selling/page/point_of_sale/pos_item_cart.js +++ b/erpnext/selling/page/point_of_sale/pos_item_cart.js @@ -928,10 +928,13 @@ erpnext.PointOfSale.ItemCart = class { const me = this; dfs.forEach((df) => { this[`customer_${df.fieldname}_field`] = frappe.ui.form.make_control({ - df: { ...df, onchange: handle_customer_field_change }, + df: df, parent: $customer_form.find(`.${df.fieldname}-field`), render_input: true, }); + this[`customer_${df.fieldname}_field`].$input?.on("blur", () => { + handle_customer_field_change.apply(this[`customer_${df.fieldname}_field`]); + }); this[`customer_${df.fieldname}_field`].set_value(this.customer_info[df.fieldname]); }); From f7b501b29bcaa39e486638cf442c385d7e7e39f1 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Mon, 6 Jan 2025 15:23:57 +0530 Subject: [PATCH 18/32] fix: Returned Qty in Work Order Consumed Materials report (cherry picked from commit 30d68a31e09553421ac91af78b1dfdeded81d6f5) --- .../work_order_consumed_materials.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/erpnext/manufacturing/report/work_order_consumed_materials/work_order_consumed_materials.py b/erpnext/manufacturing/report/work_order_consumed_materials/work_order_consumed_materials.py index 64363e20e39..a5690c477e4 100644 --- a/erpnext/manufacturing/report/work_order_consumed_materials/work_order_consumed_materials.py +++ b/erpnext/manufacturing/report/work_order_consumed_materials/work_order_consumed_materials.py @@ -50,7 +50,11 @@ def get_returned_materials(work_orders): raw_materials = frappe.get_all( "Stock Entry", - fields=["`tabStock Entry Detail`.`item_code`", "`tabStock Entry Detail`.`qty`"], + fields=[ + "`tabStock Entry`.`work_order`", + "`tabStock Entry Detail`.`item_code`", + "`tabStock Entry Detail`.`qty`", + ], filters=[ ["Stock Entry", "is_return", "=", 1], ["Stock Entry Detail", "docstatus", "=", 1], @@ -59,12 +63,14 @@ def get_returned_materials(work_orders): ) for d in raw_materials: - raw_materials_qty[d.item_code] += d.qty + key = (d.work_order, d.item_code) + raw_materials_qty[key] += d.qty for row in work_orders: row.returned_qty = 0.0 - if raw_materials_qty.get(row.raw_material_item_code): - row.returned_qty = raw_materials_qty.get(row.raw_material_item_code) + key = (row.parent, row.raw_material_item_code) + if raw_materials_qty.get(key): + row.returned_qty = raw_materials_qty.get(key) def get_fields(): From 0abace79112063e86eade3f5c25f6ff831566895 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 23:04:30 +0100 Subject: [PATCH 19/32] refactor(Project): extract custom button function (backport #45116) (#45117) Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com> --- erpnext/projects/doctype/project/project.js | 41 +++++++++++---------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/erpnext/projects/doctype/project/project.js b/erpnext/projects/doctype/project/project.js index 643e3b21782..e609e35111f 100644 --- a/erpnext/projects/doctype/project/project.js +++ b/erpnext/projects/doctype/project/project.js @@ -147,29 +147,32 @@ frappe.ui.form.on("Project", { set_project_status_button: function (frm) { frm.add_custom_button( __("Set Project Status"), - () => { - let d = new frappe.ui.Dialog({ - title: __("Set Project Status"), - fields: [ - { - fieldname: "status", - fieldtype: "Select", - label: "Status", - reqd: 1, - options: "Completed\nCancelled", - }, - ], - primary_action: function () { - frm.events.set_status(frm, d.get_values().status); - d.hide(); - }, - primary_action_label: __("Set Project Status"), - }).show(); - }, + () => frm.events.get_project_status_dialog(frm).show(), __("Actions") ); }, + get_project_status_dialog: function (frm) { + const dialog = new frappe.ui.Dialog({ + title: __("Set Project Status"), + fields: [ + { + fieldname: "status", + fieldtype: "Select", + label: "Status", + reqd: 1, + options: "Completed\nCancelled", + }, + ], + primary_action: function () { + frm.events.set_status(frm, dialog.get_values().status); + dialog.hide(); + }, + primary_action_label: __("Set Project Status"), + }); + return dialog; + }, + create_duplicate: function (frm) { return new Promise((resolve) => { frappe.prompt("Project Name", (data) => { From 0001d868c7f3bf79b296111291608e20340bb261 Mon Sep 17 00:00:00 2001 From: Raffael Meyer <14891507+barredterra@users.noreply.github.com> Date: Mon, 6 Jan 2025 23:12:53 +0100 Subject: [PATCH 20/32] fix(Project): make status in confirmation dialog translatable (#45118) (cherry picked from commit 9eede907f892dbf2c03d976270164e318091dcfa) --- erpnext/projects/doctype/project/project.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/projects/doctype/project/project.js b/erpnext/projects/doctype/project/project.js index e609e35111f..45baff562ce 100644 --- a/erpnext/projects/doctype/project/project.js +++ b/erpnext/projects/doctype/project/project.js @@ -191,7 +191,7 @@ frappe.ui.form.on("Project", { }, set_status: function (frm, status) { - frappe.confirm(__("Set Project and all Tasks to status {0}?", [status.bold()]), () => { + frappe.confirm(__("Set Project and all Tasks to status {0}?", [__(status).bold()]), () => { frappe .xcall("erpnext.projects.doctype.project.project.set_project_status", { project: frm.doc.name, From af5338116338ac9eb88e9c440528cff248aa03d4 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 7 Jan 2025 11:14:42 +0530 Subject: [PATCH 21/32] fix: discount resetting on date change revert #44989 (cherry picked from commit 886281f81a2c1d39f736aea5100a61d6ddd08325) --- erpnext/public/js/controllers/transaction.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index f6d124de23d..b3389b27e84 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -974,7 +974,6 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe } transaction_date() { - this.apply_pricing_rule() if (this.frm.doc.transaction_date) { this.frm.transaction_date = this.frm.doc.transaction_date; frappe.ui.form.trigger(this.frm.doc.doctype, "currency"); @@ -983,7 +982,6 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe posting_date() { var me = this; - me.apply_pricing_rule() if (this.frm.doc.posting_date) { this.frm.posting_date = this.frm.doc.posting_date; From f654c2d156e9fab1c74683fc264ab72d14cf0c88 Mon Sep 17 00:00:00 2001 From: Ejaaz Khan <67804911+iamejaaz@users.noreply.github.com> Date: Tue, 7 Jan 2025 17:17:59 +0530 Subject: [PATCH 22/32] refactor: change sales invoice button position (#45130) (cherry picked from commit a0f17f8e7381c31dc2f704ecc238983179ef4c5f) --- .../doctype/sales_invoice/sales_invoice.js | 84 ++++++++++--------- erpnext/public/js/controllers/transaction.js | 3 +- 2 files changed, 45 insertions(+), 42 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index 75c71ef6eb3..c07e2a392ae 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -994,47 +994,51 @@ frappe.ui.form.on("Sales Invoice", { refresh: function (frm) { if (frm.doc.docstatus === 0 && !frm.doc.is_return) { - frm.add_custom_button(__("Fetch Timesheet"), function () { - let d = new frappe.ui.Dialog({ - title: __("Fetch Timesheet"), - fields: [ - { - label: __("From"), - fieldname: "from_time", - fieldtype: "Date", - reqd: 1, + frm.add_custom_button( + __("Timesheet"), + function () { + let d = new frappe.ui.Dialog({ + title: __("Fetch Timesheet"), + fields: [ + { + label: __("From"), + fieldname: "from_time", + fieldtype: "Date", + reqd: 1, + }, + { + fieldtype: "Column Break", + fieldname: "col_break_1", + }, + { + label: __("To"), + fieldname: "to_time", + fieldtype: "Date", + reqd: 1, + }, + { + label: __("Project"), + fieldname: "project", + fieldtype: "Link", + options: "Project", + default: frm.doc.project, + }, + ], + primary_action: function () { + const data = d.get_values(); + frm.events.add_timesheet_data(frm, { + from_time: data.from_time, + to_time: data.to_time, + project: data.project, + }); + d.hide(); }, - { - fieldtype: "Column Break", - fieldname: "col_break_1", - }, - { - label: __("To"), - fieldname: "to_time", - fieldtype: "Date", - reqd: 1, - }, - { - label: __("Project"), - fieldname: "project", - fieldtype: "Link", - options: "Project", - default: frm.doc.project, - }, - ], - primary_action: function () { - const data = d.get_values(); - frm.events.add_timesheet_data(frm, { - from_time: data.from_time, - to_time: data.to_time, - project: data.project, - }); - d.hide(); - }, - primary_action_label: __("Get Timesheets"), - }); - d.show(); - }); + primary_action_label: __("Get Timesheets"), + }); + d.show(); + }, + __("Get Items From") + ); } if (frm.doc.is_debit_note) { diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index b3389b27e84..9e3a76b12ca 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -303,11 +303,10 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe } const me = this; - if (!this.frm.is_new() && this.frm.doc.docstatus === 0 && frappe.model.can_create("Quality Inspection")) { + if (!this.frm.is_new() && this.frm.doc.docstatus === 0 && frappe.model.can_create("Quality Inspection") && this.frm.doc.update_stock) { this.frm.add_custom_button(__("Quality Inspection(s)"), () => { me.make_quality_inspection(); }, __("Create")); - this.frm.page.set_inner_btn_group_as_primary(__('Create')); } const inspection_type = ["Purchase Receipt", "Purchase Invoice", "Subcontracting Receipt"].includes(this.frm.doc.doctype) From 54e3a749365c6979fb83b2cb962fd4db8f04cd60 Mon Sep 17 00:00:00 2001 From: Diptanil Saha Date: Tue, 7 Jan 2025 18:06:02 +0530 Subject: [PATCH 23/32] fix: serial and batch no. buttons on pos (#45048) (cherry picked from commit 31dd32dcdfcb054595cfa04ad1efa43377783656) --- .../page/point_of_sale/pos_item_details.js | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/erpnext/selling/page/point_of_sale/pos_item_details.js b/erpnext/selling/page/point_of_sale/pos_item_details.js index 2c93a0d546b..333b50810c9 100644 --- a/erpnext/selling/page/point_of_sale/pos_item_details.js +++ b/erpnext/selling/page/point_of_sale/pos_item_details.js @@ -210,10 +210,21 @@ erpnext.PointOfSale.ItemDetails = class { make_auto_serial_selection_btn(item) { if (item.has_serial_no || item.has_batch_no) { - const label = item.has_serial_no ? __("Select Serial No") : __("Select Batch No"); - this.$form_container.append( - `
${label}
` - ); + if (item.has_serial_no && item.has_batch_no) { + this.$form_container.append( + `
${__( + "Select Serial No / Batch No" + )}
` + ); + } else { + const classname = item.has_serial_no ? ".serial_no-control" : ".batch_no-control"; + const label = item.has_serial_no ? __("Select Serial No") : __("Select Batch No"); + this.$form_container + .find(classname) + .append( + `
${label}
` + ); + } this.$form_container.find(".serial_no-control").find("textarea").css("height", "6rem"); } } From 87405f0753d78655d621f3324003ac2b3ee743ca Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Tue, 7 Jan 2025 17:29:35 +0530 Subject: [PATCH 24/32] fix: issue in returning components against the SCO (cherry picked from commit 729ce1dc50a408a6eea74fefd80ecf4cb4b5c8e5) --- .../controllers/subcontracting_controller.py | 6 +- .../tests/test_subcontracting_controller.py | 73 +++++++++++++++++++ .../serial_and_batch_bundle.py | 2 +- .../report/stock_balance/stock_balance.py | 1 - 4 files changed, 79 insertions(+), 3 deletions(-) diff --git a/erpnext/controllers/subcontracting_controller.py b/erpnext/controllers/subcontracting_controller.py index 0f9431ab440..349a15703fb 100644 --- a/erpnext/controllers/subcontracting_controller.py +++ b/erpnext/controllers/subcontracting_controller.py @@ -1257,6 +1257,7 @@ def add_items_in_ste(ste_doc, row, qty, rm_details, rm_detail_field="sco_rm_deta "item_code": row.item_details["rm_item_code"], "subcontracted_item": row.item_details["main_item_code"], "serial_no": "\n".join(row.serial_no) if row.serial_no else "", + "use_serial_batch_fields": 1, } ) @@ -1297,10 +1298,13 @@ def make_return_stock_entry_for_subcontract( if not value.qty: continue + if item_details := value.get("item_details"): + item_details["serial_and_batch_bundle"] = None + if value.batch_no: for batch_no, qty in value.batch_no.items(): if qty > 0: - add_items_in_ste(ste_doc, value, value.qty, rm_details, rm_detail_field, batch_no) + add_items_in_ste(ste_doc, value, qty, rm_details, rm_detail_field, batch_no) else: add_items_in_ste(ste_doc, value, value.qty, rm_details, rm_detail_field) diff --git a/erpnext/controllers/tests/test_subcontracting_controller.py b/erpnext/controllers/tests/test_subcontracting_controller.py index 0bc348e8876..3b11a0f8029 100644 --- a/erpnext/controllers/tests/test_subcontracting_controller.py +++ b/erpnext/controllers/tests/test_subcontracting_controller.py @@ -282,6 +282,79 @@ class TestSubcontractingController(FrappeTestCase): frappe.db.set_single_value("Stock Settings", "use_serial_batch_fields", 1) + def test_return_non_consumed_batch_materials(self): + """ + - Set backflush based on Material Transfer. + - Create SCO for item Subcontracted Item SA2. + - Transfer the batched components from Stores to Supplier warehouse with serial nos. + - Transfer extra qty of component for the subcontracted item Subcontracted Item SA2. + - Create SCR for full qty against the SCO and change the qty of raw material. + - After that return the non consumed material back to the store from supplier's warehouse. + """ + + frappe.db.set_single_value("Stock Settings", "use_serial_batch_fields", 0) + set_backflush_based_on("Material Transferred for Subcontract") + service_item = make_item("Subcontracted Service FG Item A", properties={"is_stock_item": 0}).name + fg_item = make_item( + "Subcontracted FG Item SA2", properties={"is_stock_item": 1, "is_sub_contracted_item": 1} + ).name + rm_item = make_item( + "Subcontracted Batch RM Item SA2", + properties={ + "is_stock_item": 1, + "create_new_batch": 1, + "has_batch_no": 1, + "batch_number_series": "BATCH-RM-IRM-.####", + }, + ).name + + make_bom(item=fg_item, raw_materials=[rm_item], rate=100, currency="INR") + + service_items = [ + { + "warehouse": "_Test Warehouse - _TC", + "item_code": service_item, + "qty": 5, + "rate": 100, + "fg_item": fg_item, + "fg_item_qty": 5, + }, + ] + sco = get_subcontracting_order(service_items=service_items) + rm_items = get_rm_items(sco.supplied_items) + rm_items[0]["qty"] += 1 + itemwise_details = make_stock_in_entry(rm_items=rm_items) + + for item in rm_items: + item["sco_rm_detail"] = sco.items[0].name + + make_stock_transfer_entry( + sco_no=sco.name, + rm_items=rm_items, + itemwise_details=copy.deepcopy(itemwise_details), + ) + + scr1 = make_subcontracting_receipt(sco.name) + scr1.save() + scr1.supplied_items[0].consumed_qty = 5 + scr1.submit() + + for key, value in get_supplied_items(scr1).items(): + transferred_detais = itemwise_details.get(key) + self.assertEqual(value.qty, 5) + self.assertEqual(sorted(value.serial_no), sorted(transferred_detais.get("serial_no")[0:5])) + + sco.load_from_db() + self.assertEqual(sco.supplied_items[0].consumed_qty, 5) + doc = get_materials_from_supplier(sco.name, [d.name for d in sco.supplied_items]) + doc.save() + self.assertEqual(doc.items[0].qty, 1) + self.assertEqual(doc.items[0].s_warehouse, "_Test Warehouse 1 - _TC") + self.assertEqual(doc.items[0].t_warehouse, "_Test Warehouse - _TC") + self.assertTrue(doc.items[0].batch_no) + self.assertTrue(doc.items[0].use_serial_batch_fields) + frappe.db.set_single_value("Stock Settings", "use_serial_batch_fields", 1) + def test_return_non_consumed_materials(self): """ - Set backflush based on Material Transfer. diff --git a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py index af378ca2f0b..00076e8ca16 100644 --- a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py +++ b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py @@ -1557,7 +1557,7 @@ def get_type_of_transaction(parent_doc, child_row): elif parent_doc.get("doctype") == "Stock Reconciliation": type_of_transaction = "Inward" - if parent_doc.get("is_return"): + if parent_doc.get("is_return") and parent_doc.get("doctype") != "Stock Entry": type_of_transaction = "Inward" if ( parent_doc.get("doctype") in ["Purchase Receipt", "Purchase Invoice"] diff --git a/erpnext/stock/report/stock_balance/stock_balance.py b/erpnext/stock/report/stock_balance/stock_balance.py index 8ea07338cf1..6b5a3661a37 100644 --- a/erpnext/stock/report/stock_balance/stock_balance.py +++ b/erpnext/stock/report/stock_balance/stock_balance.py @@ -317,7 +317,6 @@ class StockBalanceReport: .where((sle.docstatus < 2) & (sle.is_cancelled == 0)) .orderby(sle.posting_datetime) .orderby(sle.creation) - .orderby(sle.actual_qty) ) query = self.apply_inventory_dimensions_filters(query, sle) From 1ea36bba886ecae907aa0a09e5a6e86e77899cb9 Mon Sep 17 00:00:00 2001 From: Khushi Rawat <142375893+khushi8112@users.noreply.github.com> Date: Tue, 7 Jan 2025 17:38:21 +0530 Subject: [PATCH 25/32] feat: work in progress status for asset (#45066) * feat: work in progress status for asset * fix: test case correction * fix(patch): added patch to update status of assets * fix: updated tests (cherry picked from commit 6850019649ca2b357c19d244cf2b1bd0054c7617) # Conflicts: # erpnext/assets/doctype/asset/asset.json # erpnext/patches.txt --- erpnext/assets/doctype/asset/asset.json | 6 +++++- erpnext/assets/doctype/asset/asset.py | 1 + erpnext/assets/doctype/asset/asset_list.js | 7 +++++-- erpnext/assets/doctype/asset/test_asset.py | 4 ++++ .../asset_capitalization/asset_capitalization.py | 6 ++++-- .../asset_capitalization/test_asset_capitalization.py | 2 ++ .../asset_depreciation_schedule.py | 5 +++-- erpnext/patches.txt | 5 +++++ .../v15_0/update_asset_status_to_work_in_progress.py | 11 +++++++++++ 9 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 erpnext/patches/v15_0/update_asset_status_to_work_in_progress.py diff --git a/erpnext/assets/doctype/asset/asset.json b/erpnext/assets/doctype/asset/asset.json index 55932e9b787..6bf3333d4d3 100644 --- a/erpnext/assets/doctype/asset/asset.json +++ b/erpnext/assets/doctype/asset/asset.json @@ -378,7 +378,7 @@ "in_standard_filter": 1, "label": "Status", "no_copy": 1, - "options": "Draft\nSubmitted\nPartially Depreciated\nFully Depreciated\nSold\nScrapped\nIn Maintenance\nOut of Order\nIssue\nReceipt\nCapitalized\nDecapitalized", + "options": "Draft\nSubmitted\nPartially Depreciated\nFully Depreciated\nSold\nScrapped\nIn Maintenance\nOut of Order\nIssue\nReceipt\nCapitalized\nDecapitalized\nWork In Progress", "read_only": 1 }, { @@ -595,7 +595,11 @@ "link_fieldname": "target_asset" } ], +<<<<<<< HEAD "modified": "2024-08-26 23:28:29.095139", +======= + "modified": "2024-12-26 14:23:20.968882", +>>>>>>> 6850019649 (feat: work in progress status for asset (#45066)) "modified_by": "Administrator", "module": "Assets", "name": "Asset", diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 2e0ba2c8218..8aa8c0ba6ac 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -112,6 +112,7 @@ class Asset(AccountsController): "Receipt", "Capitalized", "Decapitalized", + "Work In Progress", ] supplier: DF.Link | None total_asset_cost: DF.Currency diff --git a/erpnext/assets/doctype/asset/asset_list.js b/erpnext/assets/doctype/asset/asset_list.js index 712958adcfc..0086333a96b 100644 --- a/erpnext/assets/doctype/asset/asset_list.js +++ b/erpnext/assets/doctype/asset/asset_list.js @@ -1,5 +1,6 @@ frappe.listview_settings["Asset"] = { - add_fields: ["status"], + add_fields: ["status", "docstatus"], + has_indicator_for_draft: 1, get_indicator: function (doc) { if (doc.status === "Fully Depreciated") { return [__("Fully Depreciated"), "green", "status,=,Fully Depreciated"]; @@ -7,6 +8,8 @@ frappe.listview_settings["Asset"] = { return [__("Partially Depreciated"), "grey", "status,=,Partially Depreciated"]; } else if (doc.status === "Sold") { return [__("Sold"), "green", "status,=,Sold"]; + } else if (doc.status === "Work In Progress") { + return [__("Work In Progress"), "orange", "status,=,Work In Progress"]; } else if (["Capitalized", "Decapitalized"].includes(doc.status)) { return [__(doc.status), "grey", "status,=," + doc.status]; } else if (doc.status === "Scrapped") { @@ -21,7 +24,7 @@ frappe.listview_settings["Asset"] = { return [__("Receipt"), "green", "status,=,Receipt"]; } else if (doc.status === "Submitted") { return [__("Submitted"), "blue", "status,=,Submitted"]; - } else if (doc.status === "Draft") { + } else if (doc.status === "Draft" || doc.docstatus === 0) { return [__("Draft"), "red", "status,=,Draft"]; } }, diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py index 8a320d617ff..9c8db82f41b 100644 --- a/erpnext/assets/doctype/asset/test_asset.py +++ b/erpnext/assets/doctype/asset/test_asset.py @@ -1725,6 +1725,10 @@ def create_asset(**args): }, ) + if asset.is_composite_asset: + asset.gross_purchase_amount = 0 + asset.purchase_amount = 0 + if not args.do_not_save: try: asset.insert(ignore_if_duplicate=True) diff --git a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py index b38bd952bca..d33d5c4df73 100644 --- a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py +++ b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py @@ -638,6 +638,7 @@ class AssetCapitalization(StockController): self.target_fixed_asset_account = get_asset_category_account( "fixed_asset_account", item=self.target_item_code, company=asset_doc.company ) + asset_doc.set_status("Work In Progress") add_asset_activity( asset_doc.name, @@ -662,8 +663,9 @@ class AssetCapitalization(StockController): total_target_asset_value = flt(self.total_value, self.precision("total_value")) asset_doc = frappe.get_doc("Asset", self.target_asset) - asset_doc.gross_purchase_amount = total_target_asset_value - asset_doc.purchase_amount = total_target_asset_value + asset_doc.gross_purchase_amount += total_target_asset_value + asset_doc.purchase_amount += total_target_asset_value + asset_doc.set_status("Work In Progress") asset_doc.flags.ignore_validate = True asset_doc.save() diff --git a/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py b/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py index 86293fac765..ba1c5fc2444 100644 --- a/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py +++ b/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py @@ -96,6 +96,7 @@ class TestAssetCapitalization(unittest.TestCase): target_asset = frappe.get_doc("Asset", asset_capitalization.target_asset) self.assertEqual(target_asset.gross_purchase_amount, total_amount) self.assertEqual(target_asset.purchase_amount, total_amount) + self.assertEqual(target_asset.status, "Work In Progress") # Test Consumed Asset values self.assertEqual(consumed_asset.db_get("status"), "Capitalized") @@ -270,6 +271,7 @@ class TestAssetCapitalization(unittest.TestCase): target_asset = frappe.get_doc("Asset", asset_capitalization.target_asset) self.assertEqual(target_asset.gross_purchase_amount, total_amount) self.assertEqual(target_asset.purchase_amount, total_amount) + self.assertEqual(target_asset.status, "Work In Progress") # Test General Ledger Entries expected_gle = { diff --git a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py index a60478ac8a1..c3c9ef2321b 100644 --- a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py +++ b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py @@ -13,6 +13,7 @@ from frappe.utils import ( flt, get_first_day, get_last_day, + get_link_to_form, getdate, is_last_day_of_the_month, month_diff, @@ -1062,7 +1063,7 @@ def make_new_active_asset_depr_schedules_and_cancel_current_ones( if not current_asset_depr_schedule_doc: frappe.throw( _("Asset Depreciation Schedule not found for Asset {0} and Finance Book {1}").format( - asset_doc.name, row.finance_book + get_link_to_form("Asset", asset_doc.name), row.finance_book ) ) @@ -1108,7 +1109,7 @@ def get_temp_asset_depr_schedule_doc( if not current_asset_depr_schedule_doc: frappe.throw( _("Asset Depreciation Schedule not found for Asset {0} and Finance Book {1}").format( - asset_doc.name, row.finance_book + get_link_to_form("Asset", asset_doc.name), row.finance_book ) ) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 7e03ef9394c..4f50a3a6c07 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -386,3 +386,8 @@ erpnext.patches.v14_0.update_stock_uom_in_work_order_item erpnext.patches.v15_0.set_is_exchange_gain_loss_in_payment_entry_deductions erpnext.patches.v15_0.enable_allow_existing_serial_no erpnext.patches.v15_0.update_cc_in_process_statement_of_accounts +<<<<<<< HEAD +======= +erpnext.patches.v15_0.refactor_closing_stock_balance #5 +erpnext.patches.v15_0.update_asset_status_to_work_in_progress +>>>>>>> 6850019649 (feat: work in progress status for asset (#45066)) diff --git a/erpnext/patches/v15_0/update_asset_status_to_work_in_progress.py b/erpnext/patches/v15_0/update_asset_status_to_work_in_progress.py new file mode 100644 index 00000000000..3ac7f25da15 --- /dev/null +++ b/erpnext/patches/v15_0/update_asset_status_to_work_in_progress.py @@ -0,0 +1,11 @@ +import frappe + + +def execute(): + Asset = frappe.qb.DocType("Asset") + query = ( + frappe.qb.update(Asset) + .set(Asset.status, "Work In Progress") + .where((Asset.docstatus == 0) & (Asset.is_composite_asset == 1)) + ) + query.run() From 931b5166a86d235e709734f79065d6cab57c8547 Mon Sep 17 00:00:00 2001 From: marination Date: Mon, 6 Jan 2025 20:27:06 +0530 Subject: [PATCH 26/32] fix: Missing company filter breaks `get_account_balance` in Bank Reco (cherry picked from commit 8de0fe78eaa3c6798a9fa002513ee912852f661c) --- .../bank_reconciliation_tool.js | 2 ++ .../bank_reconciliation_tool.py | 26 ++++++++++--------- .../data_table_manager.js | 3 ++- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.js b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.js index b15745d834c..7a653e12c72 100644 --- a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.js +++ b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.js @@ -120,6 +120,7 @@ frappe.ui.form.on("Bank Reconciliation Tool", { args: { bank_account: frm.doc.bank_account, till_date: frappe.datetime.add_days(frm.doc.bank_statement_from_date, -1), + company: frm.doc.company, }, callback: (response) => { frm.set_value("account_opening_balance", response.message); @@ -135,6 +136,7 @@ frappe.ui.form.on("Bank Reconciliation Tool", { args: { bank_account: frm.doc.bank_account, till_date: frm.doc.bank_statement_to_date, + company: frm.doc.company, }, callback: (response) => { frm.cleared_balance = response.message; diff --git a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py index ce7e9436ad5..4b677d56f1f 100644 --- a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py +++ b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py @@ -5,11 +5,6 @@ import json import frappe -from frappe import _ -from frappe.model.document import Document -from frappe.query_builder.custom import ConstantColumn -from frappe.utils import cint, flt - from erpnext import get_default_cost_center from erpnext.accounts.doctype.bank_transaction.bank_transaction import get_total_allocated_amount from erpnext.accounts.party import get_party_account @@ -19,6 +14,10 @@ from erpnext.accounts.report.bank_reconciliation_statement.bank_reconciliation_s ) from erpnext.accounts.utils import get_account_currency, get_balance_on from erpnext.setup.utils import get_exchange_rate +from frappe import _ +from frappe.model.document import Document +from frappe.query_builder.custom import ConstantColumn +from frappe.utils import cint, flt class BankReconciliationTool(Document): @@ -79,10 +78,17 @@ def get_bank_transactions(bank_account, from_date=None, to_date=None): @frappe.whitelist() -def get_account_balance(bank_account, till_date): +def get_account_balance(bank_account, till_date, company): # returns account balance till the specified date account = frappe.db.get_value("Bank Account", bank_account, "account") - filters = frappe._dict({"account": account, "report_date": till_date, "include_pos_transactions": 1}) + filters = frappe._dict( + { + "account": account, + "report_date": till_date, + "include_pos_transactions": 1, + "company": company, + } + ) data = get_entries(filters) balance_as_per_system = get_balance_on(filters["account"], filters["report_date"]) @@ -94,11 +100,7 @@ def get_account_balance(bank_account, till_date): amounts_not_reflected_in_system = get_amounts_not_reflected_in_system(filters) - bank_bal = ( - flt(balance_as_per_system) - flt(total_debit) + flt(total_credit) + amounts_not_reflected_in_system - ) - - return bank_bal + return flt(balance_as_per_system) - flt(total_debit) + flt(total_credit) + amounts_not_reflected_in_system @frappe.whitelist() diff --git a/erpnext/public/js/bank_reconciliation_tool/data_table_manager.js b/erpnext/public/js/bank_reconciliation_tool/data_table_manager.js index 4aa087e99cf..ad5fd528cda 100644 --- a/erpnext/public/js/bank_reconciliation_tool/data_table_manager.js +++ b/erpnext/public/js/bank_reconciliation_tool/data_table_manager.js @@ -16,7 +16,7 @@ erpnext.accounts.bank_reconciliation.DataTableManager = class DataTableManager { } make_dt() { - var me = this; + const me = this; frappe.call({ method: "erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.get_bank_transactions", args: { @@ -193,6 +193,7 @@ erpnext.accounts.bank_reconciliation.DataTableManager = class DataTableManager { args: { bank_account: this.bank_account, till_date: this.bank_statement_to_date, + company: this.company, }, callback: (response) => (this.cleared_balance = response.message), }); From 754845a935d735a5e074b7de42f1df40cf8cf2e7 Mon Sep 17 00:00:00 2001 From: marination Date: Mon, 6 Jan 2025 21:14:41 +0530 Subject: [PATCH 27/32] fix: Override pre-commit behaviour due to conflicts with CI (cherry picked from commit d7bf73cffa5628c185f4ceabd6020c7e4daf54a6) --- .../bank_reconciliation_tool/bank_reconciliation_tool.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py index 4b677d56f1f..62a4c74a933 100644 --- a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py +++ b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py @@ -5,6 +5,11 @@ import json import frappe +from frappe import _ +from frappe.model.document import Document +from frappe.query_builder.custom import ConstantColumn +from frappe.utils import cint, flt + from erpnext import get_default_cost_center from erpnext.accounts.doctype.bank_transaction.bank_transaction import get_total_allocated_amount from erpnext.accounts.party import get_party_account @@ -14,10 +19,6 @@ from erpnext.accounts.report.bank_reconciliation_statement.bank_reconciliation_s ) from erpnext.accounts.utils import get_account_currency, get_balance_on from erpnext.setup.utils import get_exchange_rate -from frappe import _ -from frappe.model.document import Document -from frappe.query_builder.custom import ConstantColumn -from frappe.utils import cint, flt class BankReconciliationTool(Document): From acd66fa00c087c6d023675679b31a2c96fcde220 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Wed, 8 Jan 2025 08:22:37 +0530 Subject: [PATCH 28/32] chore: remove 'Experimental' tag (cherry picked from commit 4620025dcd5833d3a60b5787120f641e463a489b) # Conflicts: # erpnext/accounts/doctype/process_payment_reconciliation_log/process_payment_reconciliation_log.json --- .../process_payment_reconciliation.json | 5 ++--- .../process_payment_reconciliation.py | 2 +- .../process_payment_reconciliation_log.json | 5 ++++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/erpnext/accounts/doctype/process_payment_reconciliation/process_payment_reconciliation.json b/erpnext/accounts/doctype/process_payment_reconciliation/process_payment_reconciliation.json index 0511571d754..bfd4e0ad63a 100644 --- a/erpnext/accounts/doctype/process_payment_reconciliation/process_payment_reconciliation.json +++ b/erpnext/accounts/doctype/process_payment_reconciliation/process_payment_reconciliation.json @@ -1,7 +1,6 @@ { "actions": [], "autoname": "format:ACC-PPR-{#####}", - "beta": 1, "creation": "2023-03-30 21:28:39.793927", "default_view": "List", "doctype": "DocType", @@ -158,7 +157,7 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2024-08-27 14:48:56.715320", + "modified": "2025-01-08 08:22:14.798085", "modified_by": "Administrator", "module": "Accounts", "name": "Process Payment Reconciliation", @@ -192,4 +191,4 @@ "sort_order": "DESC", "states": [], "title_field": "company" -} +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/process_payment_reconciliation/process_payment_reconciliation.py b/erpnext/accounts/doctype/process_payment_reconciliation/process_payment_reconciliation.py index 882a2c4ad1c..35f1e31af34 100644 --- a/erpnext/accounts/doctype/process_payment_reconciliation/process_payment_reconciliation.py +++ b/erpnext/accounts/doctype/process_payment_reconciliation/process_payment_reconciliation.py @@ -212,7 +212,7 @@ def trigger_reconciliation_for_queued_docs(): unique_filters = set() queue_size = 5 - fields = ["company", "party_type", "party", "receivable_payable_account"] + fields = ["company", "party_type", "party", "receivable_payable_account", "default_advance_account"] def get_filters_as_tuple(fields, doc): filters = () diff --git a/erpnext/accounts/doctype/process_payment_reconciliation_log/process_payment_reconciliation_log.json b/erpnext/accounts/doctype/process_payment_reconciliation_log/process_payment_reconciliation_log.json index b4ac9812cbf..d5e52a72df5 100644 --- a/erpnext/accounts/doctype/process_payment_reconciliation_log/process_payment_reconciliation_log.json +++ b/erpnext/accounts/doctype/process_payment_reconciliation_log/process_payment_reconciliation_log.json @@ -1,7 +1,6 @@ { "actions": [], "autoname": "format:PPR-LOG-{##}", - "beta": 1, "creation": "2023-03-13 15:00:09.149681", "default_view": "List", "doctype": "DocType", @@ -110,7 +109,11 @@ "in_create": 1, "index_web_pages_for_search": 1, "links": [], +<<<<<<< HEAD "modified": "2023-11-02 11:32:12.254018", +======= + "modified": "2025-01-08 08:22:19.104975", +>>>>>>> 4620025dcd (chore: remove 'Experimental' tag) "modified_by": "Administrator", "module": "Accounts", "name": "Process Payment Reconciliation Log", From 36dbb867ed23f8e66bcdf839096fcfeaf7d0e896 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Wed, 8 Jan 2025 09:19:53 +0530 Subject: [PATCH 29/32] chore: resolve conflict --- .../process_payment_reconciliation_log.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/erpnext/accounts/doctype/process_payment_reconciliation_log/process_payment_reconciliation_log.json b/erpnext/accounts/doctype/process_payment_reconciliation_log/process_payment_reconciliation_log.json index d5e52a72df5..3e3e231fe1d 100644 --- a/erpnext/accounts/doctype/process_payment_reconciliation_log/process_payment_reconciliation_log.json +++ b/erpnext/accounts/doctype/process_payment_reconciliation_log/process_payment_reconciliation_log.json @@ -109,11 +109,7 @@ "in_create": 1, "index_web_pages_for_search": 1, "links": [], -<<<<<<< HEAD - "modified": "2023-11-02 11:32:12.254018", -======= "modified": "2025-01-08 08:22:19.104975", ->>>>>>> 4620025dcd (chore: remove 'Experimental' tag) "modified_by": "Administrator", "module": "Accounts", "name": "Process Payment Reconciliation Log", From 7318748a4ccc51c69fb6f86ef49c9cc8d9df1d83 Mon Sep 17 00:00:00 2001 From: Khushi Rawat <142375893+khushi8112@users.noreply.github.com> Date: Wed, 8 Jan 2025 11:07:30 +0530 Subject: [PATCH 30/32] fix: resolved conflicts --- erpnext/assets/doctype/asset/asset.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.json b/erpnext/assets/doctype/asset/asset.json index 6bf3333d4d3..fca0cf7877a 100644 --- a/erpnext/assets/doctype/asset/asset.json +++ b/erpnext/assets/doctype/asset/asset.json @@ -595,11 +595,7 @@ "link_fieldname": "target_asset" } ], -<<<<<<< HEAD - "modified": "2024-08-26 23:28:29.095139", -======= "modified": "2024-12-26 14:23:20.968882", ->>>>>>> 6850019649 (feat: work in progress status for asset (#45066)) "modified_by": "Administrator", "module": "Assets", "name": "Asset", From e9be8583b0f374e5c2b5b655377c4397bb130288 Mon Sep 17 00:00:00 2001 From: Khushi Rawat <142375893+khushi8112@users.noreply.github.com> Date: Wed, 8 Jan 2025 11:08:27 +0530 Subject: [PATCH 31/32] fix: resolved conflicts --- erpnext/patches.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 4f50a3a6c07..d553fd12bb5 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -386,8 +386,5 @@ erpnext.patches.v14_0.update_stock_uom_in_work_order_item erpnext.patches.v15_0.set_is_exchange_gain_loss_in_payment_entry_deductions erpnext.patches.v15_0.enable_allow_existing_serial_no erpnext.patches.v15_0.update_cc_in_process_statement_of_accounts -<<<<<<< HEAD -======= erpnext.patches.v15_0.refactor_closing_stock_balance #5 erpnext.patches.v15_0.update_asset_status_to_work_in_progress ->>>>>>> 6850019649 (feat: work in progress status for asset (#45066)) From 4227d76f082496b79ef2ae4ebf2bab2502f63e5e Mon Sep 17 00:00:00 2001 From: Khushi Rawat <142375893+khushi8112@users.noreply.github.com> Date: Wed, 8 Jan 2025 11:23:38 +0530 Subject: [PATCH 32/32] fix: removed unmerged patches --- erpnext/patches.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index d553fd12bb5..cfc8be90b4b 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -386,5 +386,4 @@ erpnext.patches.v14_0.update_stock_uom_in_work_order_item erpnext.patches.v15_0.set_is_exchange_gain_loss_in_payment_entry_deductions erpnext.patches.v15_0.enable_allow_existing_serial_no erpnext.patches.v15_0.update_cc_in_process_statement_of_accounts -erpnext.patches.v15_0.refactor_closing_stock_balance #5 erpnext.patches.v15_0.update_asset_status_to_work_in_progress