feat: allow the partial return of components against SCO (backport #35935) (#35938)

* fix: don't update SCO status to closed until full return

(cherry picked from commit 2f6d56dd62)

* fix: reduce return qty while calculating transferred qty

(cherry picked from commit 2a60884abc)

# Conflicts:
#	erpnext/controllers/subcontracting_controller.py

* chore: `conflicts`

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
This commit is contained in:
mergify[bot]
2023-06-29 22:16:53 +05:30
committed by GitHub
parent a880bdec5e
commit 6f50ad685e
2 changed files with 43 additions and 37 deletions

View File

@@ -169,45 +169,50 @@ class SubcontractingController(StockController):
self.qty_to_be_received[(row.item_code, row.parent)] += row.qty self.qty_to_be_received[(row.item_code, row.parent)] += row.qty
def __get_transferred_items(self): def __get_transferred_items(self):
fields = [f"`tabStock Entry`.`{self.subcontract_data.order_field}`"] se = frappe.qb.DocType("Stock Entry")
alias_dict = { se_detail = frappe.qb.DocType("Stock Entry Detail")
"item_code": "rm_item_code",
"subcontracted_item": "main_item_code",
"basic_rate": "rate",
}
child_table_fields = [ query = (
"item_code", frappe.qb.from_(se)
"item_name", .inner_join(se_detail)
"description", .on(se.name == se_detail.parent)
"qty", .select(
"basic_rate", se[self.subcontract_data.order_field],
"amount", se_detail.item_code.as_("rm_item_code"),
"serial_no", se_detail.item_name,
"uom", se_detail.description,
"subcontracted_item", (
"stock_uom", frappe.qb.terms.Case()
"batch_no", .when(((se.purpose == "Material Transfer") & (se.is_return == 1)), -1 * se_detail.qty)
"conversion_factor", .else_(se_detail.qty)
"s_warehouse", ).as_("qty"),
"t_warehouse", se_detail.basic_rate.as_("rate"),
"item_group", se_detail.amount,
self.subcontract_data.rm_detail_field, se_detail.serial_no,
] se_detail.uom,
se_detail.subcontracted_item.as_("main_item_code"),
se_detail.stock_uom,
se_detail.batch_no,
se_detail.conversion_factor,
se_detail.s_warehouse,
se_detail.t_warehouse,
se_detail.item_group,
se_detail[self.subcontract_data.rm_detail_field],
)
.where(
(se.docstatus == 1)
& (se[self.subcontract_data.order_field].isin(self.subcontract_orders))
& (
(se.purpose == "Send to Subcontractor")
| ((se.purpose == "Material Transfer") & (se.is_return == 1))
)
)
)
if self.backflush_based_on == "BOM": if self.backflush_based_on == "BOM":
child_table_fields.append("original_item") query = query.select(se_detail.original_item)
for field in child_table_fields: return query.run(as_dict=True)
fields.append(f"`tabStock Entry Detail`.`{field}` As {alias_dict.get(field, field)}")
filters = [
["Stock Entry", "docstatus", "=", 1],
["Stock Entry", "purpose", "=", "Send to Subcontractor"],
["Stock Entry", self.subcontract_data.order_field, "in", self.subcontract_orders],
]
return frappe.get_all("Stock Entry", fields=fields, filters=filters)
def __set_alternative_item_details(self, row): def __set_alternative_item_details(self, row):
if row.get("original_item"): if row.get("original_item"):

View File

@@ -163,9 +163,10 @@ class SubcontractingOrder(SubcontractingController):
elif self.per_received > 0 and self.per_received < 100: elif self.per_received > 0 and self.per_received < 100:
status = "Partially Received" status = "Partially Received"
for item in self.supplied_items: for item in self.supplied_items:
if item.returned_qty: if not item.returned_qty or (item.supplied_qty - item.consumed_qty - item.returned_qty) > 0:
status = "Closed"
break break
else:
status = "Closed"
else: else:
total_required_qty = total_supplied_qty = 0 total_required_qty = total_supplied_qty = 0
for item in self.supplied_items: for item in self.supplied_items: