mirror of
https://github.com/frappe/erpnext.git
synced 2026-02-16 16:15:02 +00:00
refactor: rename subcontracting fields
This commit is contained in:
@@ -406,7 +406,7 @@ erpnext.buying.PurchaseOrderController = class PurchaseOrderController extends (
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (!doc.items.every((item) => item.qty == item.sco_qty)) {
|
||||
if (!doc.items.every((item) => item.qty == item.subcontracted_quantity)) {
|
||||
this.frm.add_custom_button(
|
||||
__("Subcontracting Order"),
|
||||
() => {
|
||||
|
||||
@@ -922,7 +922,7 @@ def is_po_fully_subcontracted(po_name):
|
||||
query = (
|
||||
frappe.qb.from_(table)
|
||||
.select(table.name)
|
||||
.where((table.parent == po_name) & (table.qty != table.sco_qty))
|
||||
.where((table.parent == po_name) & (table.qty != table.subcontracted_quantity))
|
||||
)
|
||||
return not query.run(as_dict=True)
|
||||
|
||||
@@ -977,7 +977,7 @@ def get_mapped_subcontracting_order(source_name, target_doc=None):
|
||||
"material_request_item": "material_request_item",
|
||||
},
|
||||
"field_no_map": ["qty", "fg_item_qty", "amount"],
|
||||
"condition": lambda item: item.qty != item.sco_qty,
|
||||
"condition": lambda item: item.qty != item.subcontracted_quantity,
|
||||
},
|
||||
},
|
||||
target_doc,
|
||||
|
||||
@@ -1097,9 +1097,9 @@ class TestPurchaseOrder(IntegrationTestCase):
|
||||
|
||||
# Test - 2: Subcontracted Quantity for the PO Items of each line item should be updated accordingly
|
||||
po.reload()
|
||||
self.assertEqual(po.items[0].sco_qty, 5)
|
||||
self.assertEqual(po.items[1].sco_qty, 0)
|
||||
self.assertEqual(po.items[2].sco_qty, 12.5)
|
||||
self.assertEqual(po.items[0].subcontracted_quantity, 5)
|
||||
self.assertEqual(po.items[1].subcontracted_quantity, 0)
|
||||
self.assertEqual(po.items[2].subcontracted_quantity, 12.5)
|
||||
|
||||
# Test - 3: Amount for both FG Item and its Service Item should be updated correctly based on change in Quantity
|
||||
self.assertEqual(sco.items[0].amount, 2000)
|
||||
@@ -1135,10 +1135,10 @@ class TestPurchaseOrder(IntegrationTestCase):
|
||||
|
||||
# Test - 8: Subcontracted Quantity for each PO Item should be subtracted if SCO gets cancelled
|
||||
po.reload()
|
||||
self.assertEqual(po.items[2].sco_qty, 25)
|
||||
self.assertEqual(po.items[2].subcontracted_quantity, 25)
|
||||
sco.cancel()
|
||||
po.reload()
|
||||
self.assertEqual(po.items[2].sco_qty, 12.5)
|
||||
self.assertEqual(po.items[2].subcontracted_quantity, 12.5)
|
||||
|
||||
sco = make_subcontracting_order(po.name)
|
||||
sco.save()
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"quantity_and_rate",
|
||||
"qty",
|
||||
"stock_uom",
|
||||
"sco_qty",
|
||||
"subcontracted_quantity",
|
||||
"col_break2",
|
||||
"uom",
|
||||
"conversion_factor",
|
||||
@@ -933,7 +933,7 @@
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "sco_qty",
|
||||
"fieldname": "subcontracted_quantity",
|
||||
"fieldtype": "Float",
|
||||
"label": "Subcontracted Quantity",
|
||||
"no_copy": 1,
|
||||
@@ -941,11 +941,12 @@
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"grid_page_length": 50,
|
||||
"idx": 1,
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2025-02-18 12:35:04.432636",
|
||||
"modified": "2025-03-02 16:58:26.059601",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order Item",
|
||||
@@ -953,6 +954,7 @@
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"row_format": "Dynamic",
|
||||
"search_fields": "item_name",
|
||||
"sort_field": "creation",
|
||||
"sort_order": "DESC",
|
||||
|
||||
@@ -82,10 +82,10 @@ class PurchaseOrderItem(Document):
|
||||
sales_order_item: DF.Data | None
|
||||
sales_order_packed_item: DF.Data | None
|
||||
schedule_date: DF.Date
|
||||
sco_qty: DF.Float
|
||||
stock_qty: DF.Float
|
||||
stock_uom: DF.Link
|
||||
stock_uom_rate: DF.Currency
|
||||
subcontracted_quantity: DF.Float
|
||||
supplier_part_no: DF.Data | None
|
||||
supplier_quotation: DF.Link | None
|
||||
supplier_quotation_item: DF.Link | None
|
||||
|
||||
@@ -104,18 +104,18 @@ class SubcontractingController(StockController):
|
||||
)
|
||||
|
||||
if (
|
||||
self.doctype == "Subcontracting Order" and not item.sc_conversion_factor
|
||||
self.doctype == "Subcontracting Order" and not item.subcontracting_conversion_factor
|
||||
): # this condition will only be true if user has recently updated from develop branch
|
||||
service_item_qty = frappe.get_value(
|
||||
"Subcontracting Order Service Item",
|
||||
filters={"purchase_order_item": item.purchase_order_item, "parent": self.name},
|
||||
fieldname=["qty"],
|
||||
)
|
||||
item.sc_conversion_factor = service_item_qty / item.qty
|
||||
item.subcontracting_conversion_factor = service_item_qty / item.qty
|
||||
|
||||
if self.doctype not in "Subcontracting Receipt" and item.qty > flt(
|
||||
get_pending_sco_qty(self.purchase_order).get(item.purchase_order_item)
|
||||
/ item.sc_conversion_factor,
|
||||
get_pending_subcontracted_quantity(self.purchase_order).get(item.purchase_order_item)
|
||||
/ item.subcontracting_conversion_factor,
|
||||
frappe.get_precision("Purchase Order Item", "qty"),
|
||||
):
|
||||
frappe.throw(
|
||||
@@ -1138,10 +1138,14 @@ def get_item_details(items):
|
||||
return item_details
|
||||
|
||||
|
||||
def get_pending_sco_qty(po_name):
|
||||
def get_pending_subcontracted_quantity(po_name):
|
||||
table = frappe.qb.DocType("Purchase Order Item")
|
||||
query = frappe.qb.from_(table).select(table.name, table.qty, table.sco_qty).where(table.parent == po_name)
|
||||
return {item.name: item.qty - item.sco_qty for item in query.run(as_dict=True)}
|
||||
query = (
|
||||
frappe.qb.from_(table)
|
||||
.select(table.name, table.qty, table.subcontracted_quantity)
|
||||
.where(table.parent == po_name)
|
||||
)
|
||||
return {item.name: item.qty - item.subcontracted_quantity for item in query.run(as_dict=True)}
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
|
||||
@@ -1433,7 +1433,7 @@ def add_operations_cost(stock_entry, work_order=None, expense_account=None):
|
||||
},
|
||||
)
|
||||
|
||||
def get_max_op_qty():
|
||||
def get_max_operation_quantity():
|
||||
from frappe.query_builder.functions import Sum
|
||||
|
||||
table = frappe.qb.DocType("Job Card")
|
||||
@@ -1449,7 +1449,7 @@ def add_operations_cost(stock_entry, work_order=None, expense_account=None):
|
||||
)
|
||||
return min([d.qty for d in query.run(as_dict=True)], default=0)
|
||||
|
||||
def get_utilised_cc():
|
||||
def get_utilised_corrective_cost():
|
||||
from frappe.query_builder.functions import Sum
|
||||
|
||||
table = frappe.qb.DocType("Stock Entry")
|
||||
@@ -1479,15 +1479,15 @@ def add_operations_cost(stock_entry, work_order=None, expense_account=None):
|
||||
)
|
||||
)
|
||||
):
|
||||
max_qty = get_max_op_qty() - work_order.produced_qty
|
||||
remaining_cc = work_order.corrective_operation_cost - get_utilised_cc()
|
||||
max_qty = get_max_operation_quantity() - work_order.produced_qty
|
||||
remaining_corrective_cost = work_order.corrective_operation_cost - get_utilised_corrective_cost()
|
||||
stock_entry.append(
|
||||
"additional_costs",
|
||||
{
|
||||
"expense_account": expense_account,
|
||||
"description": "Corrective Operation Cost",
|
||||
"has_corrective_cost": 1,
|
||||
"amount": remaining_cc / max_qty * flt(stock_entry.fg_completed_qty),
|
||||
"amount": remaining_corrective_cost / max_qty * flt(stock_entry.fg_completed_qty),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -260,6 +260,7 @@ erpnext.patches.v14_0.show_loan_management_deprecation_warning
|
||||
erpnext.patches.v14_0.clear_reconciliation_values_from_singles
|
||||
execute:frappe.rename_doc("Report", "TDS Payable Monthly", "Tax Withholding Details", force=True)
|
||||
erpnext.patches.v14_0.update_proprietorship_to_individual
|
||||
erpnext.patches.v15_0.rename_subcontracting_fields
|
||||
|
||||
[post_model_sync]
|
||||
erpnext.patches.v15_0.create_asset_depreciation_schedules_from_assets
|
||||
|
||||
7
erpnext/patches/v15_0/rename_subcontracting_fields.py
Normal file
7
erpnext/patches/v15_0/rename_subcontracting_fields.py
Normal file
@@ -0,0 +1,7 @@
|
||||
import frappe
|
||||
from frappe.model.utils.rename_field import rename_field
|
||||
|
||||
|
||||
def execute():
|
||||
rename_field("Purchase Order Item", "sco_qty", "subcontracted_quantity")
|
||||
rename_field("Subcontracting Order Item", "sc_conversion_factor", "subcontracting_conversion_factor")
|
||||
@@ -16,14 +16,14 @@ frappe.ui.form.on("Subcontracting Order Item", {
|
||||
service_item.doctype,
|
||||
service_item.name,
|
||||
"qty",
|
||||
row.qty * row.sc_conversion_factor
|
||||
row.qty * row.subcontracting_conversion_factor
|
||||
);
|
||||
frappe.model.set_value(service_item.doctype, service_item.name, "fg_item_qty", row.qty);
|
||||
frappe.model.set_value(
|
||||
service_item.doctype,
|
||||
service_item.name,
|
||||
"amount",
|
||||
row.qty * row.sc_conversion_factor * service_item.rate
|
||||
row.qty * row.subcontracting_conversion_factor * service_item.rate
|
||||
);
|
||||
},
|
||||
before_items_remove(frm, cdt, cdn) {
|
||||
|
||||
@@ -119,12 +119,12 @@ class SubcontractingOrder(SubcontractingController):
|
||||
def on_submit(self):
|
||||
self.update_prevdoc_status()
|
||||
self.update_status()
|
||||
self.update_sco_qty_in_po()
|
||||
self.update_subcontracted_quantity_in_po()
|
||||
|
||||
def on_cancel(self):
|
||||
self.update_prevdoc_status()
|
||||
self.update_status()
|
||||
self.update_sco_qty_in_po(cancel=True)
|
||||
self.update_subcontracted_quantity_in_po(cancel=True)
|
||||
|
||||
def validate_purchase_order_for_subcontracting(self):
|
||||
if self.purchase_order:
|
||||
@@ -162,7 +162,7 @@ class SubcontractingOrder(SubcontractingController):
|
||||
item = next(
|
||||
item for item in self.items if item.purchase_order_item == service_item.purchase_order_item
|
||||
)
|
||||
service_item.qty = item.qty * item.sc_conversion_factor
|
||||
service_item.qty = item.qty * item.subcontracting_conversion_factor
|
||||
service_item.fg_item_qty = item.qty
|
||||
service_item.amount = service_item.qty * service_item.rate
|
||||
|
||||
@@ -250,7 +250,7 @@ class SubcontractingOrder(SubcontractingController):
|
||||
item = frappe.get_doc("Item", si.fg_item)
|
||||
|
||||
po_item = frappe.get_doc("Purchase Order Item", si.purchase_order_item)
|
||||
available_qty = po_item.qty - po_item.sco_qty
|
||||
available_qty = po_item.qty - po_item.subcontracted_quantity
|
||||
|
||||
if available_qty == 0:
|
||||
continue
|
||||
@@ -276,7 +276,7 @@ class SubcontractingOrder(SubcontractingController):
|
||||
"schedule_date": self.schedule_date,
|
||||
"description": item.description,
|
||||
"qty": si.fg_item_qty,
|
||||
"sc_conversion_factor": conversion_factor,
|
||||
"subcontracting_conversion_factor": conversion_factor,
|
||||
"stock_uom": item.stock_uom,
|
||||
"bom": bom,
|
||||
"purchase_order_item": si.purchase_order_item,
|
||||
@@ -330,10 +330,14 @@ class SubcontractingOrder(SubcontractingController):
|
||||
self.update_ordered_qty_for_subcontracting()
|
||||
self.update_reserved_qty_for_subcontracting()
|
||||
|
||||
def update_sco_qty_in_po(self, cancel=False):
|
||||
def update_subcontracted_quantity_in_po(self, cancel=False):
|
||||
for service_item in self.service_items:
|
||||
doc = frappe.get_doc("Purchase Order Item", service_item.purchase_order_item)
|
||||
doc.sco_qty = (doc.sco_qty + service_item.qty) if not cancel else (doc.sco_qty - service_item.qty)
|
||||
doc.subcontracted_quantity = (
|
||||
(doc.subcontracted_quantity + service_item.qty)
|
||||
if not cancel
|
||||
else (doc.subcontracted_quantity - service_item.qty)
|
||||
)
|
||||
doc.save()
|
||||
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
"section_break_34",
|
||||
"purchase_order_item",
|
||||
"page_break",
|
||||
"sc_conversion_factor"
|
||||
"subcontracting_conversion_factor"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@@ -403,18 +403,19 @@
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "sc_conversion_factor",
|
||||
"fieldname": "subcontracting_conversion_factor",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 1,
|
||||
"label": "SC Conversion Factor",
|
||||
"label": "Subcontracting Conversion Factor",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"grid_page_length": 50,
|
||||
"idx": 1,
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2024-12-13 13:35:28.935898",
|
||||
"modified": "2025-03-02 17:05:28.386492",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Subcontracting",
|
||||
"name": "Subcontracting Order Item",
|
||||
@@ -422,6 +423,7 @@
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"row_format": "Dynamic",
|
||||
"search_fields": "item_name",
|
||||
"sort_field": "creation",
|
||||
"sort_order": "DESC",
|
||||
|
||||
@@ -42,10 +42,10 @@ class SubcontractingOrderItem(Document):
|
||||
received_qty: DF.Float
|
||||
returned_qty: DF.Float
|
||||
rm_cost_per_qty: DF.Currency
|
||||
sc_conversion_factor: DF.Float
|
||||
schedule_date: DF.Date | None
|
||||
service_cost_per_qty: DF.Currency
|
||||
stock_uom: DF.Link
|
||||
subcontracting_conversion_factor: DF.Float
|
||||
warehouse: DF.Link
|
||||
# end: auto-generated types
|
||||
|
||||
|
||||
Reference in New Issue
Block a user