From 67d1709ef8e477d39c4d95e6bfb00128e570faa1 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 12 Jun 2024 12:12:58 +0530 Subject: [PATCH 01/35] fix: batch qty in the dropdown field (cherry picked from commit eb426c69fe85e27e79cadb4da7ff90b298a111de) --- erpnext/controllers/queries.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py index c57b2f3ddd6..a07a00dd03e 100644 --- a/erpnext/controllers/queries.py +++ b/erpnext/controllers/queries.py @@ -352,6 +352,7 @@ def get_batch_no(doctype, txt, searchfield, start, page_len, filters): doctype = "Batch" meta = frappe.get_meta(doctype, cached=True) searchfields = meta.get_search_fields() + page_len = 30 batches = get_batches_from_stock_ledger_entries(searchfields, txt, filters, start, page_len) batches.extend(get_batches_from_serial_and_batch_bundle(searchfields, txt, filters, start, page_len)) @@ -422,7 +423,7 @@ def get_batches_from_stock_ledger_entries(searchfields, txt, filters, start=0, p & (stock_ledger_entry.batch_no.isnotnull()) ) .groupby(stock_ledger_entry.batch_no, stock_ledger_entry.warehouse) - .having(Sum(stock_ledger_entry.actual_qty) > 0) + .having(Sum(stock_ledger_entry.actual_qty) != 0) .offset(start) .limit(page_len) ) @@ -473,7 +474,7 @@ def get_batches_from_serial_and_batch_bundle(searchfields, txt, filters, start=0 & (stock_ledger_entry.serial_and_batch_bundle.isnotnull()) ) .groupby(bundle.batch_no, bundle.warehouse) - .having(Sum(bundle.qty) > 0) + .having(Sum(bundle.qty) != 0) .offset(start) .limit(page_len) ) From ef2a6c788ee60e33798469bc7e8de436c6d4c2c5 Mon Sep 17 00:00:00 2001 From: "Nihantra C. Patel" <141945075+Nihantra-Patel@users.noreply.github.com> Date: Wed, 12 Jun 2024 12:26:40 +0530 Subject: [PATCH 02/35] fix: download materials request plan in PP (cherry picked from commit f4acdd9636dd32fcee2bc73495a1c5aa299c5baa) --- .../doctype/production_plan/production_plan.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.js b/erpnext/manufacturing/doctype/production_plan/production_plan.js index 6db901c71a4..d89ea4546c1 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.js +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.js @@ -400,13 +400,17 @@ frappe.ui.form.on("Production Plan", { }, download_materials_required(frm) { + const warehouses_data = [{ + warehouse: frm.doc.for_warehouse + }]; const fields = [ { fieldname: "warehouses", fieldtype: "Table MultiSelect", label: __("Warehouses"), - default: frm.doc.from_warehouse, + default: warehouses_data, options: "Production Plan Material Request Warehouse", + reqd: 1, get_query: function () { return { filters: { From 7193633773237105e7f461e2e589645a2bc8eab6 Mon Sep 17 00:00:00 2001 From: "Nihantra C. Patel" <141945075+Nihantra-Patel@users.noreply.github.com> Date: Wed, 12 Jun 2024 12:34:46 +0530 Subject: [PATCH 03/35] fix: download materials request plan in PP (cherry picked from commit cb52b7634215a5f580d0d01cbd0458b6a354b9ec) --- .../doctype/production_plan/production_plan.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.js b/erpnext/manufacturing/doctype/production_plan/production_plan.js index d89ea4546c1..cb3d8c3f96d 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.js +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.js @@ -400,9 +400,11 @@ frappe.ui.form.on("Production Plan", { }, download_materials_required(frm) { - const warehouses_data = [{ - warehouse: frm.doc.for_warehouse - }]; + const warehouses_data = [ + { + warehouse: frm.doc.for_warehouse + }, + ]; const fields = [ { fieldname: "warehouses", From 764235b390ba6ff0b2c794876349c6be2ac63023 Mon Sep 17 00:00:00 2001 From: Himanshu Shivhare Date: Wed, 12 Jun 2024 13:01:28 +0530 Subject: [PATCH 04/35] chore: typo in bom_operation.json (#41650) chore: typo in bom_operation.json (cherry picked from commit 7ee2a19f535010313e7be1e8c99c443446c123a6) --- .../manufacturing/doctype/bom_operation/bom_operation.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/manufacturing/doctype/bom_operation/bom_operation.json b/erpnext/manufacturing/doctype/bom_operation/bom_operation.json index 5a734d8684f..037a3fe0e81 100644 --- a/erpnext/manufacturing/doctype/bom_operation/bom_operation.json +++ b/erpnext/manufacturing/doctype/bom_operation/bom_operation.json @@ -77,7 +77,7 @@ "fieldname": "time_in_mins", "fieldtype": "Float", "in_list_view": 1, - "label": "Operation Time ", + "label": "Operation Time", "oldfieldname": "time_in_mins", "oldfieldtype": "Currency", "reqd": 1 @@ -203,4 +203,4 @@ "sort_field": "modified", "sort_order": "DESC", "states": [] -} \ No newline at end of file +} From 337082512e28bacaa292085b64dde7f5b2ec8526 Mon Sep 17 00:00:00 2001 From: "Nihantra C. Patel" <141945075+Nihantra-Patel@users.noreply.github.com> Date: Wed, 12 Jun 2024 12:36:53 +0530 Subject: [PATCH 05/35] fix: download materials request plan in PP -prettier (cherry picked from commit a1c4e0e93c7ec449c6e61d0dab8d8ee08d2deb84) --- .../manufacturing/doctype/production_plan/production_plan.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.js b/erpnext/manufacturing/doctype/production_plan/production_plan.js index cb3d8c3f96d..f57adc5db2e 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.js +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.js @@ -402,7 +402,7 @@ frappe.ui.form.on("Production Plan", { download_materials_required(frm) { const warehouses_data = [ { - warehouse: frm.doc.for_warehouse + warehouse: frm.doc.for_warehouse, }, ]; const fields = [ From 6c57971abc12fd08ca3986f10c8b78d089cbb3c4 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 12 Jun 2024 14:33:25 +0530 Subject: [PATCH 06/35] fix: return from accepted and rejected warehouse at a same time not working (cherry picked from commit 17731f09ef614537cf5dc07ad0cce6b8f918bb59) --- .../controllers/sales_and_purchase_return.py | 18 ++++++- erpnext/controllers/stock_controller.py | 9 +++- .../purchase_receipt/test_purchase_receipt.py | 49 +++++++++++++++++++ 3 files changed, 73 insertions(+), 3 deletions(-) diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py index 96af12f2340..3414b5b2520 100644 --- a/erpnext/controllers/sales_and_purchase_return.py +++ b/erpnext/controllers/sales_and_purchase_return.py @@ -936,6 +936,7 @@ def get_serial_and_batch_bundle(field, doctype, reference_ids, is_rejected=False if is_rejected: fields.extend(["rejected_serial_and_batch_bundle", "return_qty_from_rejected_warehouse"]) + del filters["rejected_serial_and_batch_bundle"] data = frappe.get_all( doctype, fields=fields, @@ -943,6 +944,9 @@ def get_serial_and_batch_bundle(field, doctype, reference_ids, is_rejected=False ) for d in data: + if not d.get("serial_and_batch_bundle") and not d.get("rejected_serial_and_batch_bundle"): + continue + if is_rejected: if d.get("return_qty_from_rejected_warehouse"): _bundle_ids.append(d.get("serial_and_batch_bundle")) @@ -1027,7 +1031,7 @@ def get_available_batch_qty(parent_doc, batch_no, warehouse): ) -def make_serial_batch_bundle_for_return(data, child_doc, parent_doc, warehouse_field=None): +def make_serial_batch_bundle_for_return(data, child_doc, parent_doc, warehouse_field=None, qty_field=None): from erpnext.stock.serial_batch_bundle import SerialBatchCreation type_of_transaction = "Outward" @@ -1037,11 +1041,21 @@ def make_serial_batch_bundle_for_return(data, child_doc, parent_doc, warehouse_f if not warehouse_field: warehouse_field = "warehouse" + if not qty_field: + qty_field = "qty" + warehouse = child_doc.get(warehouse_field) if parent_doc.get("is_internal_customer"): warehouse = child_doc.get("target_warehouse") type_of_transaction = "Outward" + if not child_doc.get(qty_field): + frappe.throw( + _("For the {0}, the quantity is required to make the return entry").format( + frappe.bold(child_doc.item_code) + ) + ) + cls_obj = SerialBatchCreation( { "type_of_transaction": type_of_transaction, @@ -1054,7 +1068,7 @@ def make_serial_batch_bundle_for_return(data, child_doc, parent_doc, warehouse_f "voucher_type": parent_doc.doctype, "voucher_no": parent_doc.name, "voucher_detail_no": child_doc.name, - "qty": child_doc.qty, + "qty": child_doc.get(qty_field), "company": parent_doc.company, "do_not_submit": True, } diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index cad9178366e..4f579fd500e 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -255,10 +255,17 @@ class StockController(AccountsController): qty_field = "qty" warehouse_field = "warehouse" + if not data.get("qty"): + frappe.throw( + _("For the {0}, no stock is available for the return in the warehouse {1}.").format( + frappe.bold(row.item_code), row.get(warehouse_field) + ) + ) + data = filter_serial_batches( self, data, row, warehouse_field=warehouse_field, qty_field=qty_field ) - bundle = make_serial_batch_bundle_for_return(data, row, self, warehouse_field) + bundle = make_serial_batch_bundle_for_return(data, row, self, warehouse_field, qty_field) if row.get("return_qty_from_rejected_warehouse"): row.db_set( { diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py index edfe8152169..88e9c94c2b1 100644 --- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -2864,6 +2864,55 @@ class TestPurchaseReceipt(FrappeTestCase): for row in sabb_doc.entries: self.assertEqual(row.incoming_rate, 0) + def test_purchase_return_from_accepted_and_rejected_warehouse(self): + from erpnext.stock.doctype.purchase_receipt.purchase_receipt import ( + make_purchase_return, + ) + + item = make_item( + "_Test PR Item With Return From Accepted and Rejected WH", + { + "is_purchase_item": 1, + "is_stock_item": 1, + "has_batch_no": 1, + "create_new_batch": 1, + "batch_number_series": "SD-TZVRFORBATCH.#####", + "valuation_rate": 200, + }, + ) + + pr = make_purchase_receipt( + qty=10, + rejected_qty=5, + rate=100, + item_code=item.name, + ) + + pr.reload() + self.assertTrue(pr.items[0].serial_and_batch_bundle) + self.assertTrue(pr.items[0].rejected_serial_and_batch_bundle) + + return_pr = make_purchase_return(pr.name) + return_pr.submit() + + return_pr.reload() + self.assertTrue(return_pr.items[0].serial_and_batch_bundle) + self.assertTrue(return_pr.items[0].rejected_serial_and_batch_bundle) + + self.assertEqual( + return_pr.items[0].qty, + frappe.db.get_value( + "Serial and Batch Bundle", return_pr.items[0].serial_and_batch_bundle, "total_qty" + ), + ) + + self.assertEqual( + return_pr.items[0].rejected_qty, + frappe.db.get_value( + "Serial and Batch Bundle", return_pr.items[0].rejected_serial_and_batch_bundle, "total_qty" + ), + ) + def prepare_data_for_internal_transfer(): from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier From 04f0c96af782d5690124f49782efedafcebddca0 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 10 Jun 2024 17:14:27 +0530 Subject: [PATCH 07/35] fix: use invoice outstanding on Dunning (#41817) (cherry picked from commit cf0a29b05f9e120a7a1e648da50164a15c6b5b4e) --- erpnext/accounts/doctype/sales_invoice/sales_invoice.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 68da9ea1657..cb0803db932 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -2678,6 +2678,10 @@ def create_dunning(source_name, target_doc=None, ignore_permissions=False): target.closing_text = letter_text.get("closing_text") target.language = letter_text.get("language") + # update outstanding + if source.payment_schedule and len(source.payment_schedule) == 1: + target.overdue_payments[0].outstanding = source.get("outstanding_amount") + target.validate() return get_mapped_doc( From 3bc5076dfc6e9c0d100c778cdee27e0f5fc2c4bf Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 12 Jun 2024 17:19:36 +0530 Subject: [PATCH 08/35] fix: allow Employee role to select Department (backport #41877) (#41881) * fix: allow Employee role to select Department (#41877) (cherry picked from commit 56082f5a2911f8f1766b504ff3b34f3ea949cf97) # Conflicts: # erpnext/setup/doctype/department/department.json * chore: fix conflicts --------- Co-authored-by: Rucha Mahabal --- erpnext/setup/doctype/department/department.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/erpnext/setup/doctype/department/department.json b/erpnext/setup/doctype/department/department.json index 99deca5c19d..fa6b9ad4a55 100644 --- a/erpnext/setup/doctype/department/department.json +++ b/erpnext/setup/doctype/department/department.json @@ -90,7 +90,7 @@ "idx": 1, "is_tree": 1, "links": [], - "modified": "2023-08-28 17:26:46.826501", + "modified": "2024-06-12 16:10:31.451257", "modified_by": "Administrator", "module": "Setup", "name": "Department", @@ -132,6 +132,10 @@ "role": "HR Manager", "share": 1, "write": 1 + }, + { + "role": "Employee", + "select": 1 } ], "show_name_in_global_search": 1, From 9cb7c279a47a2100569983ba9d938d219704f89e Mon Sep 17 00:00:00 2001 From: Kishan0330 Date: Wed, 12 Jun 2024 21:46:30 +0530 Subject: [PATCH 09/35] fix: download materials request plan in production plan (cherry picked from commit 6e55651795d7df39cc7cd2fd052809db22794d53) --- .../doctype/production_plan/production_plan.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.js b/erpnext/manufacturing/doctype/production_plan/production_plan.js index f57adc5db2e..9f7cb32c1c6 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.js +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.js @@ -400,17 +400,18 @@ frappe.ui.form.on("Production Plan", { }, download_materials_required(frm) { - const warehouses_data = [ - { - warehouse: frm.doc.for_warehouse, - }, - ]; + const warehousesData = []; + + if (frm.doc.for_warehouse) { + warehousesData.push({ warehouse: frm.doc.for_warehouse }); + } + const fields = [ { fieldname: "warehouses", fieldtype: "Table MultiSelect", label: __("Warehouses"), - default: warehouses_data, + default: warehousesData, options: "Production Plan Material Request Warehouse", reqd: 1, get_query: function () { From 164973a42cd827e289b95bfc05b0fa18ac636752 Mon Sep 17 00:00:00 2001 From: Kishan0330 Date: Wed, 12 Jun 2024 22:08:29 +0530 Subject: [PATCH 10/35] refactor: change warehousesData variable name (cherry picked from commit f4e369977a6592ffd2ed4e6c3ce7179fc4fa27a0) --- .../doctype/production_plan/production_plan.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.js b/erpnext/manufacturing/doctype/production_plan/production_plan.js index 9f7cb32c1c6..5b4ef233926 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.js +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.js @@ -400,10 +400,10 @@ frappe.ui.form.on("Production Plan", { }, download_materials_required(frm) { - const warehousesData = []; + const warehouses_data = []; if (frm.doc.for_warehouse) { - warehousesData.push({ warehouse: frm.doc.for_warehouse }); + warehouses_data.push({ warehouse: frm.doc.for_warehouse }); } const fields = [ @@ -411,7 +411,7 @@ frappe.ui.form.on("Production Plan", { fieldname: "warehouses", fieldtype: "Table MultiSelect", label: __("Warehouses"), - default: warehousesData, + default: warehouses_data, options: "Production Plan Material Request Warehouse", reqd: 1, get_query: function () { From 5ea2cdcaad1787fbbbb1da297012f0ceec5d2e62 Mon Sep 17 00:00:00 2001 From: ljain112 Date: Mon, 10 Jun 2024 20:06:05 +0530 Subject: [PATCH 11/35] fix: regional overide for updating item valution (cherry picked from commit 1a10f0bcbd0d9d19e9267a0715b3a5e69c77f2c3) --- erpnext/controllers/buying_controller.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index 14bf8ad7436..bf6e3cd663a 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -8,6 +8,7 @@ from frappe.contacts.doctype.address.address import render_address from frappe.utils import cint, flt, getdate from frappe.utils.data import nowtime +import erpnext from erpnext.accounts.doctype.budget.budget import validate_expense_against_budget from erpnext.accounts.party import get_party_details from erpnext.buying.utils import update_last_purchase_rate, validate_for_items @@ -332,6 +333,8 @@ class BuyingController(SubcontractingController): else: item.valuation_rate = 0.0 + update_regional_item_valuation_rate(self) + def set_incoming_rate(self): if self.doctype not in ("Purchase Receipt", "Purchase Invoice", "Purchase Order"): return @@ -935,3 +938,8 @@ def validate_item_type(doc, fieldname, message): ).format(items, message) frappe.throw(error_message) + + +@erpnext.allow_regional +def update_regional_item_valuation_rate(doc): + pass From 83ccb32be68c55b050e6b1993da2d9a8af5d7c67 Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Thu, 29 Feb 2024 09:04:24 +0530 Subject: [PATCH 12/35] fix: add LCV flag to determine negative expenses (cherry picked from commit baa3fee1bf9ce814a889ecf264fb6bac4ebaf93c) # Conflicts: # erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py --- erpnext/controllers/stock_controller.py | 4 +-- .../landed_cost_voucher.py | 5 ++++ .../purchase_receipt/purchase_receipt.py | 27 +++++++++---------- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index 4f579fd500e..bc8778b4505 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -97,7 +97,7 @@ class StockController(AccountsController): ) ) - def make_gl_entries(self, gl_entries=None, from_repost=False): + def make_gl_entries(self, gl_entries=None, from_repost=False, via_landed_cost_voucher=False): if self.docstatus == 2: make_reverse_gl_entries(voucher_type=self.doctype, voucher_no=self.name) @@ -118,7 +118,7 @@ class StockController(AccountsController): if self.docstatus == 1: if not gl_entries: - gl_entries = self.get_gl_entries(warehouse_account) + gl_entries = self.get_gl_entries(warehouse_account, via_landed_cost_voucher) make_gl_entries(gl_entries, from_repost=from_repost) def validate_serialized_batch(self): diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py index 683e946298a..da974c73999 100644 --- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py +++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py @@ -252,8 +252,13 @@ class LandedCostVoucher(Document): doc.docstatus = 1 doc.make_bundle_using_old_serial_batch_fields(via_landed_cost_voucher=True) doc.update_stock_ledger(allow_negative_stock=True, via_landed_cost_voucher=True) +<<<<<<< HEAD doc.make_gl_entries() doc.repost_future_sle_and_gle(via_landed_cost_voucher=True) +======= + doc.make_gl_entries(via_landed_cost_voucher=True) + doc.repost_future_sle_and_gle() +>>>>>>> baa3fee1bf (fix: add LCV flag to determine negative expenses) def validate_asset_qty_and_status(self, receipt_document_type, receipt_document): for item in self.get("items"): diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index 0742ba3b590..6a00fed5588 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -422,13 +422,13 @@ class PurchaseReceipt(BuyingController): self.delete_auto_created_batches() self.set_consumed_qty_in_subcontract_order() - def get_gl_entries(self, warehouse_account=None): + def get_gl_entries(self, warehouse_account=None, via_landed_cost_voucher=False): from erpnext.accounts.general_ledger import process_gl_map gl_entries = [] self.make_item_gl_entries(gl_entries, warehouse_account=warehouse_account) - self.make_tax_gl_entries(gl_entries) + self.make_tax_gl_entries(gl_entries, via_landed_cost_voucher) update_regional_gl_entries(gl_entries, self) return process_gl_map(gl_entries) @@ -776,7 +776,7 @@ class PurchaseReceipt(BuyingController): posting_date=posting_date, ) - def make_tax_gl_entries(self, gl_entries): + def make_tax_gl_entries(self, gl_entries, via_landed_cost_voucher=False): negative_expense_to_be_booked = sum([flt(d.item_tax_amount) for d in self.get("items")]) is_asset_pr = any(d.is_fixed_asset for d in self.get("items")) # Cost center-wise amount breakup for other charges included for valuation @@ -811,18 +811,17 @@ class PurchaseReceipt(BuyingController): i = 1 for tax in self.get("taxes"): if valuation_tax.get(tax.name): - negative_expense_booked_in_pi = frappe.db.sql( - """select name from `tabPurchase Invoice Item` pi - where docstatus = 1 and purchase_receipt=%s - and exists(select name from `tabGL Entry` where voucher_type='Purchase Invoice' - and voucher_no=pi.parent and account=%s)""", - (self.name, tax.account_head), - ) - - if negative_expense_booked_in_pi: - account = stock_rbnb - else: + if via_landed_cost_voucher: account = tax.account_head + else: + negative_expense_booked_in_pi = frappe.db.sql( + """select name from `tabPurchase Invoice Item` pi + where docstatus = 1 and purchase_receipt=%s + and exists(select name from `tabGL Entry` where voucher_type='Purchase Invoice' + and voucher_no=pi.parent and account=%s)""", + (self.name, tax.account_head), + ) + account = stock_rbnb if negative_expense_booked_in_pi else tax.account_head if i == len(valuation_tax): applicable_amount = amount_including_divisional_loss From c7c9d33954b78a8b0f3926cf3daa99bc382cd215 Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Thu, 29 Feb 2024 11:26:31 +0530 Subject: [PATCH 13/35] test: LCV entries after billing (cherry picked from commit 53642e7417c54197ba526625902d2671a7a564c2) # Conflicts: # erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py --- erpnext/controllers/stock_controller.py | 6 +- .../purchase_receipt/test_purchase_receipt.py | 69 +++++++++++++++++-- 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index bc8778b4505..212c9adf4af 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -118,7 +118,11 @@ class StockController(AccountsController): if self.docstatus == 1: if not gl_entries: - gl_entries = self.get_gl_entries(warehouse_account, via_landed_cost_voucher) + gl_entries = ( + self.get_gl_entries(warehouse_account, via_landed_cost_voucher) + if self.doctype == "Purchase Receipt" + else self.get_gl_entries(warehouse_account) + ) make_gl_entries(gl_entries, from_repost=from_repost) def validate_serialized_batch(self): diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py index 88e9c94c2b1..497dd331f7a 100644 --- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -2426,6 +2426,7 @@ class TestPurchaseReceipt(FrappeTestCase): pr.reload() self.assertEqual(pr.per_billed, 100) +<<<<<<< HEAD def test_purchase_receipt_with_use_serial_batch_field_for_rejected_qty(self): batch_item = make_item( "_Test Purchase Receipt Batch Item For Rejected Qty", @@ -2912,6 +2913,50 @@ class TestPurchaseReceipt(FrappeTestCase): "Serial and Batch Bundle", return_pr.items[0].rejected_serial_and_batch_bundle, "total_qty" ), ) +======= + def test_valuation_taxes_lcv_repost_after_billing(self): + from erpnext.stock.doctype.landed_cost_voucher.test_landed_cost_voucher import ( + make_landed_cost_voucher, + ) + + company = frappe.get_doc("Company", "_Test Company") + company.enable_perpetual_inventory = 1 + company.default_inventory_account = "Stock In Hand - _TC" + company.stock_received_but_not_billed = "Stock Received But Not Billed - _TC" + company.save() + + pr = make_purchase_receipt(qty=10, rate=1000, do_not_submit=1) + pr.append( + "taxes", + { + "category": "Valuation and Total", + "charge_type": "Actual", + "account_head": "Freight and Forwarding Charges - _TC", + "tax_amount": 2000, + "description": "Test", + }, + ) + pr.submit() + pi = make_purchase_invoice(pr.name) + pi.submit() + lcv = make_landed_cost_voucher( + company=pr.company, + receipt_document_type="Purchase Receipt", + receipt_document=pr.name, + charges=2000, + distribute_charges_based_on="Qty", + expense_account="Expenses Included In Valuation - _TC", + ) + + gl_entries = get_gl_entries("Purchase Receipt", pr.name, skip_cancelled=True, as_dict=False) + expected_gle = ( + ("Stock Received But Not Billed - _TC", 0, 10000, "Main - _TC"), + ("Stock In Hand - _TC", 14000, 0, "Main - _TC"), + ("Freight and Forwarding Charges - _TC", 0, 2000, "Main - _TC"), + ("Expenses Included In Valuation - _TC", 0, 2000, "Main - _TC"), + ) + self.assertSequenceEqual(expected_gle, gl_entries) +>>>>>>> 53642e7417 (test: LCV entries after billing) def prepare_data_for_internal_transfer(): @@ -2959,14 +3004,24 @@ def get_sl_entries(voucher_type, voucher_no): ) -def get_gl_entries(voucher_type, voucher_no): - return frappe.db.sql( - """select account, debit, credit, cost_center, is_cancelled - from `tabGL Entry` where voucher_type=%s and voucher_no=%s - order by account desc""", - (voucher_type, voucher_no), - as_dict=1, +def get_gl_entries(voucher_type, voucher_no, skip_cancelled=False, as_dict=True): + gl = frappe.qb.DocType("GL Entry") + gl_query = ( + frappe.qb.from_(gl) + .select( + gl.account, + gl.debit, + gl.credit, + gl.cost_center, + ) + .where((gl.voucher_type == voucher_type) & (gl.voucher_no == voucher_no)) + .orderby(gl.account, order=frappe.qb.desc) ) + if skip_cancelled: + gl_query = gl_query.where(gl.is_cancelled == 0) + else: + gl_query = gl_query.select(gl.is_cancelled) + return gl_query.run(as_dict=as_dict) def get_taxes(**args): From 8618402829d9553ddc0c7d7ac41d86147ab2a84d Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Thu, 29 Feb 2024 11:58:14 +0530 Subject: [PATCH 14/35] fix: parameters for PI references (cherry picked from commit 8b3d46610eacd27edbceaefff6452efb68a83365) # Conflicts: # erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py # erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py --- .../doctype/landed_cost_voucher/landed_cost_voucher.py | 7 +++++++ .../doctype/purchase_receipt/test_purchase_receipt.py | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py index da974c73999..70874af677b 100644 --- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py +++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py @@ -252,11 +252,18 @@ class LandedCostVoucher(Document): doc.docstatus = 1 doc.make_bundle_using_old_serial_batch_fields(via_landed_cost_voucher=True) doc.update_stock_ledger(allow_negative_stock=True, via_landed_cost_voucher=True) +<<<<<<< HEAD <<<<<<< HEAD doc.make_gl_entries() doc.repost_future_sle_and_gle(via_landed_cost_voucher=True) ======= doc.make_gl_entries(via_landed_cost_voucher=True) +======= + if d.receipt_document_type == "Purchase Receipt": + doc.make_gl_entries(via_landed_cost_voucher=True) + else: + doc.make_gl_entries() +>>>>>>> 8b3d46610e (fix: parameters for PI references) doc.repost_future_sle_and_gle() >>>>>>> baa3fee1bf (fix: add LCV flag to determine negative expenses) diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py index 497dd331f7a..30b72a96c7d 100644 --- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -2956,7 +2956,11 @@ class TestPurchaseReceipt(FrappeTestCase): ("Expenses Included In Valuation - _TC", 0, 2000, "Main - _TC"), ) self.assertSequenceEqual(expected_gle, gl_entries) +<<<<<<< HEAD >>>>>>> 53642e7417 (test: LCV entries after billing) +======= + frappe.db.rollback() +>>>>>>> 8b3d46610e (fix: parameters for PI references) def prepare_data_for_internal_transfer(): From 4c11f2bff23102eff34146baa15521218e31b77a Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Thu, 29 Feb 2024 13:04:01 +0530 Subject: [PATCH 15/35] fix: reset perpetual inventory flag after test (cherry picked from commit 0b36cbe307fec68f72ddfdfdeee401134887a884) # Conflicts: # erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py --- .../purchase_receipt/test_purchase_receipt.py | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py index 30b72a96c7d..a7a54f4f5c2 100644 --- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -9,6 +9,7 @@ from pypika import functions as fn import erpnext from erpnext.accounts.doctype.account.test_account import get_inventory_account from erpnext.controllers.buying_controller import QtyMismatchError +from erpnext.stock import get_warehouse_account_map from erpnext.stock.doctype.item.test_item import create_item, make_item from erpnext.stock.doctype.purchase_receipt.purchase_receipt import make_purchase_invoice from erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle import ( @@ -1681,7 +1682,6 @@ class TestPurchaseReceipt(FrappeTestCase): frappe.db.set_single_value("Stock Settings", "over_delivery_receipt_allowance", 0) def test_internal_pr_gl_entries(self): - from erpnext.stock import get_warehouse_account_map from erpnext.stock.doctype.delivery_note.delivery_note import make_inter_company_purchase_receipt from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry @@ -2919,11 +2919,14 @@ class TestPurchaseReceipt(FrappeTestCase): make_landed_cost_voucher, ) - company = frappe.get_doc("Company", "_Test Company") - company.enable_perpetual_inventory = 1 - company.default_inventory_account = "Stock In Hand - _TC" - company.stock_received_but_not_billed = "Stock Received But Not Billed - _TC" - company.save() + old_perpetual_inventory = erpnext.is_perpetual_inventory_enabled("_Test Company") + frappe.local.enable_perpetual_inventory["_Test Company"] = 1 + frappe.db.set_value( + "Company", + "_Test Company", + "stock_received_but_not_billed", + "Stock Received But Not Billed - _TC", + ) pr = make_purchase_receipt(qty=10, rate=1000, do_not_submit=1) pr.append( @@ -2939,7 +2942,7 @@ class TestPurchaseReceipt(FrappeTestCase): pr.submit() pi = make_purchase_invoice(pr.name) pi.submit() - lcv = make_landed_cost_voucher( + make_landed_cost_voucher( company=pr.company, receipt_document_type="Purchase Receipt", receipt_document=pr.name, @@ -2949,18 +2952,23 @@ class TestPurchaseReceipt(FrappeTestCase): ) gl_entries = get_gl_entries("Purchase Receipt", pr.name, skip_cancelled=True, as_dict=False) + warehouse_account = get_warehouse_account_map("_Test Company") expected_gle = ( ("Stock Received But Not Billed - _TC", 0, 10000, "Main - _TC"), - ("Stock In Hand - _TC", 14000, 0, "Main - _TC"), ("Freight and Forwarding Charges - _TC", 0, 2000, "Main - _TC"), ("Expenses Included In Valuation - _TC", 0, 2000, "Main - _TC"), + (warehouse_account[pr.items[0].warehouse]["account"], 14000, 0, "Main - _TC"), ) self.assertSequenceEqual(expected_gle, gl_entries) <<<<<<< HEAD +<<<<<<< HEAD >>>>>>> 53642e7417 (test: LCV entries after billing) ======= frappe.db.rollback() >>>>>>> 8b3d46610e (fix: parameters for PI references) +======= + frappe.local.enable_perpetual_inventory["_Test Company"] = old_perpetual_inventory +>>>>>>> 0b36cbe307 (fix: reset perpetual inventory flag after test) def prepare_data_for_internal_transfer(): From 248e9cac712afbaf92302f11f8baa9ec420fbf3a Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Sun, 21 Apr 2024 19:07:08 +0530 Subject: [PATCH 16/35] chore: resolve conflicts (cherry picked from commit 54a58e9205af43f4aabe1668e8d8cf925a226536) # Conflicts: # erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py --- .../stock/doctype/landed_cost_voucher/landed_cost_voucher.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py index 70874af677b..0d15338c37c 100644 --- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py +++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py @@ -263,9 +263,13 @@ class LandedCostVoucher(Document): doc.make_gl_entries(via_landed_cost_voucher=True) else: doc.make_gl_entries() +<<<<<<< HEAD >>>>>>> 8b3d46610e (fix: parameters for PI references) doc.repost_future_sle_and_gle() >>>>>>> baa3fee1bf (fix: add LCV flag to determine negative expenses) +======= + doc.repost_future_sle_and_gle(via_landed_cost_voucher=True) +>>>>>>> 54a58e9205 (chore: resolve conflicts) def validate_asset_qty_and_status(self, receipt_document_type, receipt_document): for item in self.get("items"): From b577d95ecd9893313258b69ed67297e32aea7c40 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Sun, 16 Jun 2024 20:47:55 +0530 Subject: [PATCH 17/35] chore: resolve conflicts --- .../landed_cost_voucher/landed_cost_voucher.py | 13 ------------- .../purchase_receipt/test_purchase_receipt.py | 11 +---------- 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py index 0d15338c37c..eb84fdbc7c0 100644 --- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py +++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py @@ -252,24 +252,11 @@ class LandedCostVoucher(Document): doc.docstatus = 1 doc.make_bundle_using_old_serial_batch_fields(via_landed_cost_voucher=True) doc.update_stock_ledger(allow_negative_stock=True, via_landed_cost_voucher=True) -<<<<<<< HEAD -<<<<<<< HEAD - doc.make_gl_entries() - doc.repost_future_sle_and_gle(via_landed_cost_voucher=True) -======= - doc.make_gl_entries(via_landed_cost_voucher=True) -======= if d.receipt_document_type == "Purchase Receipt": doc.make_gl_entries(via_landed_cost_voucher=True) else: doc.make_gl_entries() -<<<<<<< HEAD ->>>>>>> 8b3d46610e (fix: parameters for PI references) - doc.repost_future_sle_and_gle() ->>>>>>> baa3fee1bf (fix: add LCV flag to determine negative expenses) -======= doc.repost_future_sle_and_gle(via_landed_cost_voucher=True) ->>>>>>> 54a58e9205 (chore: resolve conflicts) def validate_asset_qty_and_status(self, receipt_document_type, receipt_document): for item in self.get("items"): diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py index a7a54f4f5c2..42747818d2b 100644 --- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -2426,7 +2426,6 @@ class TestPurchaseReceipt(FrappeTestCase): pr.reload() self.assertEqual(pr.per_billed, 100) -<<<<<<< HEAD def test_purchase_receipt_with_use_serial_batch_field_for_rejected_qty(self): batch_item = make_item( "_Test Purchase Receipt Batch Item For Rejected Qty", @@ -2913,7 +2912,7 @@ class TestPurchaseReceipt(FrappeTestCase): "Serial and Batch Bundle", return_pr.items[0].rejected_serial_and_batch_bundle, "total_qty" ), ) -======= + def test_valuation_taxes_lcv_repost_after_billing(self): from erpnext.stock.doctype.landed_cost_voucher.test_landed_cost_voucher import ( make_landed_cost_voucher, @@ -2960,15 +2959,7 @@ class TestPurchaseReceipt(FrappeTestCase): (warehouse_account[pr.items[0].warehouse]["account"], 14000, 0, "Main - _TC"), ) self.assertSequenceEqual(expected_gle, gl_entries) -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> 53642e7417 (test: LCV entries after billing) -======= - frappe.db.rollback() ->>>>>>> 8b3d46610e (fix: parameters for PI references) -======= frappe.local.enable_perpetual_inventory["_Test Company"] = old_perpetual_inventory ->>>>>>> 0b36cbe307 (fix: reset perpetual inventory flag after test) def prepare_data_for_internal_transfer(): From b64b4330a34b14b6d544cc18fb0bab8a5c622ce3 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Mon, 17 Jun 2024 10:15:54 +0530 Subject: [PATCH 18/35] fix: incorrect batch return from sales return (cherry picked from commit 317047c8085a253f41741a18d8a4496ffdebe972) --- .../controllers/sales_and_purchase_return.py | 3 + .../delivery_note/test_delivery_note.py | 104 ++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py index 3414b5b2520..b61d1773a67 100644 --- a/erpnext/controllers/sales_and_purchase_return.py +++ b/erpnext/controllers/sales_and_purchase_return.py @@ -883,6 +883,9 @@ def get_serial_batches_based_on_bundle(field, _bundle_ids): if frappe.get_cached_value(row.voucher_type, row.voucher_no, "is_return"): key = frappe.get_cached_value(row.voucher_type + " Item", row.voucher_detail_no, field) + if row.voucher_type in ["Sales Invoice", "Delivery Note"]: + row.qty = -1 * row.qty + if key not in available_dict: available_dict[key] = frappe._dict( {"qty": 0.0, "serial_nos": defaultdict(float), "batches": defaultdict(float)} diff --git a/erpnext/stock/doctype/delivery_note/test_delivery_note.py b/erpnext/stock/doctype/delivery_note/test_delivery_note.py index 5ebcc795fa0..f24c912e362 100644 --- a/erpnext/stock/doctype/delivery_note/test_delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/test_delivery_note.py @@ -1814,6 +1814,110 @@ class TestDeliveryNote(FrappeTestCase): self.assertEqual(sle_data.actual_qty, 1 * -1) self.assertEqual(sle_data.stock_value_difference, 200.0 * -1) + def test_sales_return_batch_no_for_batched_item_in_dn(self): + from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_return + + item_code = make_item( + "Test Batched Item for Sales Return 11", + properties={ + "has_batch_no": 1, + "create_new_batch": 1, + "batch_number_series": "B11-TESTBATCH.#####", + "is_stock_item": 1, + }, + ).name + + se = make_stock_entry(item_code=item_code, target="_Test Warehouse - _TC", qty=5, basic_rate=100) + + batch_no = get_batch_from_bundle(se.items[0].serial_and_batch_bundle) + dn = create_delivery_note( + item_code=item_code, + qty=5, + rate=500, + use_serial_batch_fields=0, + batch_no=batch_no, + ) + + dn_return = make_sales_return(dn.name) + dn_return.save().submit() + returned_batch_no = get_batch_from_bundle(dn_return.items[0].serial_and_batch_bundle) + self.assertEqual(batch_no, returned_batch_no) + + def test_partial_sales_return_batch_no_for_batched_item_in_dn(self): + from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_return + + item_code = make_item( + "Test Partial Batched Item for Sales Return 11", + properties={ + "has_batch_no": 1, + "create_new_batch": 1, + "batch_number_series": "BPART11-TESTBATCH.#####", + "is_stock_item": 1, + }, + ).name + + se = make_stock_entry(item_code=item_code, target="_Test Warehouse - _TC", qty=5, basic_rate=100) + + batch_no = get_batch_from_bundle(se.items[0].serial_and_batch_bundle) + dn = create_delivery_note( + item_code=item_code, + qty=5, + rate=500, + use_serial_batch_fields=0, + batch_no=batch_no, + ) + + dn_return = make_sales_return(dn.name) + dn_return.items[0].qty = 3 * -1 + dn_return.save().submit() + + returned_batch_no = get_batch_from_bundle(dn_return.items[0].serial_and_batch_bundle) + self.assertEqual(batch_no, returned_batch_no) + sabb_qty = frappe.db.get_value( + "Serial and Batch Bundle", dn_return.items[0].serial_and_batch_bundle, "total_qty" + ) + self.assertEqual(sabb_qty, 3) + + dn_return = make_sales_return(dn.name) + dn_return.items[0].qty = 2 * -1 + dn_return.save().submit() + + returned_batch_no = get_batch_from_bundle(dn_return.items[0].serial_and_batch_bundle) + self.assertEqual(batch_no, returned_batch_no) + + sabb_qty = frappe.db.get_value( + "Serial and Batch Bundle", dn_return.items[0].serial_and_batch_bundle, "total_qty" + ) + self.assertEqual(sabb_qty, 2) + + def test_sales_return_serial_no_for_serial_item_in_dn(self): + from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_return + + item_code = make_item( + "Test Serial Item for Sales Return 11", + properties={ + "has_serial_no": 1, + "serial_no_series": "SNN11-TESTBATCH.#####", + "is_stock_item": 1, + }, + ).name + + se = make_stock_entry(item_code=item_code, target="_Test Warehouse - _TC", qty=5, basic_rate=100) + + serial_nos = get_serial_nos_from_bundle(se.items[0].serial_and_batch_bundle) + dn = create_delivery_note( + item_code=item_code, + qty=5, + rate=500, + use_serial_batch_fields=0, + serial_no=serial_nos, + ) + + dn_return = make_sales_return(dn.name) + dn_return.save().submit() + returned_serial_nos = get_serial_nos_from_bundle(dn_return.items[0].serial_and_batch_bundle) + self.assertEqual(serial_nos, returned_serial_nos) + def create_delivery_note(**args): dn = frappe.new_doc("Delivery Note") From 4551b4b63820852fd23b76fe98defb46f52d8039 Mon Sep 17 00:00:00 2001 From: Nihantra Patel Date: Fri, 14 Jun 2024 12:39:45 +0530 Subject: [PATCH 19/35] fix: update received qty in MR on purchase invoice submit with update stock (cherry picked from commit 13cb53fa899104ee519c13fe4289e9ea0baf0581) # Conflicts: # erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json --- .../purchase_invoice/purchase_invoice.py | 13 +++++++++ .../purchase_invoice_item.json | 28 +++++++++++++++++++ .../purchase_invoice_item.py | 2 ++ .../doctype/purchase_order/purchase_order.py | 2 ++ 4 files changed, 45 insertions(+) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index df54a63b661..fba60cef632 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -683,6 +683,19 @@ class PurchaseInvoice(BuyingController): where name=`tabPurchase Invoice Item`.parent and update_stock = 1)""", } ) + self.status_updater.append( + { + "source_dt": "Purchase Invoice Item", + "target_dt": "Material Request Item", + "join_field": "material_request_item", + "target_field": "received_qty", + "target_parent_dt": "Material Request", + "target_parent_field": "per_received", + "target_ref_field": "stock_qty", + "source_field": "stock_qty", + "percent_join_field": "material_request", + } + ) if cint(self.is_return): self.status_updater.append( { diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json index 66df76a3af0..d783478a2cc 100644 --- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json +++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json @@ -105,6 +105,8 @@ "purchase_receipt", "pr_detail", "sales_invoice_item", + "material_request", + "material_request_item", "item_weight_details", "weight_per_unit", "total_weight", @@ -934,12 +936,38 @@ { "fieldname": "column_break_vbbb", "fieldtype": "Column Break" + }, + { + "fieldname": "material_request", + "fieldtype": "Link", + "label": "Material Request", + "no_copy": 1, + "options": "Material Request", + "print_hide": 1, + "read_only": 1, + "search_index": 1 + }, + { + "fieldname": "material_request_item", + "fieldtype": "Data", + "hidden": 1, + "label": "Material Request Item", + "no_copy": 1, + "oldfieldname": "pr_detail", + "oldfieldtype": "Data", + "print_hide": 1, + "read_only": 1, + "search_index": 1 } ], "idx": 1, "istable": 1, "links": [], +<<<<<<< HEAD "modified": "2024-03-19 19:09:47.210965", +======= + "modified": "2024-06-14 11:57:07.171700", +>>>>>>> 13cb53fa89 (fix: update received qty in MR on purchase invoice submit with update stock) "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice Item", diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.py b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.py index ccbc34749d7..baeece4815c 100644 --- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.py +++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.py @@ -52,6 +52,8 @@ class PurchaseInvoiceItem(Document): manufacturer_part_no: DF.Data | None margin_rate_or_amount: DF.Float margin_type: DF.Literal["", "Percentage", "Amount"] + material_request: DF.Link | None + material_request_item: DF.Data | None net_amount: DF.Currency net_rate: DF.Currency page_break: DF.Check diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py index d1f19841ac5..a280724193d 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/purchase_order.py @@ -794,6 +794,8 @@ def get_mapped_purchase_invoice(source_name, target_doc=None, ignore_permissions "field_map": { "name": "po_detail", "parent": "purchase_order", + "material_request": "material_request", + "material_request_item": "material_request_item", "wip_composite_asset": "wip_composite_asset", }, "postprocess": update_item, From 125d97a182e2e8feebf1bbfc64d9b81234034507 Mon Sep 17 00:00:00 2001 From: Nihantra Patel Date: Fri, 14 Jun 2024 16:44:26 +0530 Subject: [PATCH 20/35] fix: add test case for update received qty in MR (cherry picked from commit ebb0cef601e29cdaca3b5698d624bafbc6a8afcc) --- .../purchase_invoice/test_purchase_invoice.py | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index 3ea88f195d8..8abb089f56a 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -31,6 +31,8 @@ from erpnext.stock.doctype.serial_and_batch_bundle.test_serial_and_batch_bundle ) from erpnext.stock.doctype.stock_entry.test_stock_entry import get_qty_after_transaction from erpnext.stock.tests.test_utils import StockTestMixin +from erpnext.stock.doctype.material_request.test_material_request import make_material_request +from erpnext.stock.doctype.material_request.material_request import make_purchase_order test_dependencies = ["Item", "Cost Center", "Payment Term", "Payment Terms Template"] test_ignore = ["Serial No"] @@ -72,6 +74,32 @@ class TestPurchaseInvoice(FrappeTestCase, StockTestMixin): # teardown pi.delete() + def test_update_received_qty_in_material_request(self): + from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_invoice + """ + Test if the received_qty in Material Request is updated correctly when + a Purchase Invoice with update_stock=True is submitted. + """ + mr = make_material_request(item_code="_Test Item", qty=10) + mr.save() + mr.submit() + frappe.db.commit() + po = make_purchase_order(mr.name) + po.supplier = "_Test Supplier" + po.save() + po.submit() + + # Create a Purchase Invoice with update_stock=True + pi = make_purchase_invoice(po.name) + pi.update_stock = True + pi.insert() + pi.submit() + frappe.db.commit() + + # Check if the received quantity is updated in Material Request + mr.reload() + self.assertEqual(mr.items[0].received_qty, 10) + def test_gl_entries_without_perpetual_inventory(self): frappe.db.set_value("Company", "_Test Company", "round_off_account", "Round Off - _TC") pi = frappe.copy_doc(test_records[0]) From aaee02835b4104bfc79771a877d1da1b7b3f1543 Mon Sep 17 00:00:00 2001 From: Nihantra Patel Date: Fri, 14 Jun 2024 16:46:23 +0530 Subject: [PATCH 21/35] fix: add test case for update received qty in MR (cherry picked from commit cff105015901af0f5b18497e8110ae394d49f1c6) --- .../accounts/doctype/purchase_invoice/test_purchase_invoice.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index 8abb089f56a..cd3eda99b07 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -83,7 +83,6 @@ class TestPurchaseInvoice(FrappeTestCase, StockTestMixin): mr = make_material_request(item_code="_Test Item", qty=10) mr.save() mr.submit() - frappe.db.commit() po = make_purchase_order(mr.name) po.supplier = "_Test Supplier" po.save() @@ -94,7 +93,6 @@ class TestPurchaseInvoice(FrappeTestCase, StockTestMixin): pi.update_stock = True pi.insert() pi.submit() - frappe.db.commit() # Check if the received quantity is updated in Material Request mr.reload() From 858058c9e1ba457af9a10db041756ad91f7c53ab Mon Sep 17 00:00:00 2001 From: Nihantra Patel Date: Fri, 14 Jun 2024 16:47:30 +0530 Subject: [PATCH 22/35] fix: add test case for update received qty in MR (cherry picked from commit 62e4e88f1d60cdd6865b77df41a0bba9c0a4f8eb) --- .../doctype/purchase_invoice/test_purchase_invoice.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index cd3eda99b07..179d580298e 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -17,6 +17,8 @@ from erpnext.controllers.buying_controller import QtyMismatchError from erpnext.exceptions import InvalidCurrency from erpnext.projects.doctype.project.test_project import make_project from erpnext.stock.doctype.item.test_item import create_item +from erpnext.stock.doctype.material_request.test_material_request import make_material_request +from erpnext.stock.doctype.material_request.material_request import make_purchase_order from erpnext.stock.doctype.purchase_receipt.purchase_receipt import ( make_purchase_invoice as create_purchase_invoice_from_receipt, ) @@ -31,8 +33,6 @@ from erpnext.stock.doctype.serial_and_batch_bundle.test_serial_and_batch_bundle ) from erpnext.stock.doctype.stock_entry.test_stock_entry import get_qty_after_transaction from erpnext.stock.tests.test_utils import StockTestMixin -from erpnext.stock.doctype.material_request.test_material_request import make_material_request -from erpnext.stock.doctype.material_request.material_request import make_purchase_order test_dependencies = ["Item", "Cost Center", "Payment Term", "Payment Terms Template"] test_ignore = ["Serial No"] From 21596c6c23a66e6bcf976b368082c1384b831ccf Mon Sep 17 00:00:00 2001 From: Nihantra Patel Date: Fri, 14 Jun 2024 16:50:04 +0530 Subject: [PATCH 23/35] fix: add test case for update received qty in MR - import sorter (cherry picked from commit 73f22ba9a00eeffc444a23fb9b0fa80c05741e24) --- .../accounts/doctype/purchase_invoice/test_purchase_invoice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index 179d580298e..a7e30e2eb9e 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -17,8 +17,8 @@ from erpnext.controllers.buying_controller import QtyMismatchError from erpnext.exceptions import InvalidCurrency from erpnext.projects.doctype.project.test_project import make_project from erpnext.stock.doctype.item.test_item import create_item -from erpnext.stock.doctype.material_request.test_material_request import make_material_request from erpnext.stock.doctype.material_request.material_request import make_purchase_order +from erpnext.stock.doctype.material_request.test_material_request import make_material_request from erpnext.stock.doctype.purchase_receipt.purchase_receipt import ( make_purchase_invoice as create_purchase_invoice_from_receipt, ) From 084658e8ff6c5decea94baf7babda52603301223 Mon Sep 17 00:00:00 2001 From: Nihantra Patel Date: Fri, 14 Jun 2024 16:50:49 +0530 Subject: [PATCH 24/35] fix: add test case for update received qty in MR - import sorter (cherry picked from commit 77959596db8a2002e54224e6ad1bf1a5fc9f7e6c) --- .../accounts/doctype/purchase_invoice/test_purchase_invoice.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index a7e30e2eb9e..3c3b081fa2f 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -76,6 +76,7 @@ class TestPurchaseInvoice(FrappeTestCase, StockTestMixin): def test_update_received_qty_in_material_request(self): from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_invoice + """ Test if the received_qty in Material Request is updated correctly when a Purchase Invoice with update_stock=True is submitted. From 7e9f6aee58459b6894678e999ba5d373d1b2c14b Mon Sep 17 00:00:00 2001 From: "Nihantra C. Patel" <141945075+Nihantra-Patel@users.noreply.github.com> Date: Mon, 17 Jun 2024 11:39:42 +0530 Subject: [PATCH 25/35] fix: update received qty in MR on purchase invoice submit with update stock --- .../purchase_invoice_item/purchase_invoice_item.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json index d783478a2cc..1d7b0c2f461 100644 --- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json +++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json @@ -963,11 +963,7 @@ "idx": 1, "istable": 1, "links": [], -<<<<<<< HEAD - "modified": "2024-03-19 19:09:47.210965", -======= "modified": "2024-06-14 11:57:07.171700", ->>>>>>> 13cb53fa89 (fix: update received qty in MR on purchase invoice submit with update stock) "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice Item", @@ -977,4 +973,4 @@ "sort_field": "modified", "sort_order": "DESC", "states": [] -} \ No newline at end of file +} From c159e3b06f86b16cbf6ff8b2e28060451e1454f0 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Mon, 17 Jun 2024 12:48:33 +0530 Subject: [PATCH 26/35] fix: duplicate rows fetching in RFQ (cherry picked from commit 555510c128a2f13181c4b27475bf7326f232ab34) --- erpnext/public/js/utils.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js index fcb541f71a8..a7d88edcafa 100755 --- a/erpnext/public/js/utils.js +++ b/erpnext/public/js/utils.js @@ -933,7 +933,13 @@ erpnext.utils.map_current_doc = function (opts) { frappe.msgprint(__("Please select {0}", [opts.source_doctype])); return; } - opts.source_name = values; + + if (values.constructor === Array) { + opts.source_name = [...new Set(values)]; + } else { + opts.source_name = values; + } + if ( opts.allow_child_item_selection || ["Purchase Receipt", "Delivery Note"].includes(opts.source_doctype) From 98c8feded034f5d23e939bb53aed2935ddac5179 Mon Sep 17 00:00:00 2001 From: Nihantra Patel Date: Mon, 17 Jun 2024 12:33:14 +0530 Subject: [PATCH 27/35] fix: item_code filter in item-wise sales-purchase register (cherry picked from commit 757aef397235707b2a6341c9c0a11070fa647842) --- .../item_wise_purchase_register.py | 5 ++++- .../item_wise_sales_register/item_wise_sales_register.js | 6 ++++++ .../item_wise_sales_register/item_wise_sales_register.py | 5 ++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py index 80c246cad55..a75473b165d 100644 --- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py +++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py @@ -289,7 +289,7 @@ def get_columns(additional_table_columns, filters): def apply_conditions(query, pi, pii, filters): - for opts in ("company", "supplier", "item_code", "mode_of_payment"): + for opts in ("company", "supplier", "mode_of_payment"): if filters.get(opts): query = query.where(pi[opts] == filters[opts]) @@ -299,6 +299,9 @@ def apply_conditions(query, pi, pii, filters): if filters.get("to_date"): query = query.where(pi.posting_date <= filters.get("to_date")) + if filters.get("item_code"): + query = query.where(pii.item_code == filters.get("item_code")) + if filters.get("item_group"): query = query.where(pii.item_group == filters.get("item_group")) diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js index 1f155de63a0..16a97733393 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js @@ -54,6 +54,12 @@ frappe.query_reports["Item-wise Sales Register"] = { fieldtype: "Link", options: "Brand", }, + { + fieldname: "item_code", + label: __("Item"), + fieldtype: "Link", + options: "Item", + }, { fieldname: "item_group", label: __("Item Group"), diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py index cd50b118715..cf08e45c537 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py @@ -342,7 +342,7 @@ def get_columns(additional_table_columns, filters): def apply_conditions(query, si, sii, filters, additional_conditions=None): - for opts in ("company", "customer", "item_code"): + for opts in ("company", "customer"): if filters.get(opts): query = query.where(si[opts] == filters[opts]) @@ -371,6 +371,9 @@ def apply_conditions(query, si, sii, filters, additional_conditions=None): if filters.get("brand"): query = query.where(sii.brand == filters.get("brand")) + if filters.get("item_code"): + query = query.where(sii.item_code == filters.get("item_code")) + if filters.get("item_group"): query = query.where(sii.item_group == filters.get("item_group")) From a43c181673d57fa095e5dd3c6e027628089353c8 Mon Sep 17 00:00:00 2001 From: ljain112 Date: Mon, 17 Jun 2024 14:30:31 +0530 Subject: [PATCH 28/35] fix: consistent query field name in item wise purchase register with item wise sales register (cherry picked from commit 6d539e0fc068a8386a8aad30d146765185d25ba3) --- .../item_wise_purchase_register/item_wise_purchase_register.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py index a75473b165d..1cd9b872a9b 100644 --- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py +++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py @@ -325,7 +325,7 @@ def get_items(filters, additional_table_columns): .left_join(Item) .on(pii.item_code == Item.name) .select( - pii.name.as_("pii_name"), + pii.name, pii.parent, pi.posting_date, pi.credit_to, From ceafa0ce282cc41cb00a9c8f302a87166ea03595 Mon Sep 17 00:00:00 2001 From: ljain112 Date: Mon, 17 Jun 2024 12:32:17 +0530 Subject: [PATCH 29/35] fix: handle NoneType error where customer details are not available in sales register (cherry picked from commit f876fec6f5602744dd1b879ec7abe4c039e162a8) --- erpnext/accounts/report/sales_register/sales_register.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/report/sales_register/sales_register.py b/erpnext/accounts/report/sales_register/sales_register.py index f27569531b1..6c0bf91e3f8 100644 --- a/erpnext/accounts/report/sales_register/sales_register.py +++ b/erpnext/accounts/report/sales_register/sales_register.py @@ -80,6 +80,7 @@ def _execute(filters, additional_table_columns=None): delivery_note = list(set(invoice_so_dn_map.get(inv.name, {}).get("delivery_note", []))) cost_center = list(set(invoice_cc_wh_map.get(inv.name, {}).get("cost_center", []))) warehouse = list(set(invoice_cc_wh_map.get(inv.name, {}).get("warehouse", []))) + inv_customer_details = customer_details.get(inv.customer, {}) row = { "voucher_type": inv.doctype, @@ -88,9 +89,9 @@ def _execute(filters, additional_table_columns=None): "customer": inv.customer, "customer_name": inv.customer_name, **get_values_for_columns(additional_table_columns, inv), - "customer_group": customer_details.get(inv.customer).get("customer_group"), - "territory": customer_details.get(inv.customer).get("territory"), - "tax_id": customer_details.get(inv.customer).get("tax_id"), + "customer_group": inv_customer_details.get("customer_group"), + "territory": inv_customer_details.get("territory"), + "tax_id": inv_customer_details.get("tax_id"), "receivable_account": inv.debit_to, "mode_of_payment": ", ".join(mode_of_payments.get(inv.name, [])), "project": inv.project, From f4852d472a6eba10db722ef8ef0d73ec8c5a2931 Mon Sep 17 00:00:00 2001 From: mahsem <137205921+mahsem@users.noreply.github.com> Date: Fri, 14 Jun 2024 15:40:08 +0200 Subject: [PATCH 30/35] fix: add strings for translation in pos_item_cart.js fix: add strings for translation in pos_item_cart.js (cherry picked from commit 2fb3e5da4a252061d566d025447cf47572371282) --- erpnext/selling/page/point_of_sale/pos_item_cart.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 fbee9c16267..694f70d4db5 100644 --- a/erpnext/selling/page/point_of_sale/pos_item_cart.js +++ b/erpnext/selling/page/point_of_sale/pos_item_cart.js @@ -857,7 +857,7 @@ erpnext.PointOfSale.ItemCart = class { }); this.$customer_section.find(".customer-details").html( `
-
Contact Details
+
${__("Contact Details")}
@@ -877,7 +877,7 @@ erpnext.PointOfSale.ItemCart = class {
-
Recent Transactions
` +
${__("Recent Transactions")}
` ); // transactions need to be in diff div from sticky elem for scrolling this.$customer_section.append(`
`); From 794ade832f66d9e347d5dd7ab9c0c48eef5aea86 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Mon, 17 Jun 2024 16:51:46 +0530 Subject: [PATCH 31/35] fix: reposting validation related PCV (cherry picked from commit 194f1dc67431c4b823289c9603de51d78a40dda8) --- .../repost_item_valuation.py | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py index d8b44765251..40767704f4e 100644 --- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py +++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py @@ -77,7 +77,7 @@ class RepostItemValuation(Document): def validate_period_closing_voucher(self): # Period Closing Voucher - year_end_date = self.get_max_year_end_date(self.company) + year_end_date = self.get_max_period_closing_date(self.company) if year_end_date and getdate(self.posting_date) <= getdate(year_end_date): date = frappe.format(year_end_date, "Date") msg = f"Due to period closing, you cannot repost item valuation before {date}" @@ -120,24 +120,16 @@ class RepostItemValuation(Document): return frappe.get_all("Closing Stock Balance", fields=["name", "to_date"], filters=filters) @staticmethod - def get_max_year_end_date(company): - data = frappe.get_all( - "Period Closing Voucher", fields=["fiscal_year"], filters={"docstatus": 1, "company": company} - ) - - if not data: - return - - fiscal_years = [d.fiscal_year for d in data] - table = frappe.qb.DocType("Fiscal Year") + def get_max_period_closing_date(company): + table = frappe.qb.DocType("Period Closing Voucher") query = ( frappe.qb.from_(table) - .select(Max(table.year_end_date)) - .where((table.name.isin(fiscal_years)) & (table.disabled == 0)) + .select(Max(table.posting_date)) + .where((table.company == company) & (table.docstatus == 1)) ).run() - return query[0][0] if query else None + return query[0][0] if query and query[0][0] else None def validate_accounts_freeze(self): acc_settings = frappe.db.get_value( From 7cc5579ecaae99336b8164e7aeedc15b990d2257 Mon Sep 17 00:00:00 2001 From: ljain112 Date: Fri, 14 Jun 2024 13:13:11 +0530 Subject: [PATCH 32/35] refactor: ignore unreconcile doc for PO and SO on cancel/delete (cherry picked from commit b618d685c62837657fe808d6c30dc3582a12d0ec) --- erpnext/buying/doctype/purchase_order/purchase_order.js | 1 + erpnext/buying/doctype/purchase_order/purchase_order.py | 8 +++++++- erpnext/selling/doctype/sales_order/sales_order.js | 6 +++++- erpnext/selling/doctype/sales_order/sales_order.py | 8 +++++++- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index cf383021b06..bd92ebef3d7 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -12,6 +12,7 @@ erpnext.buying.setup_buying_controller(); frappe.ui.form.on("Purchase Order", { setup: function (frm) { + frm.ignore_doctypes_on_cancel_all = ["Unreconcile Payment", "Unreconcile Payment Entries"]; if (frm.doc.is_old_subcontracting_flow) { frm.set_query("reserve_warehouse", "supplied_items", function () { return { diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py index a280724193d..0508483a0fc 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/purchase_order.py @@ -484,7 +484,13 @@ class PurchaseOrder(BuyingController): self.auto_create_subcontracting_order() def on_cancel(self): - self.ignore_linked_doctypes = ("GL Entry", "Payment Ledger Entry") + self.ignore_linked_doctypes = ( + "GL Entry", + "Payment Ledger Entry", + "Unreconcile Payment", + "Unreconcile Payment Entries", + ) + super().on_cancel() if self.is_against_so(): diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js index d903f7eedf5..5885d092cce 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.js +++ b/erpnext/selling/doctype/sales_order/sales_order.js @@ -217,7 +217,11 @@ frappe.ui.form.on("Sales Order", { frm.set_value("advance_paid", 0); } - frm.ignore_doctypes_on_cancel_all = ["Purchase Order"]; + frm.ignore_doctypes_on_cancel_all = [ + "Purchase Order", + "Unreconcile Payment", + "Unreconcile Payment Entries", + ]; }, delivery_date: function (frm) { diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index e5e67ed38b7..af67f07a360 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -421,7 +421,13 @@ class SalesOrder(SellingController): self.create_stock_reservation_entries() def on_cancel(self): - self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry", "Payment Ledger Entry") + self.ignore_linked_doctypes = ( + "GL Entry", + "Stock Ledger Entry", + "Payment Ledger Entry", + "Unreconcile Payment", + "Unreconcile Payment Entries", + ) super().on_cancel() # Cannot cancel closed SO From 5663432bd838e7ef2673c7e4cede6f014a4fff1a Mon Sep 17 00:00:00 2001 From: barredterra <14891507+barredterra@users.noreply.github.com> Date: Sun, 12 May 2024 23:01:19 +0200 Subject: [PATCH 33/35] fix: migrate lead notes (cherry picked from commit 382d0ff45300fe6e92d1c535b8e6126d5e4057c3) --- .../migrate_existing_lead_notes_as_per_the_new_format.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/erpnext/patches/v14_0/migrate_existing_lead_notes_as_per_the_new_format.py b/erpnext/patches/v14_0/migrate_existing_lead_notes_as_per_the_new_format.py index ec72527552c..d740a5b9c8e 100644 --- a/erpnext/patches/v14_0/migrate_existing_lead_notes_as_per_the_new_format.py +++ b/erpnext/patches/v14_0/migrate_existing_lead_notes_as_per_the_new_format.py @@ -9,15 +9,13 @@ def execute(): dt = frappe.qb.DocType(doctype) records = ( - frappe.qb.from_(dt) - .select(dt.name, dt.notes, dt.modified_by, dt.modified) - .where(dt.notes.isnotnull() & dt.notes != "") + frappe.qb.from_(dt).select(dt.name, dt.notes).where(dt.notes.isnotnull() & dt.notes != "") ).run(as_dict=True) for d in records: if strip_html(cstr(d.notes)).strip(): doc = frappe.get_doc(doctype, d.name) - doc.append("notes", {"note": d.notes, "added_by": d.modified_by, "added_on": d.modified}) + doc.append("notes", {"note": d.notes}) doc.update_child_table("notes") frappe.db.sql_ddl(f"alter table `tab{doctype}` drop column `notes`") From 24ee765e6a3edc7a9e45c249e3ed1cc012cfb549 Mon Sep 17 00:00:00 2001 From: barredterra <14891507+barredterra@users.noreply.github.com> Date: Fri, 14 Jun 2024 17:47:02 +0200 Subject: [PATCH 34/35] fix: only show user and date if available (cherry picked from commit 895aede5907cd949ae4d93521705e3144e31dfd5) --- erpnext/public/js/templates/crm_notes.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/erpnext/public/js/templates/crm_notes.html b/erpnext/public/js/templates/crm_notes.html index 53df9330784..a20e6c2723c 100644 --- a/erpnext/public/js/templates/crm_notes.html +++ b/erpnext/public/js/templates/crm_notes.html @@ -12,6 +12,7 @@ {% for(var i=0, l=notes.length; i
+ {% if (notes[i].added_by && notes[i].added_on) %}
{{ frappe.avatar(notes[i].added_by) }} @@ -25,6 +26,7 @@
+ {% } %}
{{ notes[i].note }} From cd1db37c74b542c7bfd148fa181237d2d5ea689b Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Wed, 19 Jun 2024 11:25:02 +0530 Subject: [PATCH 35/35] chore: fix linter --- erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py index 37756533f44..42747818d2b 100644 --- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -2961,6 +2961,7 @@ class TestPurchaseReceipt(FrappeTestCase): self.assertSequenceEqual(expected_gle, gl_entries) frappe.local.enable_perpetual_inventory["_Test Company"] = old_perpetual_inventory + def prepare_data_for_internal_transfer(): from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier from erpnext.selling.doctype.customer.test_customer import create_internal_customer