From 4fc45b035a17e9e0f755f7f02faf0f7699f11a22 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 20 Oct 2023 17:03:25 +0530 Subject: [PATCH 1/2] fix: incorrect cost center in the purchase invoice (backport #37591) (#37610) * fix: incorrect cost center in the purchase invoice (#37591) (cherry picked from commit 14b009b09355f53b1dfcd05d0f7ba918b0b25210) # Conflicts: # erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py * chore: fix conflicts --------- Co-authored-by: rohitwaghchaure --- .../purchase_invoice/test_purchase_invoice.py | 24 +++++++++++++++++++ erpnext/stock/doctype/item/test_item.py | 12 +++++++++- erpnext/stock/get_item_details.py | 6 +++++ 3 files changed, 41 insertions(+), 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 e25b8463487..d61efe1c44c 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -1626,6 +1626,30 @@ class TestPurchaseInvoice(unittest.TestCase, StockTestMixin): 0, ) + def test_default_cost_center_for_purchase(self): + from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center + + for c_center in ["_Test Cost Center Selling", "_Test Cost Center Buying"]: + create_cost_center(cost_center_name=c_center) + + item = create_item( + "_Test Cost Center Item For Purchase", + is_stock_item=1, + buying_cost_center="_Test Cost Center Buying - _TC", + selling_cost_center="_Test Cost Center Selling - _TC", + ) + + pi = make_purchase_invoice( + item=item.name, qty=1, rate=1000, update_stock=True, do_not_submit=True, cost_center="" + ) + + pi.items[0].cost_center = "" + pi.set_missing_values() + pi.calculate_taxes_and_totals() + pi.save() + + self.assertEqual(pi.items[0].cost_center, "_Test Cost Center Buying - _TC") + def check_gl_entries(doc, voucher_no, expected_gle, posting_date): gl_entries = frappe.db.sql( diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py index 3314f8c9d57..8f4bbfbf06b 100644 --- a/erpnext/stock/doctype/item/test_item.py +++ b/erpnext/stock/doctype/item/test_item.py @@ -742,6 +742,8 @@ def create_item( opening_stock=0, is_fixed_asset=0, asset_category=None, + buying_cost_center=None, + selling_cost_center=None, company="_Test Company", ): if not frappe.db.exists("Item", item_code): @@ -759,7 +761,15 @@ def create_item( item.is_purchase_item = is_purchase_item item.is_customer_provided_item = is_customer_provided_item item.customer = customer or "" - item.append("item_defaults", {"default_warehouse": warehouse, "company": company}) + item.append( + "item_defaults", + { + "default_warehouse": warehouse, + "company": company, + "selling_cost_center": selling_cost_center, + "buying_cost_center": buying_cost_center, + }, + ) item.save() else: item = frappe.get_doc("Item", item_code) diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index d2e4cd7d13a..69376b8d104 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -751,6 +751,12 @@ def get_default_cost_center(args, item=None, item_group=None, brand=None, compan data = frappe.get_attr(path)(args.get("item_code"), company) if data and (data.selling_cost_center or data.buying_cost_center): + if args.get("customer") and data.selling_cost_center: + return data.selling_cost_center + + elif args.get("supplier") and data.buying_cost_center: + return data.buying_cost_center + return data.selling_cost_center or data.buying_cost_center if not cost_center and args.get("cost_center"): From b5b51879ee021178c803e96c370402fcbc72edef Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 24 Oct 2023 08:41:41 +0530 Subject: [PATCH 2/2] fix: remove from or target warehouse for non internal transfer entries (backport #37612) (#37629) * fix: remove from or target warehouse for non internal transfer entries (#37612) (cherry picked from commit 5136fe196b4e3aab6bb18d2edf5effbfacd2b060) * chore: removed test cases * chore: removed test case --------- Co-authored-by: rohitwaghchaure --- .../sales_invoice/test_sales_invoice.py | 30 ------ erpnext/controllers/stock_controller.py | 22 +++-- .../delivery_note/test_delivery_note.py | 15 +++ .../purchase_receipt/test_purchase_receipt.py | 97 +++---------------- 4 files changed, 45 insertions(+), 119 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index 84a56404123..c0587e43ddb 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -2472,36 +2472,6 @@ class TestSalesInvoice(unittest.TestCase): self.assertEqual(target_doc.company, "_Test Company 1") self.assertEqual(target_doc.supplier, "_Test Internal Supplier") - def test_sle_for_target_warehouse(self): - se = make_stock_entry( - item_code="138-CMS Shoe", - target="Finished Goods - _TC", - company="_Test Company", - qty=1, - basic_rate=500, - ) - - si = frappe.copy_doc(test_records[0]) - si.update_stock = 1 - si.set_warehouse = "Finished Goods - _TC" - si.set_target_warehouse = "Stores - _TC" - si.get("items")[0].warehouse = "Finished Goods - _TC" - si.get("items")[0].target_warehouse = "Stores - _TC" - si.insert() - si.submit() - - sles = frappe.get_all( - "Stock Ledger Entry", filters={"voucher_no": si.name}, fields=["name", "actual_qty"] - ) - - # check if both SLEs are created - self.assertEqual(len(sles), 2) - self.assertEqual(sum(d.actual_qty for d in sles), 0.0) - - # tear down - si.cancel() - se.cancel() - def test_internal_transfer_gl_entry(self): si = create_sales_invoice( company="_Test Company with perpetual inventory", diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index cd947a8a564..c866f6d3727 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -582,13 +582,21 @@ class StockController(AccountsController): d.stock_uom_rate = d.rate / (d.conversion_factor or 1) def validate_internal_transfer(self): - if ( - self.doctype in ("Sales Invoice", "Delivery Note", "Purchase Invoice", "Purchase Receipt") - and self.is_internal_transfer() - ): - self.validate_in_transit_warehouses() - self.validate_multi_currency() - self.validate_packed_items() + if self.doctype in ("Sales Invoice", "Delivery Note", "Purchase Invoice", "Purchase Receipt"): + if self.is_internal_transfer(): + self.validate_in_transit_warehouses() + self.validate_multi_currency() + self.validate_packed_items() + else: + self.validate_internal_transfer_warehouse() + + def validate_internal_transfer_warehouse(self): + for row in self.items: + if row.get("target_warehouse"): + row.target_warehouse = None + + if row.get("from_warehouse"): + row.from_warehouse = None def validate_in_transit_warehouses(self): if ( diff --git a/erpnext/stock/doctype/delivery_note/test_delivery_note.py b/erpnext/stock/doctype/delivery_note/test_delivery_note.py index edc7b996bac..f4800b47bf8 100644 --- a/erpnext/stock/doctype/delivery_note/test_delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/test_delivery_note.py @@ -1184,6 +1184,21 @@ class TestDeliveryNote(FrappeTestCase): frappe.db.rollback() frappe.db.set_single_value("Selling Settings", "dont_reserve_sales_order_qty_on_sales_return", 0) + def non_internal_transfer_delivery_note(self): + from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse + + dn = create_delivery_note(do_not_submit=True) + warehouse = create_warehouse("Internal Transfer Warehouse", dn.company) + dn.items[0].db_set("target_warehouse", "warehouse") + + dn.reload() + + self.assertEqual(dn.items[0].target_warehouse, warehouse.name) + + dn.save() + dn.reload() + self.assertFalse(dn.items[0].target_warehouse) + def create_delivery_note(**args): dn = frappe.new_doc("Delivery Note") diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py index 6d7be972fff..983eeec3686 100644 --- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -1069,88 +1069,6 @@ class TestPurchaseReceipt(FrappeTestCase): pr1.reload() pr1.cancel() - def test_stock_transfer_from_purchase_receipt(self): - pr1 = make_purchase_receipt( - warehouse="Work In Progress - TCP1", company="_Test Company with perpetual inventory" - ) - - pr = make_purchase_receipt( - company="_Test Company with perpetual inventory", warehouse="Stores - TCP1", do_not_save=1 - ) - - pr.supplier_warehouse = "" - pr.items[0].from_warehouse = "Work In Progress - TCP1" - - pr.submit() - - gl_entries = get_gl_entries("Purchase Receipt", pr.name) - sl_entries = get_sl_entries("Purchase Receipt", pr.name) - - self.assertFalse(gl_entries) - - expected_sle = {"Work In Progress - TCP1": -5, "Stores - TCP1": 5} - - for sle in sl_entries: - self.assertEqual(expected_sle[sle.warehouse], sle.actual_qty) - - pr.cancel() - pr1.cancel() - - def test_stock_transfer_from_purchase_receipt_with_valuation(self): - create_warehouse( - "_Test Warehouse for Valuation", - company="_Test Company with perpetual inventory", - properties={"account": "_Test Account Stock In Hand - TCP1"}, - ) - - pr1 = make_purchase_receipt( - warehouse="_Test Warehouse for Valuation - TCP1", - company="_Test Company with perpetual inventory", - ) - - pr = make_purchase_receipt( - company="_Test Company with perpetual inventory", warehouse="Stores - TCP1", do_not_save=1 - ) - - pr.items[0].from_warehouse = "_Test Warehouse for Valuation - TCP1" - pr.supplier_warehouse = "" - - pr.append( - "taxes", - { - "charge_type": "On Net Total", - "account_head": "_Test Account Shipping Charges - TCP1", - "category": "Valuation and Total", - "cost_center": "Main - TCP1", - "description": "Test", - "rate": 9, - }, - ) - - pr.submit() - - gl_entries = get_gl_entries("Purchase Receipt", pr.name) - sl_entries = get_sl_entries("Purchase Receipt", pr.name) - - expected_gle = [ - ["Stock In Hand - TCP1", 272.5, 0.0], - ["_Test Account Stock In Hand - TCP1", 0.0, 250.0], - ["_Test Account Shipping Charges - TCP1", 0.0, 22.5], - ] - - expected_sle = {"_Test Warehouse for Valuation - TCP1": -5, "Stores - TCP1": 5} - - for sle in sl_entries: - self.assertEqual(expected_sle[sle.warehouse], sle.actual_qty) - - for i, gle in enumerate(gl_entries): - self.assertEqual(gle.account, expected_gle[i][0]) - self.assertEqual(gle.debit, expected_gle[i][1]) - self.assertEqual(gle.credit, expected_gle[i][2]) - - pr.cancel() - pr1.cancel() - def test_subcontracted_pr_for_multi_transfer_batches(self): from erpnext.buying.doctype.purchase_order.purchase_order import ( make_purchase_receipt, @@ -2050,6 +1968,21 @@ class TestPurchaseReceipt(FrappeTestCase): # Test - 2: Valuation Rate should be equal to Previous SLE Valuation Rate self.assertEqual(flt(sle.valuation_rate, 2), flt(previous_sle_valuation_rate, 2)) + def non_internal_transfer_purchase_receipt(self): + from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse + + pr_doc = make_purchase_receipt(do_not_submit=True) + warehouse = create_warehouse("Internal Transfer Warehouse", pr_doc.company) + pr_doc.items[0].db_set("target_warehouse", "warehouse") + + pr_doc.reload() + + self.assertEqual(pr_doc.items[0].from_warehouse, warehouse.name) + + pr_doc.save() + pr_doc.reload() + self.assertFalse(pr_doc.items[0].from_warehouse) + def prepare_data_for_internal_transfer(): from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier