mirror of
https://github.com/frappe/erpnext.git
synced 2026-03-25 06:02:09 +01:00
This commit is contained in:
@@ -10,6 +10,10 @@ import erpnext
|
|||||||
from erpnext.accounts.utils import get_account_currency
|
from erpnext.accounts.utils import get_account_currency
|
||||||
from erpnext.buying.utils import check_on_hold_or_closed_status
|
from erpnext.buying.utils import check_on_hold_or_closed_status
|
||||||
from erpnext.controllers.subcontracting_controller import SubcontractingController
|
from erpnext.controllers.subcontracting_controller import SubcontractingController
|
||||||
|
from erpnext.setup.doctype.brand.brand import get_brand_defaults
|
||||||
|
from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
|
||||||
|
from erpnext.stock.doctype.item.item import get_item_defaults
|
||||||
|
from erpnext.stock.get_item_details import get_default_cost_center, get_default_expense_account
|
||||||
from erpnext.stock.stock_ledger import get_valuation_rate
|
from erpnext.stock.stock_ledger import get_valuation_rate
|
||||||
|
|
||||||
|
|
||||||
@@ -140,6 +144,9 @@ class SubcontractingReceipt(SubcontractingController):
|
|||||||
self.reset_default_field_value("rejected_warehouse", "items", "rejected_warehouse")
|
self.reset_default_field_value("rejected_warehouse", "items", "rejected_warehouse")
|
||||||
self.get_current_stock()
|
self.get_current_stock()
|
||||||
|
|
||||||
|
self.set_supplied_items_expense_account()
|
||||||
|
self.set_supplied_items_cost_center()
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
self.validate_closed_subcontracting_order()
|
self.validate_closed_subcontracting_order()
|
||||||
self.validate_available_qty_for_consumption()
|
self.validate_available_qty_for_consumption()
|
||||||
@@ -224,6 +231,17 @@ class SubcontractingReceipt(SubcontractingController):
|
|||||||
if not item.cost_center:
|
if not item.cost_center:
|
||||||
item.cost_center = cost_center
|
item.cost_center = cost_center
|
||||||
|
|
||||||
|
def set_supplied_items_cost_center(self):
|
||||||
|
for item in self.supplied_items:
|
||||||
|
if not item.cost_center:
|
||||||
|
item.cost_center = get_default_cost_center(
|
||||||
|
{"project": self.project},
|
||||||
|
get_item_defaults(item.rm_item_code, self.company),
|
||||||
|
get_item_group_defaults(item.rm_item_code, self.company),
|
||||||
|
get_brand_defaults(item.rm_item_code, self.company),
|
||||||
|
self.company,
|
||||||
|
)
|
||||||
|
|
||||||
def set_items_expense_account(self):
|
def set_items_expense_account(self):
|
||||||
if self.company:
|
if self.company:
|
||||||
expense_account = self.get_company_default("default_expense_account", ignore_validation=True)
|
expense_account = self.get_company_default("default_expense_account", ignore_validation=True)
|
||||||
@@ -232,6 +250,22 @@ class SubcontractingReceipt(SubcontractingController):
|
|||||||
if not item.expense_account:
|
if not item.expense_account:
|
||||||
item.expense_account = expense_account
|
item.expense_account = expense_account
|
||||||
|
|
||||||
|
def set_supplied_items_expense_account(self):
|
||||||
|
for item in self.supplied_items:
|
||||||
|
if not item.expense_account:
|
||||||
|
item.expense_account = get_default_expense_account(
|
||||||
|
frappe._dict(
|
||||||
|
{
|
||||||
|
"expense_account": self.get_company_default(
|
||||||
|
"default_expense_account", ignore_validation=True
|
||||||
|
)
|
||||||
|
}
|
||||||
|
),
|
||||||
|
get_item_defaults(item.rm_item_code, self.company),
|
||||||
|
get_item_group_defaults(item.rm_item_code, self.company),
|
||||||
|
get_brand_defaults(item.rm_item_code, self.company),
|
||||||
|
)
|
||||||
|
|
||||||
def reset_supplied_items(self):
|
def reset_supplied_items(self):
|
||||||
if (
|
if (
|
||||||
frappe.db.get_single_value("Buying Settings", "backflush_raw_materials_of_subcontract_based_on")
|
frappe.db.get_single_value("Buying Settings", "backflush_raw_materials_of_subcontract_based_on")
|
||||||
@@ -519,6 +553,18 @@ class SubcontractingReceipt(SubcontractingController):
|
|||||||
def make_item_gl_entries(self, gl_entries, warehouse_account=None):
|
def make_item_gl_entries(self, gl_entries, warehouse_account=None):
|
||||||
warehouse_with_no_account = []
|
warehouse_with_no_account = []
|
||||||
|
|
||||||
|
supplied_items_details = frappe._dict()
|
||||||
|
for item in self.supplied_items:
|
||||||
|
supplied_items_details.setdefault(item.reference_name, []).append(
|
||||||
|
frappe._dict(
|
||||||
|
{
|
||||||
|
"amount": item.amount,
|
||||||
|
"expense_account": item.expense_account,
|
||||||
|
"cost_center": item.cost_center,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
for item in self.items:
|
for item in self.items:
|
||||||
if flt(item.rate) and flt(item.qty):
|
if flt(item.rate) and flt(item.qty):
|
||||||
if warehouse_account.get(item.warehouse):
|
if warehouse_account.get(item.warehouse):
|
||||||
@@ -568,32 +614,33 @@ class SubcontractingReceipt(SubcontractingController):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if flt(item.rm_supp_cost) and supplier_warehouse_account:
|
if flt(item.rm_supp_cost) and supplier_warehouse_account:
|
||||||
# Supplier Warehouse Account (Credit)
|
for rm_item in supplied_items_details.get(item.name):
|
||||||
self.add_gl_entry(
|
# Supplier Warehouse Account (Credit)
|
||||||
gl_entries=gl_entries,
|
self.add_gl_entry(
|
||||||
account=supplier_warehouse_account,
|
gl_entries=gl_entries,
|
||||||
cost_center=item.cost_center,
|
account=supplier_warehouse_account,
|
||||||
debit=0.0,
|
cost_center=rm_item.cost_center,
|
||||||
credit=flt(item.rm_supp_cost),
|
debit=0.0,
|
||||||
remarks=remarks,
|
credit=flt(rm_item.amount),
|
||||||
against_account=item.expense_account,
|
remarks=remarks,
|
||||||
account_currency=get_account_currency(supplier_warehouse_account),
|
against_account=rm_item.expense_account,
|
||||||
project=item.project,
|
account_currency=get_account_currency(supplier_warehouse_account),
|
||||||
item=item,
|
project=item.project,
|
||||||
)
|
item=item,
|
||||||
# Expense Account (Debit)
|
)
|
||||||
self.add_gl_entry(
|
# Expense Account (Debit)
|
||||||
gl_entries=gl_entries,
|
self.add_gl_entry(
|
||||||
account=item.expense_account,
|
gl_entries=gl_entries,
|
||||||
cost_center=item.cost_center,
|
account=rm_item.expense_account,
|
||||||
debit=flt(item.rm_supp_cost),
|
cost_center=rm_item.cost_center,
|
||||||
credit=0.0,
|
debit=flt(rm_item.amount),
|
||||||
remarks=remarks,
|
credit=0.0,
|
||||||
against_account=supplier_warehouse_account,
|
remarks=remarks,
|
||||||
account_currency=get_account_currency(item.expense_account),
|
against_account=supplier_warehouse_account,
|
||||||
project=item.project,
|
account_currency=get_account_currency(item.expense_account),
|
||||||
item=item,
|
project=item.project,
|
||||||
)
|
item=item,
|
||||||
|
)
|
||||||
|
|
||||||
# Expense Account (Debit)
|
# Expense Account (Debit)
|
||||||
if item.additional_cost_per_qty:
|
if item.additional_cost_per_qty:
|
||||||
|
|||||||
@@ -372,6 +372,56 @@ class TestSubcontractingReceipt(FrappeTestCase):
|
|||||||
self.assertTrue(get_gl_entries("Subcontracting Receipt", scr.name))
|
self.assertTrue(get_gl_entries("Subcontracting Receipt", scr.name))
|
||||||
frappe.db.set_single_value("Stock Settings", "use_serial_batch_fields", 1)
|
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_gl_entry_with_different_rm_expense_accounts(self):
|
||||||
|
service_items = [
|
||||||
|
{
|
||||||
|
"warehouse": "Stores - TCP1",
|
||||||
|
"item_code": "Subcontracted Service Item 7",
|
||||||
|
"qty": 10,
|
||||||
|
"rate": 100,
|
||||||
|
"fg_item": "Subcontracted Item SA4",
|
||||||
|
"fg_item_qty": 10,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
sco = get_subcontracting_order(
|
||||||
|
company="_Test Company with perpetual inventory",
|
||||||
|
warehouse="Stores - TCP1",
|
||||||
|
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.supplied_items[1].expense_account = "_Test Write Off - TCP1"
|
||||||
|
scr.save()
|
||||||
|
scr.submit()
|
||||||
|
|
||||||
|
for item in scr.supplied_items:
|
||||||
|
self.assertTrue(item.expense_account)
|
||||||
|
|
||||||
|
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: [4000, 3000],
|
||||||
|
expense_account: [2000, 4000],
|
||||||
|
"_Test Write Off - TCP1": [1000, 0],
|
||||||
|
}
|
||||||
|
|
||||||
|
for gle in gl_entries:
|
||||||
|
self.assertEqual(expected_values[gle.account][0], gle.debit)
|
||||||
|
self.assertEqual(expected_values[gle.account][1], gle.credit)
|
||||||
|
|
||||||
@change_settings("Stock Settings", {"use_serial_batch_fields": 0})
|
@change_settings("Stock Settings", {"use_serial_batch_fields": 0})
|
||||||
def test_subcontracting_receipt_with_zero_service_cost(self):
|
def test_subcontracting_receipt_with_zero_service_cost(self):
|
||||||
warehouse = "Stores - TCP1"
|
warehouse = "Stores - TCP1"
|
||||||
|
|||||||
@@ -33,7 +33,11 @@
|
|||||||
"section_break_zwnh",
|
"section_break_zwnh",
|
||||||
"serial_no",
|
"serial_no",
|
||||||
"column_break_qibi",
|
"column_break_qibi",
|
||||||
"batch_no"
|
"batch_no",
|
||||||
|
"accounting_details_section",
|
||||||
|
"expense_account",
|
||||||
|
"accounting_dimensions_section",
|
||||||
|
"cost_center"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@@ -103,7 +107,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "stock_uom",
|
"fieldname": "stock_uom",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Stock Uom",
|
"label": "Stock UOM",
|
||||||
"options": "UOM",
|
"options": "UOM",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
@@ -231,18 +235,43 @@
|
|||||||
"fieldname": "add_serial_batch_bundle",
|
"fieldname": "add_serial_batch_bundle",
|
||||||
"fieldtype": "Button",
|
"fieldtype": "Button",
|
||||||
"label": "Add Serial / Batch Bundle"
|
"label": "Add Serial / Batch Bundle"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "accounting_details_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Accounting Details"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "expense_account",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Expense Account",
|
||||||
|
"options": "Account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "accounting_dimensions_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Accounting Dimensions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:cint(erpnext.is_perpetual_inventory_enabled(parent.company))",
|
||||||
|
"fieldname": "cost_center",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Cost Center",
|
||||||
|
"options": "Cost Center",
|
||||||
|
"print_hide": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2024-03-30 10:26:27.237371",
|
"modified": "2025-05-27 12:33:58.772638",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Subcontracting",
|
"module": "Subcontracting",
|
||||||
"name": "Subcontracting Receipt Supplied Item",
|
"name": "Subcontracting Receipt Supplied Item",
|
||||||
"naming_rule": "Autoincrement",
|
"naming_rule": "Autoincrement",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
|
"row_format": "Dynamic",
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"states": [],
|
"states": [],
|
||||||
|
|||||||
@@ -20,8 +20,10 @@ class SubcontractingReceiptSuppliedItem(Document):
|
|||||||
bom_detail_no: DF.Data | None
|
bom_detail_no: DF.Data | None
|
||||||
consumed_qty: DF.Float
|
consumed_qty: DF.Float
|
||||||
conversion_factor: DF.Float
|
conversion_factor: DF.Float
|
||||||
|
cost_center: DF.Link | None
|
||||||
current_stock: DF.Float
|
current_stock: DF.Float
|
||||||
description: DF.TextEditor | None
|
description: DF.TextEditor | None
|
||||||
|
expense_account: DF.Link | None
|
||||||
item_name: DF.Data | None
|
item_name: DF.Data | None
|
||||||
main_item_code: DF.Link | None
|
main_item_code: DF.Link | None
|
||||||
parent: DF.Data
|
parent: DF.Data
|
||||||
|
|||||||
Reference in New Issue
Block a user