diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py index 4e2b9c2a3b9221f292f25b6d85ff15363a586a56..0152a4666e773c1aa97eb26d991ef4b79b9d2559 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py @@ -494,8 +494,6 @@ class SubcontractingReceipt(SubcontractingController): return process_gl_map(gl_entries) def make_item_gl_entries(self, gl_entries, warehouse_account=None): - stock_rbnb = self.get_company_default("stock_received_but_not_billed") - warehouse_with_no_account = [] for item in self.items: @@ -513,29 +511,39 @@ class SubcontractingReceipt(SubcontractingController): "stock_value_difference", ) - warehouse_account_name = warehouse_account[item.warehouse]["account"] - warehouse_account_currency = warehouse_account[item.warehouse]["account_currency"] + accepted_warehouse_account = warehouse_account[item.warehouse]["account"] supplier_warehouse_account = warehouse_account.get(self.supplier_warehouse, {}).get("account") - supplier_warehouse_account_currency = warehouse_account.get(self.supplier_warehouse, {}).get( - "account_currency" - ) remarks = self.get("remarks") or _("Accounting Entry for Stock") - # FG Warehouse Account (Debit) + # Accepted Warehouse Account (Debit) self.add_gl_entry( gl_entries=gl_entries, - account=warehouse_account_name, + account=accepted_warehouse_account, cost_center=item.cost_center, debit=stock_value_diff, credit=0.0, remarks=remarks, - against_account=stock_rbnb, - account_currency=warehouse_account_currency, + against_account=item.expense_account, + account_currency=get_account_currency(accepted_warehouse_account), + project=item.project, + item=item, + ) + # Expense Account (Credit) + self.add_gl_entry( + gl_entries=gl_entries, + account=item.expense_account, + cost_center=item.cost_center, + debit=0.0, + credit=stock_value_diff, + remarks=remarks, + against_account=accepted_warehouse_account, + account_currency=get_account_currency(item.expense_account), + project=item.project, item=item, ) - # Supplier Warehouse Account (Credit) - if flt(item.rm_supp_cost) and warehouse_account.get(self.supplier_warehouse): + if flt(item.rm_supp_cost) and supplier_warehouse_account: + # Supplier Warehouse Account (Credit) self.add_gl_entry( gl_entries=gl_entries, account=supplier_warehouse_account, @@ -543,40 +551,64 @@ class SubcontractingReceipt(SubcontractingController): debit=0.0, credit=flt(item.rm_supp_cost), remarks=remarks, - against_account=warehouse_account_name, - account_currency=supplier_warehouse_account_currency, + against_account=item.expense_account, + account_currency=get_account_currency(supplier_warehouse_account), + project=item.project, item=item, ) - - # Expense Account (Credit) - if flt(item.service_cost_per_qty): + # Expense Account (Debit) self.add_gl_entry( gl_entries=gl_entries, account=item.expense_account, cost_center=item.cost_center, - debit=0.0, - credit=flt(item.service_cost_per_qty) * flt(item.qty), + debit=flt(item.rm_supp_cost), + credit=0.0, remarks=remarks, - against_account=warehouse_account_name, + against_account=supplier_warehouse_account, account_currency=get_account_currency(item.expense_account), + project=item.project, item=item, ) - # Loss Account (Credit) - divisional_loss = flt(item.amount - stock_value_diff, item.precision("amount")) + # Expense Account (Debit) + if item.additional_cost_per_qty: + self.add_gl_entry( + gl_entries=gl_entries, + account=item.expense_account, + cost_center=self.cost_center or self.get_company_default("cost_center"), + debit=item.qty * item.additional_cost_per_qty, + credit=0.0, + remarks=remarks, + against_account=None, + account_currency=get_account_currency(item.expense_account), + ) - if divisional_loss: - loss_account = item.expense_account + if divisional_loss := flt(item.amount - stock_value_diff, item.precision("amount")): + loss_account = self.get_company_default("stock_adjustment_account", ignore_validation=True) + # Loss Account (Credit) self.add_gl_entry( gl_entries=gl_entries, account=loss_account, cost_center=item.cost_center, + debit=0.0, + credit=divisional_loss, + remarks=remarks, + against_account=item.expense_account, + account_currency=get_account_currency(loss_account), + project=item.project, + item=item, + ) + # Expense Account (Debit) + self.add_gl_entry( + gl_entries=gl_entries, + account=item.expense_account, + cost_center=item.cost_center, debit=divisional_loss, credit=0.0, remarks=remarks, - against_account=warehouse_account_name, - account_currency=get_account_currency(loss_account), + against_account=loss_account, + account_currency=get_account_currency(item.expense_account), project=item.project, item=item, ) @@ -586,7 +618,6 @@ class SubcontractingReceipt(SubcontractingController): ): warehouse_with_no_account.append(item.warehouse) - # Additional Costs Expense Accounts (Credit) for row in self.additional_costs: credit_amount = ( flt(row.base_amount) @@ -594,6 +625,7 @@ class SubcontractingReceipt(SubcontractingController): else flt(row.amount) ) + # Additional Cost Expense Account (Credit) self.add_gl_entry( gl_entries=gl_entries, account=row.expense_account, @@ -602,6 +634,7 @@ class SubcontractingReceipt(SubcontractingController): credit=credit_amount, remarks=remarks, against_account=None, + account_currency=get_account_currency(row.expense_account), ) if warehouse_with_no_account: diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py b/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py index 1f665260fb0a77544039884ba2738760f2d00b4d..b98ea997689172363c0222efb3cf417e0220a8e7 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py @@ -10,6 +10,7 @@ from frappe.utils import add_days, cint, flt, nowtime, today import erpnext from erpnext.accounts.doctype.account.test_account import get_inventory_account +from erpnext.accounts.utils import get_company_default from erpnext.controllers.sales_and_purchase_return import make_return_doc from erpnext.controllers.tests.test_subcontracting_controller import ( get_rm_items, @@ -361,26 +362,15 @@ class TestSubcontractingReceipt(FrappeTestCase): self.assertEqual(cint(erpnext.is_perpetual_inventory_enabled(scr.company)), 1) gl_entries = get_gl_entries("Subcontracting Receipt", scr.name) - self.assertTrue(gl_entries) fg_warehouse_ac = get_inventory_account(scr.company, scr.items[0].warehouse) - supplier_warehouse_ac = get_inventory_account(scr.company, scr.supplier_warehouse) expense_account = scr.items[0].expense_account - - if fg_warehouse_ac == supplier_warehouse_ac: - expected_values = { - fg_warehouse_ac: [2100.0, 1000.0], # FG Amount (D), RM Cost (C) - expense_account: [0.0, 1000.0], # Service Cost (C) - additional_costs_expense_account: [0.0, 100.0], # Additional Cost (C) - } - else: - expected_values = { - fg_warehouse_ac: [2100.0, 0.0], # FG Amount (D) - supplier_warehouse_ac: [0.0, 1000.0], # RM Cost (C) - expense_account: [0.0, 1000.0], # Service Cost (C) - additional_costs_expense_account: [0.0, 100.0], # Additional Cost (C) - } + expected_values = { + fg_warehouse_ac: [2100.0, 1000], + expense_account: [1100, 2100], + additional_costs_expense_account: [0.0, 100.0], + } for gle in gl_entries: self.assertEqual(expected_values[gle.account][0], gle.debit) @@ -391,6 +381,53 @@ class TestSubcontractingReceipt(FrappeTestCase): self.assertTrue(get_gl_entries("Subcontracting Receipt", scr.name)) frappe.db.set_single_value("Stock Settings", "use_serial_batch_fields", 1) + @change_settings("Stock Settings", {"use_serial_batch_fields": 0}) + def test_subcontracting_receipt_with_zero_service_cost(self): + warehouse = "Stores - TCP1" + service_items = [ + { + "warehouse": warehouse, + "item_code": "Subcontracted Service Item 7", + "qty": 10, + "rate": 0, + "fg_item": "Subcontracted Item SA7", + "fg_item_qty": 10, + }, + ] + sco = get_subcontracting_order( + company="_Test Company with perpetual inventory", + warehouse=warehouse, + supplier_warehouse="Work In Progress - TCP1", + service_items=service_items, + ) + rm_items = get_rm_items(sco.supplied_items) + itemwise_details = make_stock_in_entry(rm_items=rm_items) + make_stock_transfer_entry( + sco_no=sco.name, + rm_items=rm_items, + itemwise_details=copy.deepcopy(itemwise_details), + ) + scr = make_subcontracting_receipt(sco.name) + scr.save() + scr.submit() + + gl_entries = get_gl_entries("Subcontracting Receipt", scr.name) + self.assertTrue(gl_entries) + + fg_warehouse_ac = get_inventory_account(scr.company, scr.items[0].warehouse) + expense_account = scr.items[0].expense_account + expected_values = { + fg_warehouse_ac: [1000, 1000], + expense_account: [1000, 1000], + } + + for gle in gl_entries: + self.assertEqual(expected_values[gle.account][0], gle.debit) + self.assertEqual(expected_values[gle.account][1], gle.credit) + + scr.reload() + scr.cancel() + def test_supplied_items_consumed_qty(self): # Set Backflush Based On as "Material Transferred for Subcontracting" to transfer RM's more than the required qty set_backflush_based_on("Material Transferred for Subcontract")