From 9d6f3180d4313b4363ff83312c06091782bedc1c Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Wed, 5 Feb 2025 15:48:08 +0530 Subject: [PATCH 01/37] fix: create job card with wip warehouse set to source warehouse if material transfer to wip warehouse is skipped in work order (cherry picked from commit 723e902470c772469f1fd3ecc04d2923acf96d0b) # Conflicts: # erpnext/manufacturing/doctype/work_order/work_order.py --- .../manufacturing/doctype/work_order/work_order.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py index e6e7d7612c5..d34d6bed57a 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order.py +++ b/erpnext/manufacturing/doctype/work_order/work_order.py @@ -1623,6 +1623,20 @@ def create_job_card(work_order, row, enable_capacity_planning=False, auto_create "wip_warehouse": work_order.wip_warehouse, "hour_rate": row.get("hour_rate"), "serial_no": row.get("serial_no"), +<<<<<<< HEAD +======= + "time_required": row.get("time_in_mins"), + "source_warehouse": row.get("source_warehouse"), + "target_warehouse": row.get("fg_warehouse"), + "wip_warehouse": work_order.wip_warehouse or row.get("wip_warehouse") + if not work_order.skip_transfer or work_order.from_wip_warehouse + else work_order.source_warehouse or row.get("source_warehouse"), + "skip_material_transfer": row.get("skip_material_transfer"), + "backflush_from_wip_warehouse": row.get("backflush_from_wip_warehouse"), + "finished_good": row.get("finished_good"), + "semi_fg_bom": row.get("bom_no"), + "is_subcontracted": row.get("is_subcontracted"), +>>>>>>> 723e902470 (fix: create job card with wip warehouse set to source warehouse if material transfer to wip warehouse is skipped in work order) } ) From 419698627388efbe131cd14f20eef0fc677b93d6 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Wed, 5 Feb 2025 17:59:34 +0530 Subject: [PATCH 02/37] chore: resolve conflicts --- .../doctype/work_order/work_order.py | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py index d34d6bed57a..721af21be99 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order.py +++ b/erpnext/manufacturing/doctype/work_order/work_order.py @@ -1620,23 +1620,11 @@ def create_job_card(work_order, row, enable_capacity_planning=False, auto_create "project": work_order.project, "company": work_order.company, "sequence_id": row.get("sequence_id"), - "wip_warehouse": work_order.wip_warehouse, - "hour_rate": row.get("hour_rate"), - "serial_no": row.get("serial_no"), -<<<<<<< HEAD -======= - "time_required": row.get("time_in_mins"), - "source_warehouse": row.get("source_warehouse"), - "target_warehouse": row.get("fg_warehouse"), "wip_warehouse": work_order.wip_warehouse or row.get("wip_warehouse") if not work_order.skip_transfer or work_order.from_wip_warehouse else work_order.source_warehouse or row.get("source_warehouse"), - "skip_material_transfer": row.get("skip_material_transfer"), - "backflush_from_wip_warehouse": row.get("backflush_from_wip_warehouse"), - "finished_good": row.get("finished_good"), - "semi_fg_bom": row.get("bom_no"), - "is_subcontracted": row.get("is_subcontracted"), ->>>>>>> 723e902470 (fix: create job card with wip warehouse set to source warehouse if material transfer to wip warehouse is skipped in work order) + "hour_rate": row.get("hour_rate"), + "serial_no": row.get("serial_no"), } ) From d4bc3d182fb7bb4409fcca949b7ff338984496f7 Mon Sep 17 00:00:00 2001 From: Sanket322 Date: Thu, 6 Feb 2025 17:55:37 +0530 Subject: [PATCH 03/37] fix: update ctx to args --- erpnext/public/js/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js index a000cdee7cc..cd851b57972 100755 --- a/erpnext/public/js/utils.js +++ b/erpnext/public/js/utils.js @@ -661,7 +661,7 @@ erpnext.utils.update_child_items = function (opts) { method: "erpnext.stock.get_item_details.get_item_details", args: { doc: frm.doc, - ctx: { + args: { item_code: this.value, set_warehouse: frm.doc.set_warehouse, customer: frm.doc.customer || frm.doc.party_name, From 3ada5206189a0c9b9b4ea667515503391a284fce Mon Sep 17 00:00:00 2001 From: ljain112 Date: Thu, 6 Feb 2025 18:56:29 +0530 Subject: [PATCH 04/37] fix: correct pay amount in portal pages --- erpnext/templates/pages/order.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/templates/pages/order.html b/erpnext/templates/pages/order.html index ade66dd481f..7fb5ed9b56a 100644 --- a/erpnext/templates/pages/order.html +++ b/erpnext/templates/pages/order.html @@ -40,7 +40,7 @@

- {{ _("Pay", null, "Amount") }} {{ pay_amount }} + {{ _("Pay", null, "Amount") }} {{doc.get_formatted("grand_total") }}

From 28cbce435667880ea7168b090e1b48f7d5b51cc4 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 6 Feb 2025 16:04:51 +0530 Subject: [PATCH 05/37] fix: the project document timed out while opening (cherry picked from commit 33d03b1542207c595c5e4abd5a874c96041462a2) # Conflicts: # erpnext/selling/doctype/sales_order/sales_order.json --- erpnext/accounts/doctype/sales_invoice/sales_invoice.json | 5 +++-- erpnext/projects/doctype/project/project.py | 2 -- erpnext/selling/doctype/sales_order/sales_order.json | 7 ++++++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index 4c6d9a85aa1..4183cc21ab8 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -299,7 +299,8 @@ "oldfieldname": "project_name", "oldfieldtype": "Link", "options": "Project", - "print_hide": 1 + "print_hide": 1, + "search_index": 1 }, { "default": "0", @@ -2186,7 +2187,7 @@ "link_fieldname": "consolidated_invoice" } ], - "modified": "2025-01-14 11:38:30.446370", + "modified": "2025-02-06 15:59:54.636202", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice", diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py index 5253cd0eae5..4ed8ffc0077 100644 --- a/erpnext/projects/doctype/project/project.py +++ b/erpnext/projects/doctype/project/project.py @@ -86,8 +86,6 @@ class Project(Document): ), ) - self.update_costing() - def before_print(self, settings=None): self.onload() diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json index 1525b9632de..3e89689024f 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.json +++ b/erpnext/selling/doctype/sales_order/sales_order.json @@ -1151,7 +1151,8 @@ "label": "Project", "oldfieldname": "project", "oldfieldtype": "Link", - "options": "Project" + "options": "Project", + "search_index": 1 }, { "fieldname": "party_account_currency", @@ -1654,7 +1655,11 @@ "idx": 105, "is_submittable": 1, "links": [], +<<<<<<< HEAD "modified": "2024-11-26 12:42:06.872527", +======= + "modified": "2025-02-06 16:02:20.320877", +>>>>>>> 33d03b1542 (fix: the project document timed out while opening) "modified_by": "Administrator", "module": "Selling", "name": "Sales Order", From 08a6f4e6d352de785a31a4c31b3dc074fffd5310 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Thu, 6 Feb 2025 22:09:44 +0530 Subject: [PATCH 06/37] chore: fix conflicts --- erpnext/selling/doctype/sales_order/sales_order.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json index 3e89689024f..4db7bf6f003 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.json +++ b/erpnext/selling/doctype/sales_order/sales_order.json @@ -1655,11 +1655,7 @@ "idx": 105, "is_submittable": 1, "links": [], -<<<<<<< HEAD - "modified": "2024-11-26 12:42:06.872527", -======= "modified": "2025-02-06 16:02:20.320877", ->>>>>>> 33d03b1542 (fix: the project document timed out while opening) "modified_by": "Administrator", "module": "Selling", "name": "Sales Order", @@ -1737,4 +1733,4 @@ "title_field": "customer_name", "track_changes": 1, "track_seen": 1 -} \ No newline at end of file +} From 96c19cd9902b0de61b6582435fc4a1bd552b4867 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Fri, 31 Jan 2025 15:34:50 +0530 Subject: [PATCH 07/37] fix: '0' rate LDC's Invoice net totals should be ignored (cherry picked from commit 325c4e3536aaf84be0d7fb9ff9850360b2eeb2bd) --- .../tax_withholding_category.py | 42 ++++++++++++++----- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py index 3215b93a496..06549973242 100644 --- a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py +++ b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py @@ -270,7 +270,10 @@ def get_lower_deduction_certificate(company, posting_date, tax_details, pan_no): def get_tax_amount(party_type, parties, inv, tax_details, posting_date, pan_no=None): vouchers, voucher_wise_amount = get_invoice_vouchers( - parties, tax_details, inv.company, party_type=party_type + parties, + tax_details, + inv.company, + party_type=party_type, ) payment_entry_vouchers = get_payment_entry_vouchers( @@ -360,11 +363,23 @@ def get_invoice_vouchers(parties, tax_details, company, party_type="Supplier"): voucher_wise_amount = [] vouchers = [] + ldcs = frappe.db.get_all( + "Lower Deduction Certificate", + filters={ + "valid_from": [">=", tax_details.from_date], + "valid_upto": ["<=", tax_details.to_date], + "company": company, + "supplier": ["in", parties], + }, + fields=["supplier", "valid_from", "valid_upto", "rate"], + ) + doctype = "Purchase Invoice" if party_type == "Supplier" else "Sales Invoice" field = [ "base_tax_withholding_net_total as base_net_total" if party_type == "Supplier" else "base_net_total", "name", "grand_total", + "posting_date", ] filters = { @@ -383,18 +398,23 @@ def get_invoice_vouchers(parties, tax_details, company, party_type="Supplier"): invoices_details = frappe.get_all(doctype, filters=filters, fields=field) for d in invoices_details: - vouchers.append(d.name) - voucher_wise_amount.append( - frappe._dict( - { - "voucher_name": d.name, - "voucher_type": doctype, - "taxable_amount": d.base_net_total, - "grand_total": d.grand_total, - } - ) + d = frappe._dict( + { + "voucher_name": d.name, + "voucher_type": doctype, + "taxable_amount": d.base_net_total, + "grand_total": d.grand_total, + "posting_date": d.posting_date, + } ) + if ldc := [x for x in ldcs if d.posting_date >= x.valid_from and d.posting_date <= x.valid_upto]: + if ldc[0].supplier in parties and ldc[0].rate == 0: + d.update({"taxable_amount": 0}) + + vouchers.append(d.voucher_name) + voucher_wise_amount.append(d) + journal_entries_details = frappe.db.sql( """ SELECT j.name, ja.credit - ja.debit AS amount, ja.reference_type From 3734289983656586fb63d2a86bf3ad11979098b1 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Fri, 7 Feb 2025 12:18:01 +0530 Subject: [PATCH 08/37] test: ldc @ 0 rate (cherry picked from commit 0cdd346f8fd2000cba7591d3b03bf0db7b69f158) # Conflicts: # erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py --- .../test_tax_withholding_category.py | 59 +++++++++++++++++-- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py b/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py index c4ab2f94581..4f527868722 100644 --- a/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py +++ b/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py @@ -6,8 +6,13 @@ import unittest import frappe from frappe.custom.doctype.custom_field.custom_field import create_custom_fields +<<<<<<< HEAD from frappe.tests.utils import FrappeTestCase, change_settings from frappe.utils import add_days, today +======= +from frappe.tests import IntegrationTestCase, UnitTestCase +from frappe.utils import add_days, add_months, today +>>>>>>> 0cdd346f8f (test: ldc @ 0 rate) from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry from erpnext.accounts.utils import get_fiscal_year @@ -666,6 +671,49 @@ class TestTaxWithholdingCategory(FrappeTestCase): pi2.cancel() pi3.cancel() + def test_ldc_at_0_rate(self): + frappe.db.set_value( + "Supplier", + "Test LDC Supplier", + { + "tax_withholding_category": "Test Service Category", + "pan": "ABCTY1234D", + }, + ) + + fiscal_year = get_fiscal_year(today(), company="_Test Company") + valid_from = fiscal_year[1] + valid_upto = add_months(valid_from, 1) + create_lower_deduction_certificate( + supplier="Test LDC Supplier", + certificate_no="1AE0423AAJ", + tax_withholding_category="Test Service Category", + tax_rate=0, + limit=50000, + valid_from=valid_from, + valid_upto=valid_upto, + ) + + pi1 = create_purchase_invoice( + supplier="Test LDC Supplier", rate=35000, posting_date=valid_from, set_posting_time=True + ) + pi1.submit() + self.assertEqual(pi1.taxes, []) + + pi2 = create_purchase_invoice( + supplier="Test LDC Supplier", + rate=35000, + posting_date=add_days(valid_upto, 1), + set_posting_time=True, + ) + pi2.submit() + self.assertEqual(len(pi2.taxes), 1) + # pi1 net total shouldn't be included as it lies within LDC at rate of '0' + self.assertEqual(pi2.taxes[0].tax_amount, 3500) + + pi1.cancel() + pi2.cancel() + def set_previous_fy_and_tax_category(self): test_company = "_Test Company" category = "Cumulative Threshold TDS" @@ -823,7 +871,8 @@ def create_purchase_invoice(**args): pi = frappe.get_doc( { "doctype": "Purchase Invoice", - "posting_date": today(), + "set_posting_time": args.set_posting_time or False, + "posting_date": args.posting_date or today(), "apply_tds": 0 if args.do_not_apply_tds else 1, "supplier": args.supplier, "company": "_Test Company", @@ -1161,7 +1210,9 @@ def create_tax_withholding_category( ).insert() -def create_lower_deduction_certificate(supplier, tax_withholding_category, tax_rate, certificate_no, limit): +def create_lower_deduction_certificate( + supplier, tax_withholding_category, tax_rate, certificate_no, limit, valid_from=None, valid_upto=None +): fiscal_year = get_fiscal_year(today(), company="_Test Company") if not frappe.db.exists("Lower Deduction Certificate", certificate_no): frappe.get_doc( @@ -1172,8 +1223,8 @@ def create_lower_deduction_certificate(supplier, tax_withholding_category, tax_r "certificate_no": certificate_no, "tax_withholding_category": tax_withholding_category, "fiscal_year": fiscal_year[0], - "valid_from": fiscal_year[1], - "valid_upto": fiscal_year[2], + "valid_from": valid_from or fiscal_year[1], + "valid_upto": valid_upto or fiscal_year[2], "rate": tax_rate, "certificate_limit": limit, } From 43d75b96c6fe25a51ac49e3c30681d62157a0b7a Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Fri, 7 Feb 2025 13:18:42 +0530 Subject: [PATCH 09/37] chore: resolve conflict --- .../test_tax_withholding_category.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py b/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py index 4f527868722..6ab6bcc08a2 100644 --- a/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py +++ b/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py @@ -6,13 +6,8 @@ import unittest import frappe from frappe.custom.doctype.custom_field.custom_field import create_custom_fields -<<<<<<< HEAD from frappe.tests.utils import FrappeTestCase, change_settings -from frappe.utils import add_days, today -======= -from frappe.tests import IntegrationTestCase, UnitTestCase from frappe.utils import add_days, add_months, today ->>>>>>> 0cdd346f8f (test: ldc @ 0 rate) from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry from erpnext.accounts.utils import get_fiscal_year From 086c36fca6e0db5abc097f82c443b843048adc8f Mon Sep 17 00:00:00 2001 From: Sugesh393 Date: Fri, 31 Jan 2025 17:49:28 +0530 Subject: [PATCH 10/37] fix: add allow_on_submit for party_balance, paid_from_account_balance and paid_to_account_balance (cherry picked from commit 707c01487e158fc16301290a48c16d2577330e56) --- erpnext/accounts/doctype/payment_entry/payment_entry.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.json b/erpnext/accounts/doctype/payment_entry/payment_entry.json index 5f191e4800a..3a0a4a8d065 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.json +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.json @@ -224,6 +224,7 @@ "label": "Accounts" }, { + "allow_on_submit": 1, "depends_on": "party", "fieldname": "party_balance", "fieldtype": "Currency", @@ -253,6 +254,7 @@ "reqd": 1 }, { + "allow_on_submit": 1, "depends_on": "paid_from", "fieldname": "paid_from_account_balance", "fieldtype": "Currency", @@ -286,6 +288,7 @@ "reqd": 1 }, { + "allow_on_submit": 1, "depends_on": "paid_to", "fieldname": "paid_to_account_balance", "fieldtype": "Currency", @@ -806,7 +809,7 @@ "table_fieldname": "payment_entries" } ], - "modified": "2025-01-13 16:03:47.169699", + "modified": "2025-01-31 17:27:28.555246", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Entry", From 757dd3f0b62c7c207a8a0e02f9ae59fffe47e6b3 Mon Sep 17 00:00:00 2001 From: l0gesh29 Date: Fri, 31 Jan 2025 16:00:00 +0530 Subject: [PATCH 11/37] feat: add repost accounting ledger entry for payment entry (cherry picked from commit 5676d60ed37937a0cda9d4bdf60eabafadadf52c) --- .../doctype/payment_entry/payment_entry.py | 21 +++++++++++++++++++ erpnext/accounts/utils.py | 2 ++ 2 files changed, 23 insertions(+) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index a63d8d87807..967b12599bf 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -25,6 +25,10 @@ from erpnext.accounts.doctype.invoice_discounting.invoice_discounting import ( get_party_account_based_on_invoice_discounting, ) from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account +from erpnext.accounts.doctype.repost_accounting_ledger.repost_accounting_ledger import ( + validate_docs_for_deferred_accounting, + validate_docs_for_voucher_types, +) from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import ( get_party_tax_withholding_details, ) @@ -114,6 +118,23 @@ class PaymentEntry(AccountsController): self.update_advance_paid() # advance_paid_status depends on the payment request amount self.set_status() + def validate_for_repost(self): + validate_docs_for_voucher_types(["Payment Entry"]) + validate_docs_for_deferred_accounting([self.name], []) + + def on_update_after_submit(self): + # Flag will be set on Reconciliation + # Reconciliation tool will anyways repost ledger entries. So, no need to check and do implicit repost. + if self.flags.get("ignore_reposting_on_reconciliation"): + return + + self.needs_repost = self.check_if_fields_updated( + fields_to_check=[], child_tables={"references": [], "taxes": [], "deductions": []} + ) + if self.needs_repost: + self.validate_for_repost() + self.repost_accounting_entries() + def set_liability_account(self): # Auto setting liability account should only be done during 'draft' status if self.docstatus > 0 or self.payment_type == "Internal Transfer": diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index b3c82e84192..db7a3a2a70f 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -773,6 +773,8 @@ def update_reference_in_payment_entry( frappe._dict({"difference_posting_date": d.difference_posting_date}), dimensions_dict ) + # Ledgers will be reposted by Reconciliation tool + payment_entry.flags.ignore_reposting_on_reconciliation = True if not do_not_save: payment_entry.save(ignore_permissions=True) return row, update_advance_paid From a649001886c57846d2053ebf0124e79144265a0f Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Mon, 10 Feb 2025 09:27:36 +0530 Subject: [PATCH 12/37] fix: not able to select the item in the sales invoice (cherry picked from commit 35388e7a04738aedff2cae423f212831fd5471ee) --- erpnext/stock/get_item_details.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index e565b5c6015..649df536f87 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -187,6 +187,9 @@ def update_stock(ctx, out, doc=None): and out.warehouse and out.stock_qty > 0 ): + if doc and isinstance(doc, dict): + doc = frappe._dict(doc) + kwargs = frappe._dict( { "item_code": ctx.item_code, From e3cceb894b2c9eef44b6c582313dbb13b7e9efea Mon Sep 17 00:00:00 2001 From: Asmita Hase Date: Fri, 7 Feb 2025 17:27:44 +0530 Subject: [PATCH 13/37] fix: unable to remove image from employee fix: employee image disappears when newly created user_id is linked to employee (cherry picked from commit 0207d2d7b69558f5a8a203a3f1036b8cd7378ac2) # Conflicts: # erpnext/setup/doctype/employee/employee.json --- erpnext/setup/doctype/employee/employee.json | 8 +++++--- erpnext/setup/doctype/employee/employee.py | 4 +--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/erpnext/setup/doctype/employee/employee.json b/erpnext/setup/doctype/employee/employee.json index 8948211b2e5..c07e14fc3be 100644 --- a/erpnext/setup/doctype/employee/employee.json +++ b/erpnext/setup/doctype/employee/employee.json @@ -182,8 +182,6 @@ "read_only": 1 }, { - "fetch_from": "user_id.user_image", - "fetch_if_empty": 1, "fieldname": "image", "fieldtype": "Attach Image", "hidden": 1, @@ -824,7 +822,11 @@ "image_field": "image", "is_tree": 1, "links": [], +<<<<<<< HEAD "modified": "2024-01-03 17:36:20.984421", +======= + "modified": "2025-02-07 13:54:40.122345", +>>>>>>> 0207d2d7b6 (fix: unable to remove image from employee) "modified_by": "Administrator", "module": "Setup", "name": "Employee", @@ -873,4 +875,4 @@ "states": [], "title_field": "employee_name", "track_changes": 1 -} +} \ No newline at end of file diff --git a/erpnext/setup/doctype/employee/employee.py b/erpnext/setup/doctype/employee/employee.py index 31568fe50dc..ad062cd6473 100755 --- a/erpnext/setup/doctype/employee/employee.py +++ b/erpnext/setup/doctype/employee/employee.py @@ -64,14 +64,12 @@ class Employee(NestedSet): def validate_user_details(self): if self.user_id: - data = frappe.db.get_value("User", self.user_id, ["enabled", "user_image"], as_dict=1) + data = frappe.db.get_value("User", self.user_id, ["enabled"], as_dict=1) if not data: self.user_id = None return - if data.get("user_image") and self.image == "": - self.image = data.get("user_image") self.validate_for_enabled_user_id(data.get("enabled", 0)) self.validate_duplicate_user_id() From 6638b391ff732cc045d1a5e45675069503718281 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Thu, 6 Feb 2025 13:47:59 +0530 Subject: [PATCH 14/37] refactor: set received amount based on paid amount (cherry picked from commit 5ff540bd82946222740ee416a02072be94645c60) --- erpnext/accounts/doctype/payment_entry/payment_entry.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js index 4a45007d50a..dd108e13e9e 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.js +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js @@ -812,6 +812,15 @@ frappe.ui.form.on("Payment Entry", { paid_amount: function (frm) { frm.set_value("base_paid_amount", flt(frm.doc.paid_amount) * flt(frm.doc.source_exchange_rate)); + let company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency; + if (!frm.doc.received_amount) { + if (frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency) { + frm.set_value("received_amount", frm.doc.paid_amount); + } else if (company_currency == frm.doc.paid_to_account_currency) { + frm.set_value("received_amount", frm.doc.base_paid_amount); + frm.set_value("base_received_amount", frm.doc.base_paid_amount); + } + } frm.trigger("reset_received_amount"); frm.events.hide_unhide_fields(frm); }, From e589c5b6efcd2baa565e625bf2ad02af066191c5 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Thu, 6 Feb 2025 14:15:24 +0530 Subject: [PATCH 15/37] refactor: set paid amount based on received amount if unset (cherry picked from commit 99e721e622ffed5967d17544b0e72bd402469b2e) --- .../doctype/payment_entry/payment_entry.js | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js index dd108e13e9e..55fab670fd8 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.js +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js @@ -826,22 +826,27 @@ frappe.ui.form.on("Payment Entry", { }, received_amount: function (frm) { + let company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency; frm.set_paid_amount_based_on_received_amount = true; - if (!frm.doc.paid_amount && frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency) { - frm.set_value("paid_amount", frm.doc.received_amount); - - if (frm.doc.target_exchange_rate) { - frm.set_value("source_exchange_rate", frm.doc.target_exchange_rate); - } - frm.set_value("base_paid_amount", frm.doc.base_received_amount); - } - frm.set_value( "base_received_amount", flt(frm.doc.received_amount) * flt(frm.doc.target_exchange_rate) ); + if (!frm.doc.paid_amount) { + if (frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency) { + frm.set_value("paid_amount", frm.doc.received_amount); + if (frm.doc.target_exchange_rate) { + frm.set_value("source_exchange_rate", frm.doc.target_exchange_rate); + } + frm.set_value("base_paid_amount", frm.doc.base_received_amount); + } else if (company_currency == frm.doc.paid_from_account_currency) { + frm.set_value("paid_amount", frm.doc.base_received_amount); + frm.set_value("base_paid_amount", frm.doc.base_received_amount); + } + } + if (frm.doc.payment_type == "Pay") frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.received_amount, true); else frm.events.set_unallocated_amount(frm); From 1d6c50c9a1946d2bfabc54f04ce345187fe77d8c Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 10 Feb 2025 10:38:18 +0530 Subject: [PATCH 16/37] chore: resolve conflict --- erpnext/setup/doctype/employee/employee.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/erpnext/setup/doctype/employee/employee.json b/erpnext/setup/doctype/employee/employee.json index c07e14fc3be..22c1ce7927a 100644 --- a/erpnext/setup/doctype/employee/employee.json +++ b/erpnext/setup/doctype/employee/employee.json @@ -822,11 +822,7 @@ "image_field": "image", "is_tree": 1, "links": [], -<<<<<<< HEAD - "modified": "2024-01-03 17:36:20.984421", -======= "modified": "2025-02-07 13:54:40.122345", ->>>>>>> 0207d2d7b6 (fix: unable to remove image from employee) "modified_by": "Administrator", "module": "Setup", "name": "Employee", From eeb322bd0e837e66d57365d5fe1669e0c9a47579 Mon Sep 17 00:00:00 2001 From: Sanket322 Date: Wed, 5 Feb 2025 17:41:07 +0530 Subject: [PATCH 17/37] fix: handle response when json is None (cherry picked from commit 133e0417b8961657f40e4692ff9a0abf2d985d21) --- erpnext/patches/v14_0/update_reports_with_range.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/patches/v14_0/update_reports_with_range.py b/erpnext/patches/v14_0/update_reports_with_range.py index 014fba883fc..ccfa4936cfd 100644 --- a/erpnext/patches/v14_0/update_reports_with_range.py +++ b/erpnext/patches/v14_0/update_reports_with_range.py @@ -27,7 +27,7 @@ def update_reference_reports(reference_report): def update_report_json(report): - report_json = json.loads(report.json) + report_json = json.loads(report.json) if report.get("json") else {} report_filter = report_json.get("filters") if not report_filter: From 6dc99f95c01f955acc132b816c5eaa91b4c535af Mon Sep 17 00:00:00 2001 From: DaizyModi Date: Thu, 6 Feb 2025 21:54:57 +0530 Subject: [PATCH 18/37] fix: Attibute error `selling_price_list` (cherry picked from commit 820b32eb8ab0aa145e008cd42e7ded376e61568c) --- erpnext/stock/get_item_details.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index 649df536f87..5c5fe5db276 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -210,7 +210,7 @@ def update_stock(ctx, out, doc=None): for batch_no, batch_qty in batches.items(): rate = get_batch_based_item_price( - {"price_list": doc.selling_price_list, "uom": out.uom, "batch_no": batch_no}, + {"price_list": doc.get("selling_price_list"), "uom": out.uom, "batch_no": batch_no}, out.item_code, ) if batch_qty >= qty: From 035758f47dcaa10e7484909eb252cf4cbb333fe6 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 16:28:59 +0530 Subject: [PATCH 19/37] fix: pos numpad editable action buttons (backport #45823) (#45826) fix: pos numpad editable action buttons (#45823) (cherry picked from commit 0b9c28620faae004fd1a88774e5cbc2687b0338a) Co-authored-by: Diptanil Saha --- erpnext/selling/page/point_of_sale/pos_item_cart.js | 2 +- 1 file changed, 1 insertion(+), 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 9de6dbbd429..dee052912ff 100644 --- a/erpnext/selling/page/point_of_sale/pos_item_cart.js +++ b/erpnext/selling/page/point_of_sale/pos_item_cart.js @@ -748,6 +748,7 @@ erpnext.PointOfSale.ItemCart = class { frappe.utils.play_sound("error"); return; } + this.highlight_numpad_btn($btn, current_action); if (first_click_event || field_to_edit_changed) { this.prev_action = current_action; @@ -793,7 +794,6 @@ erpnext.PointOfSale.ItemCart = class { this.numpad_value = current_action; } - this.highlight_numpad_btn($btn, current_action); this.events.numpad_event(this.numpad_value, this.prev_action); } From 0a4a09352aebade2a3f7be0c25210a947bf0268c Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Mon, 10 Feb 2025 19:09:02 +0530 Subject: [PATCH 20/37] fix: check_item_quality_inspection is not whitelisted --- erpnext/controllers/stock_controller.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index fd92fe104cc..a8f9976c83b 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -1564,6 +1564,7 @@ def repost_required_for_queue(doc: StockController) -> bool: return False +@frappe.whitelist() def check_item_quality_inspection(doctype, items): if isinstance(items, str): items = json.loads(items) From ea01fa135ee2ef0a467a97ba6dfb804926333f85 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 10 Feb 2025 17:15:28 +0530 Subject: [PATCH 21/37] fix: possible model sync issue (cherry picked from commit 0069581aa34ce72f17f7504d25f974a02c63b087) --- .../v15_0/sync_auto_reconcile_config.py | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/erpnext/patches/v15_0/sync_auto_reconcile_config.py b/erpnext/patches/v15_0/sync_auto_reconcile_config.py index 721364dcaa6..be92ad99536 100644 --- a/erpnext/patches/v15_0/sync_auto_reconcile_config.py +++ b/erpnext/patches/v15_0/sync_auto_reconcile_config.py @@ -11,16 +11,17 @@ def execute(): frappe.db.set_single_value("Accounts Settings", "reconciliation_queue_size", 5) # Create Scheduler Event record if it doesn't exist - method = "erpnext.accounts.doctype.process_payment_reconciliation.process_payment_reconciliation.trigger_reconciliation_for_queued_docs" - if not frappe.db.get_all( - "Scheduler Event", {"scheduled_against": "Process Payment Reconciliation", "method": method} - ): - frappe.get_doc( - { - "doctype": "Scheduler Event", - "scheduled_against": "Process Payment Reconciliation", - "method": method, - } - ).save() + if frappe.reload_doc("core", "doctype", "scheduler_event"): + method = "erpnext.accounts.doctype.process_payment_reconciliation.process_payment_reconciliation.trigger_reconciliation_for_queued_docs" + if not frappe.db.get_all( + "Scheduler Event", {"scheduled_against": "Process Payment Reconciliation", "method": method} + ): + frappe.get_doc( + { + "doctype": "Scheduler Event", + "scheduled_against": "Process Payment Reconciliation", + "method": method, + } + ).save() - sync_auto_reconcile_config(15) + sync_auto_reconcile_config(15) From e432ae98a94c7f44470d26f207ff3a2feda45a49 Mon Sep 17 00:00:00 2001 From: Sanket322 Date: Fri, 7 Feb 2025 12:37:33 +0530 Subject: [PATCH 22/37] fix: add total row in non_grouped_invoices (cherry picked from commit 2d32ddacc3397e118ab65ffa892706589b933f63) --- .../report/gross_profit/gross_profit.py | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py index 4802b0f35c1..fe17924d527 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.py +++ b/erpnext/accounts/report/gross_profit/gross_profit.py @@ -219,15 +219,34 @@ def get_data_when_grouped_by_invoice(columns, gross_profit_data, filters, group_ def get_data_when_not_grouped_by_invoice(gross_profit_data, filters, group_wise_columns, data): - for src in gross_profit_data.grouped_data: - row = [] - for col in group_wise_columns.get(scrub(filters.group_by)): - row.append(src.get(col)) + total_base_amount = 0 + total_buying_amount = 0 - row.append(filters.currency) + group_columns = group_wise_columns.get(scrub(filters.group_by)) + + for src in gross_profit_data.grouped_data: + total_base_amount += src.base_amount or 0.00 + total_buying_amount += src.buying_amount or 0.00 + + row = [src.get(col) for col in group_columns] + [filters.currency] data.append(row) + total_gross_profit = total_base_amount - total_buying_amount + currency_precision = cint(frappe.db.get_default("currency_precision")) or 3 + gross_profit_percent = (total_gross_profit / total_base_amount * 100.0) if total_base_amount else 0 + + total_row = { + group_columns[0]: "Total", + "base_amount": total_base_amount, + "buying_amount": total_buying_amount, + "gross_profit": total_gross_profit, + "gross_profit_percent": flt(gross_profit_percent, currency_precision), + } + + total_row = [total_row.get(col, None) for col in [*group_columns, "currency"]] + data.append(total_row) + def get_columns(group_wise_columns, filters): columns = [] From 6d777cdc68e21836355245c86148767add7f495b Mon Sep 17 00:00:00 2001 From: ljain112 Date: Fri, 7 Feb 2025 18:30:26 +0530 Subject: [PATCH 23/37] fix: do not validate party against Receivable and Payable account for cancelled gl entries (cherry picked from commit 0809e00455b3b94de1b3731afd096f4d77414b81) --- erpnext/accounts/doctype/gl_entry/gl_entry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py index c77a201ab51..66214cc7485 100644 --- a/erpnext/accounts/doctype/gl_entry/gl_entry.py +++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py @@ -129,7 +129,7 @@ class GLEntry(Document): if not self.get(k): frappe.throw(_("{0} is required").format(_(self.meta.get_label(k)))) - if not (self.party_type and self.party): + if not self.is_cancelled and not (self.party_type and self.party): account_type = frappe.get_cached_value("Account", self.account, "account_type") if account_type == "Receivable": frappe.throw( From b06bd825c19a5d1c1aeb3ade1a5dda65a7f2286f Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 11 Feb 2025 14:49:27 +0530 Subject: [PATCH 24/37] fix: correct amount in transaction currency for reverse gl entries (backport #45794) (#45849) fix: correct amount in tansaction currency for reverse gl entries (cherry picked from commit 6077c248b021c4123dadf3878fb071dab457a469) Co-authored-by: ljain112 --- erpnext/accounts/general_ledger.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index e5e43aefa32..7d0bf2cca11 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -680,11 +680,15 @@ def make_reverse_gl_entries( debit_in_account_currency = new_gle.get("debit_in_account_currency", 0) credit_in_account_currency = new_gle.get("credit_in_account_currency", 0) + debit_in_transaction_currency = new_gle.get("debit_in_transaction_currency", 0) + credit_in_transaction_currency = new_gle.get("credit_in_transaction_currency", 0) new_gle["debit"] = credit new_gle["credit"] = debit new_gle["debit_in_account_currency"] = credit_in_account_currency new_gle["credit_in_account_currency"] = debit_in_account_currency + new_gle["debit_in_transaction_currency"] = credit_in_transaction_currency + new_gle["credit_in_transaction_currency"] = debit_in_transaction_currency new_gle["remarks"] = "On cancellation of " + new_gle["voucher_no"] new_gle["is_cancelled"] = 1 From b112d88767a3cd98a8c9a3a2804d3f491c4c7d4a Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 11 Feb 2025 14:52:13 +0530 Subject: [PATCH 25/37] fix: map project from rfq to supplier quotation (backport #45745) (#45828) * fix: map project from rfq to supplier quotation (cherry picked from commit d0479036bbfc72b531976809e8e8c33b2fdc61e4) * fix: add project field map from mr to rfq (cherry picked from commit 8fa39bec618dd490432c88c3e6d53ca4ae232e27) --------- Co-authored-by: HenningWendtland <156231187+HenningWendtland@users.noreply.github.com> --- .../doctype/request_for_quotation/request_for_quotation.py | 6 +++++- erpnext/stock/doctype/material_request/material_request.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py index 3a71733a003..bef41394742 100644 --- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py +++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py @@ -394,7 +394,11 @@ def make_supplier_quotation_from_rfq(source_name, target_doc=None, for_supplier= }, "Request for Quotation Item": { "doctype": "Supplier Quotation Item", - "field_map": {"name": "request_for_quotation_item", "parent": "request_for_quotation"}, + "field_map": { + "name": "request_for_quotation_item", + "parent": "request_for_quotation", + "project_name": "project", + }, }, }, target_doc, diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py index f59b60a3f51..69572e661f8 100644 --- a/erpnext/stock/doctype/material_request/material_request.py +++ b/erpnext/stock/doctype/material_request/material_request.py @@ -482,7 +482,7 @@ def make_request_for_quotation(source_name, target_doc=None): "field_map": [ ["name", "material_request_item"], ["parent", "material_request"], - ["uom", "uom"], + ["project", "project_name"], ], }, }, From 2e9e355329cd69b5822d4ffa9dc5aae395e07513 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 11 Feb 2025 15:41:30 +0530 Subject: [PATCH 26/37] fix(regional): removed payment schedule validation in sales invoice for italy (backport #45852) (#45854) fix(regional): removed payment schedule validation in sales invoice for italy (#45852) (cherry picked from commit 494310293cfd896e7b6ed6a4863a0fa3e4b2aa2b) Co-authored-by: Lakshit Jain <108322669+ljain112@users.noreply.github.com> --- erpnext/regional/italy/utils.py | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/erpnext/regional/italy/utils.py b/erpnext/regional/italy/utils.py index 1e0a8805075..43ff59a1006 100644 --- a/erpnext/regional/italy/utils.py +++ b/erpnext/regional/italy/utils.py @@ -331,22 +331,19 @@ def sales_invoice_on_submit(doc, method): ]: return - if not len(doc.payment_schedule): - frappe.throw(_("Please set the Payment Schedule"), title=_("E-Invoicing Information Missing")) - else: - for schedule in doc.payment_schedule: - if not schedule.mode_of_payment: - frappe.throw( - _("Row {0}: Please set the Mode of Payment in Payment Schedule").format(schedule.idx), - title=_("E-Invoicing Information Missing"), - ) - elif not frappe.db.get_value("Mode of Payment", schedule.mode_of_payment, "mode_of_payment_code"): - frappe.throw( - _("Row {0}: Please set the correct code on Mode of Payment {1}").format( - schedule.idx, schedule.mode_of_payment - ), - title=_("E-Invoicing Information Missing"), - ) + for schedule in doc.payment_schedule: + if not schedule.mode_of_payment: + frappe.throw( + _("Row {0}: Please set the Mode of Payment in Payment Schedule").format(schedule.idx), + title=_("E-Invoicing Information Missing"), + ) + elif not frappe.db.get_value("Mode of Payment", schedule.mode_of_payment, "mode_of_payment_code"): + frappe.throw( + _("Row {0}: Please set the correct code on Mode of Payment {1}").format( + schedule.idx, schedule.mode_of_payment + ), + title=_("E-Invoicing Information Missing"), + ) prepare_and_attach_invoice(doc) From 0954aca758e73ebb9f6bc078139497377e4b4954 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 11 Feb 2025 15:42:36 +0530 Subject: [PATCH 27/37] fix: do not allow "Finance Book" in Accounting Dimensions (backport #45696) (#45856) fix: do not allow "Finance Book" in Accounting Dimensions (cherry picked from commit a44be73a98989bd53ffa6b295ac29530065e3a62) Co-authored-by: ljain112 --- .../doctype/accounting_dimension/accounting_dimension.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py index 8fc22dd7650..f8eeba84662 100644 --- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py +++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py @@ -49,6 +49,7 @@ class AccountingDimension(Document): "Accounting Dimension Detail", "Company", "Account", + "Finance Book", ): msg = _("Not allowed to create accounting dimension for {0}").format(self.document_type) frappe.throw(msg) From 435c35414fab3f259c8f1a1709037bf35dbe4056 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 11 Feb 2025 15:42:45 +0530 Subject: [PATCH 28/37] fix: Party name in Supplier Portal for Purchase Order (backport #45772) (#45858) fix: Party name in Supplier Portal for Purchase Order (cherry picked from commit fc8663421be7499dadb1019d9db7e520a8b01f6a) Co-authored-by: ljain112 --- erpnext/templates/pages/order.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/erpnext/templates/pages/order.html b/erpnext/templates/pages/order.html index 7fb5ed9b56a..315478fc649 100644 --- a/erpnext/templates/pages/order.html +++ b/erpnext/templates/pages/order.html @@ -72,8 +72,7 @@
- {%- set party_name = doc.supplier_name if doc.doctype in ['Supplier Quotation', 'Purchase Invoice', 'Purchase - Order'] else doc.customer_name %} + {%- set party_name = doc.supplier_name if doc.doctype in ['Supplier Quotation', 'Purchase Invoice', 'Purchase Order'] else doc.customer_name %} {{ party_name }} {% if doc.contact_display and doc.contact_display != party_name %} From 179cb1e6e589b9d1e60dda5243e7f5a284e9fd86 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 11 Feb 2025 16:05:42 +0530 Subject: [PATCH 29/37] fix: correct amt in account currency for lcv with manually distributed charges. (backport #45532) (#45864) fix: correct amt in account currency for lcv with manually distributed charges. (cherry picked from commit db38e7bf5a8e088578f1c84b7b095ff8abdda32f) Co-authored-by: ljain112 --- .../purchase_receipt/purchase_receipt.py | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index 44e0145ea6c..0328c447ec2 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -1360,26 +1360,25 @@ def get_item_account_wise_additional_cost(purchase_document): for item in landed_cost_voucher_doc.items: if item.receipt_document == purchase_document: for account in landed_cost_voucher_doc.taxes: + exchange_rate = account.exchange_rate or 1 item_account_wise_cost.setdefault((item.item_code, item.purchase_receipt_item), {}) item_account_wise_cost[(item.item_code, item.purchase_receipt_item)].setdefault( account.expense_account, {"amount": 0.0, "base_amount": 0.0} ) - if total_item_cost > 0: - item_account_wise_cost[(item.item_code, item.purchase_receipt_item)][ - account.expense_account - ]["amount"] += account.amount * item.get(based_on_field) / total_item_cost + item_row = item_account_wise_cost[(item.item_code, item.purchase_receipt_item)][ + account.expense_account + ] - item_account_wise_cost[(item.item_code, item.purchase_receipt_item)][ - account.expense_account - ]["base_amount"] += account.base_amount * item.get(based_on_field) / total_item_cost + if total_item_cost > 0: + item_row["amount"] += account.amount * item.get(based_on_field) / total_item_cost + + item_row["base_amount"] += ( + account.base_amount * item.get(based_on_field) / total_item_cost + ) else: - item_account_wise_cost[(item.item_code, item.purchase_receipt_item)][ - account.expense_account - ]["amount"] += item.applicable_charges - item_account_wise_cost[(item.item_code, item.purchase_receipt_item)][ - account.expense_account - ]["base_amount"] += item.applicable_charges + item_row["amount"] += item.applicable_charges / exchange_rate + item_row["base_amount"] += item.applicable_charges return item_account_wise_cost From 3b7c38da1095f246af15e91398e73a32964efbda Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Tue, 11 Feb 2025 15:58:35 +0530 Subject: [PATCH 30/37] fix: stock reco current valuation rate (cherry picked from commit 8d8f3afb39758b98a33a71189098fa4af3df385f) --- .../stock_reconciliation.py | 4 +- .../test_stock_reconciliation.py | 38 +++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py index 85c74480e7d..a9f99e177fd 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -1372,13 +1372,13 @@ def get_stock_balance_for( or 0 ) - if row.use_serial_batch_fields and row.batch_no: + if row.use_serial_batch_fields and row.batch_no and (qty or row.current_qty): rate = get_incoming_rate( frappe._dict( { "item_code": row.item_code, "warehouse": row.warehouse, - "qty": row.qty * -1, + "qty": flt(qty or row.current_qty) * -1, "batch_no": row.batch_no, "company": company, "posting_date": posting_date, diff --git a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py index 48a27a25962..77d2f7eaebb 100644 --- a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py @@ -1408,6 +1408,44 @@ class TestStockReconciliation(FrappeTestCase, StockTestMixin): self.assertTrue(sr.items[0].current_serial_and_batch_bundle) self.assertFalse(sr.items[0].serial_and_batch_bundle) + def test_stock_reco_batch_item_current_valuation(self): + from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry + + # Add new serial nos + item_code = "Stock-Reco-batch-Item-1234" + warehouse = "_Test Warehouse - _TC" + self.make_item( + item_code, + frappe._dict( + { + "is_stock_item": 1, + "has_batch_no": 1, + "create_new_batch": 1, + "batch_number_series": "JJ-SRI1234-.#####", + } + ), + ) + + se = make_stock_entry( + item_code=item_code, + target=warehouse, + qty=1, + basic_rate=100, + ) + + batch_no = get_batch_from_bundle(se.items[0].serial_and_batch_bundle) + + sr = create_stock_reconciliation( + item_code=item_code, warehouse=warehouse, qty=0, rate=100, do_not_save=1 + ) + + sr.items[0].batch_no = batch_no + sr.items[0].use_serial_batch_fields = 1 + sr.save() + self.assertEqual(sr.items[0].current_valuation_rate, 100) + self.assertEqual(sr.difference_amount, 100 * -1) + self.assertTrue(sr.items[0].qty == 0) + def create_batch_item_with_batch(item_name, batch_id): batch_item_doc = create_item(item_name, is_stock_item=1) From 1359a77e7245cef415ba5f1988b45b7e2c64f0c8 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Tue, 11 Feb 2025 13:31:24 +0530 Subject: [PATCH 31/37] fix: remove serial no if qty is zero (cherry picked from commit 3a4ae8c463de469c6deb6d67252b6f224632e202) --- .../doctype/stock_reconciliation/stock_reconciliation.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js index 85acc762969..9307eee46f1 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js @@ -295,6 +295,11 @@ frappe.ui.form.on("Stock Reconciliation Item", { qty: function (frm, cdt, cdn) { frm.events.set_amount_quantity(frm, cdt, cdn); + + let row = locals[cdt][cdn]; + if (row.use_serial_batch_fields && !row.qty && row.serial_no) { + frappe.model.set_value(cdt, cdn, "serial_no", ""); + } }, valuation_rate: function (frm, cdt, cdn) { From 4f9a7f50653109c547b4465a9bf867d11e15bf9c Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 11 Feb 2025 17:55:07 +0530 Subject: [PATCH 32/37] fix: added validation for required invoice_fields in POS (backport #45780) (#45868) * fix: added validation for required invoice_fields in POS (#45780) fix: added missing validation for required invoice_fields (cherry picked from commit b95b13ecd880a595275a795b7da45dede0756c44) # Conflicts: # erpnext/selling/page/point_of_sale/pos_payment.js * fix: resolved merge conflict --------- Co-authored-by: Diptanil Saha --- .../selling/page/point_of_sale/pos_payment.js | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/erpnext/selling/page/point_of_sale/pos_payment.js b/erpnext/selling/page/point_of_sale/pos_payment.js index 0adbf2280dc..33dd0489ba2 100644 --- a/erpnext/selling/page/point_of_sale/pos_payment.js +++ b/erpnext/selling/page/point_of_sale/pos_payment.js @@ -41,6 +41,7 @@ erpnext.PointOfSale.Payment = class { } make_invoice_fields_control() { + this.reqd_invoice_fields = []; frappe.db.get_doc("POS Settings", undefined).then((doc) => { const fields = doc.invoice_fields; if (!fields.length) return; @@ -67,6 +68,9 @@ erpnext.PointOfSale.Payment = class { }, }; } + if (df.reqd && (df.fieldtype !== "Button" || !df.read_only)) { + this.reqd_invoice_fields.push({ fieldname: df.fieldname, label: df.label }); + } this[`${df.fieldname}_field`] = frappe.ui.form.make_control({ df: { @@ -204,7 +208,11 @@ erpnext.PointOfSale.Payment = class { const paid_amount = doc.paid_amount; const items = doc.items; - if (paid_amount == 0 || !items.length) { + if (!this.validate_reqd_invoice_fields()) { + return; + } + + if (!items.length || (paid_amount == 0 && doc.additional_discount_percentage != 100)) { const message = items.length ? __("You cannot submit the order without payment.") : __("You cannot submit empty order."); @@ -620,4 +628,20 @@ erpnext.PointOfSale.Payment = class { .replace(/^[^_a-zA-Z\p{L}]+/u, "") .toLowerCase(); } + + validate_reqd_invoice_fields() { + const doc = this.events.get_frm().doc; + let validation_flag = true; + for (let field of this.reqd_invoice_fields) { + if (!doc[field.fieldname]) { + validation_flag = false; + frappe.show_alert({ + message: __("{0} is a mandatory field.", [field.label]), + indicator: "orange", + }); + frappe.utils.play_sound("error"); + } + } + return validation_flag; + } }; From a85f6f54fe5340877c1aad06afb323420807fe08 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Tue, 11 Feb 2025 22:51:17 +0530 Subject: [PATCH 33/37] fix: add precision in serial_batch_bundle.py (cherry picked from commit 4bf85d1a5a9d8a916e84205e38ad4db7c4ae2275) --- erpnext/stock/serial_batch_bundle.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/serial_batch_bundle.py b/erpnext/stock/serial_batch_bundle.py index 650c66dd408..993d918f8bc 100644 --- a/erpnext/stock/serial_batch_bundle.py +++ b/erpnext/stock/serial_batch_bundle.py @@ -1080,6 +1080,7 @@ class SerialBatchCreation: def set_serial_batch_entries(self, doc): incoming_rate = self.get("incoming_rate") + precision = frappe.get_precision("Serial and Batch Entry", "qty") if self.get("serial_nos"): serial_no_wise_batch = frappe._dict({}) if self.has_batch_no: @@ -1109,7 +1110,8 @@ class SerialBatchCreation: "entries", { "batch_no": batch_no, - "qty": batch_qty * (-1 if self.type_of_transaction == "Outward" else 1), + "qty": flt(batch_qty, precision) + * (-1 if self.type_of_transaction == "Outward" else 1), "incoming_rate": incoming_rate, }, ) From 1d3da4d49a921c40072c980c016964cdccbfef41 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Tue, 11 Feb 2025 15:32:35 +0530 Subject: [PATCH 34/37] fix: dont update rate of free item on save (cherry picked from commit 6591e76a635aa6efe1214054e964a0fca1572004) --- erpnext/controllers/accounts_controller.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 715a73e0da6..f1e98c624b5 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -821,7 +821,7 @@ class AccountsController(TransactionBase): and item.get("use_serial_batch_fields") ) ): - if fieldname == "batch_no" and not item.batch_no: + if fieldname == "batch_no" and not item.batch_no and not item.is_free_item: item.set("rate", ret.get("rate")) item.set("price_list_rate", ret.get("price_list_rate")) item.set(fieldname, value) From 48a4effdb65b016b9d0eb8066758c9577fcb0d8c Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 12 Feb 2025 09:55:20 +0530 Subject: [PATCH 35/37] fix: changed naming series to random for SABB (cherry picked from commit a007dc285d121bc3a004df19a53523e4ac7e4737) # Conflicts: # erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.json --- .../serial_and_batch_bundle.json | 18 +++++++++--------- .../serial_and_batch_bundle.py | 5 +---- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.json b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.json index 59ef43e31a8..4cb32bc3f6a 100644 --- a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.json +++ b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.json @@ -1,13 +1,12 @@ { "actions": [], - "autoname": "naming_series:", + "autoname": "hash", "creation": "2023-08-11 17:22:12.907518", "doctype": "DocType", "editable_grid": 1, "engine": "InnoDB", "field_order": [ "item_details_tab", - "naming_series", "company", "item_name", "has_serial_no", @@ -152,6 +151,7 @@ "fieldtype": "Column Break" }, { + "allow_on_submit": 1, "fieldname": "avg_rate", "fieldtype": "Float", "label": "Avg Rate", @@ -159,6 +159,7 @@ "read_only": 1 }, { + "allow_on_submit": 1, "fieldname": "total_amount", "fieldtype": "Float", "label": "Total Amount", @@ -166,6 +167,7 @@ "read_only": 1 }, { + "allow_on_submit": 1, "fieldname": "total_qty", "fieldtype": "Float", "label": "Total Qty", @@ -195,12 +197,6 @@ "reqd": 1, "search_index": 1 }, - { - "fieldname": "naming_series", - "fieldtype": "Select", - "label": "Naming Series", - "options": "SABB-.########" - }, { "default": "0", "depends_on": "eval:doc.voucher_type == \"Purchase Receipt\"", @@ -251,11 +247,15 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], +<<<<<<< HEAD "modified": "2024-03-15 15:22:24.003486", +======= + "modified": "2025-02-12 09:53:32.090309", +>>>>>>> a007dc285d (fix: changed naming series to random for SABB) "modified_by": "Administrator", "module": "Stock", "name": "Serial and Batch Bundle", - "naming_rule": "By \"Naming Series\" field", + "naming_rule": "Random", "owner": "Administrator", "permissions": [ { 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 dcd876deeb7..c37d2464ff0 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 @@ -55,9 +55,7 @@ class SerialandBatchBundle(Document): if TYPE_CHECKING: from frappe.types import DF - from erpnext.stock.doctype.serial_and_batch_entry.serial_and_batch_entry import ( - SerialandBatchEntry, - ) + from erpnext.stock.doctype.serial_and_batch_entry.serial_and_batch_entry import SerialandBatchEntry amended_from: DF.Link | None avg_rate: DF.Float @@ -70,7 +68,6 @@ class SerialandBatchBundle(Document): item_code: DF.Link item_group: DF.Link | None item_name: DF.Data | None - naming_series: DF.Literal["SABB-.########"] posting_date: DF.Date | None posting_time: DF.Time | None returned_against: DF.Data | None From 4094fbd6c5f970f0bd8d8b2a659f8b9a48fab979 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Wed, 12 Feb 2025 10:21:44 +0530 Subject: [PATCH 36/37] chore: fix conflicts --- .../serial_and_batch_bundle/serial_and_batch_bundle.json | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.json b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.json index 4cb32bc3f6a..3ff76ee818b 100644 --- a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.json +++ b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.json @@ -247,11 +247,7 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], -<<<<<<< HEAD - "modified": "2024-03-15 15:22:24.003486", -======= - "modified": "2025-02-12 09:53:32.090309", ->>>>>>> a007dc285d (fix: changed naming series to random for SABB) + "modified": "2025-02-12 10:53:32.090309", "modified_by": "Administrator", "module": "Stock", "name": "Serial and Batch Bundle", @@ -389,4 +385,4 @@ "sort_order": "DESC", "states": [], "title_field": "item_code" -} \ No newline at end of file +} From 2adab1d36f2bace8185bb761706f855a2a7b2a18 Mon Sep 17 00:00:00 2001 From: barredterra <14891507+barredterra@users.noreply.github.com> Date: Fri, 7 Feb 2025 11:43:25 +0100 Subject: [PATCH 37/37] fix: skip warning for free items (cherry picked from commit 772776ad8a91d082b66dc8c45052f703902b3691) --- erpnext/controllers/accounts_controller.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index f1e98c624b5..e75fdc126e6 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -1903,22 +1903,22 @@ class AccountsController(TransactionBase): continue ref_amt = flt(reference_details.get(item.get(item_ref_dn)), self.precision(based_on, item)) + based_on_amt = flt(item.get(based_on)) if not ref_amt: - frappe.msgprint( - _("System will not check over billing since amount for Item {0} in {1} is zero").format( - item.item_code, ref_dt - ), - title=_("Warning"), - indicator="orange", - ) + if based_on_amt: # Skip warning for free items + frappe.msgprint( + _( + "System will not check over billing since amount for Item {0} in {1} is zero" + ).format(item.item_code, ref_dt), + title=_("Warning"), + indicator="orange", + ) continue already_billed = self.get_billed_amount_for_item(item, item_ref_dn, based_on) - total_billed_amt = flt( - flt(already_billed) + flt(item.get(based_on)), self.precision(based_on, item) - ) + total_billed_amt = flt(flt(already_billed) + based_on_amt, self.precision(based_on, item)) allowance, item_allowance, global_qty_allowance, global_amount_allowance = get_allowance_for( item.item_code, item_allowance, global_qty_allowance, global_amount_allowance, "amount"