mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-15 11:09:17 +00:00
fix: scrap items in job card
This commit is contained in:
@@ -1280,6 +1280,10 @@ def get_bom_items_as_dict(
|
|||||||
fetch_exploded = 0
|
fetch_exploded = 0
|
||||||
group_by_cond = "group by item_code, operation_row_id, stock_uom"
|
group_by_cond = "group by item_code, operation_row_id, stock_uom"
|
||||||
|
|
||||||
|
if fetch_scrap_items:
|
||||||
|
fetch_exploded = 0
|
||||||
|
group_by_cond = "group by item_code"
|
||||||
|
|
||||||
# Did not use qty_consumed_per_unit in the query, as it leads to rounding loss
|
# Did not use qty_consumed_per_unit in the query, as it leads to rounding loss
|
||||||
query = """select
|
query = """select
|
||||||
bom_item.item_code,
|
bom_item.item_code,
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ from frappe.utils import (
|
|||||||
time_diff_in_hours,
|
time_diff_in_hours,
|
||||||
)
|
)
|
||||||
|
|
||||||
from erpnext.manufacturing.doctype.bom.bom import add_additional_cost
|
from erpnext.manufacturing.doctype.bom.bom import add_additional_cost, get_bom_items_as_dict
|
||||||
from erpnext.manufacturing.doctype.manufacturing_settings.manufacturing_settings import (
|
from erpnext.manufacturing.doctype.manufacturing_settings.manufacturing_settings import (
|
||||||
get_mins_between_operations,
|
get_mins_between_operations,
|
||||||
)
|
)
|
||||||
@@ -240,6 +240,26 @@ class JobCard(Document):
|
|||||||
row.sub_operation = row.operation
|
row.sub_operation = row.operation
|
||||||
self.append("sub_operations", row)
|
self.append("sub_operations", row)
|
||||||
|
|
||||||
|
def set_scrap_items(self):
|
||||||
|
if not self.semi_fg_bom:
|
||||||
|
return
|
||||||
|
|
||||||
|
items_dict = get_bom_items_as_dict(
|
||||||
|
self.semi_fg_bom, self.company, qty=self.for_quantity, fetch_exploded=0, fetch_scrap_items=1
|
||||||
|
)
|
||||||
|
for item_code, values in items_dict.items():
|
||||||
|
values = frappe._dict(values)
|
||||||
|
|
||||||
|
self.append(
|
||||||
|
"scrap_items",
|
||||||
|
{
|
||||||
|
"item_code": item_code,
|
||||||
|
"stock_qty": values.qty,
|
||||||
|
"item_name": values.item_name,
|
||||||
|
"stock_uom": values.stock_uom,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
def validate_time_logs(self, save=False):
|
def validate_time_logs(self, save=False):
|
||||||
self.total_time_in_mins = 0.0
|
self.total_time_in_mins = 0.0
|
||||||
self.total_completed_qty = 0.0
|
self.total_completed_qty = 0.0
|
||||||
@@ -1361,10 +1381,15 @@ class JobCard(Document):
|
|||||||
wo_doc = frappe.get_doc("Work Order", self.work_order)
|
wo_doc = frappe.get_doc("Work Order", self.work_order)
|
||||||
add_additional_cost(ste.stock_entry, wo_doc, self)
|
add_additional_cost(ste.stock_entry, wo_doc, self)
|
||||||
|
|
||||||
ste.stock_entry.save()
|
ste.stock_entry.set_scrap_items()
|
||||||
|
for row in ste.stock_entry.items:
|
||||||
|
if row.is_scrap_item and not row.t_warehouse:
|
||||||
|
row.t_warehouse = self.target_warehouse
|
||||||
|
|
||||||
if auto_submit:
|
if auto_submit:
|
||||||
ste.stock_entry.submit()
|
ste.stock_entry.submit()
|
||||||
|
else:
|
||||||
|
ste.stock_entry.save()
|
||||||
|
|
||||||
frappe.msgprint(
|
frappe.msgprint(
|
||||||
_("Stock Entry {0} has created").format(get_link_to_form("Stock Entry", ste.stock_entry.name))
|
_("Stock Entry {0} has created").format(get_link_to_form("Stock Entry", ste.stock_entry.name))
|
||||||
|
|||||||
@@ -2565,6 +2565,8 @@ def create_job_card(work_order, row, enable_capacity_planning=False, auto_create
|
|||||||
work_order.transfer_material_against == "Job Card" and not work_order.skip_transfer
|
work_order.transfer_material_against == "Job Card" and not work_order.skip_transfer
|
||||||
):
|
):
|
||||||
doc.get_required_items()
|
doc.get_required_items()
|
||||||
|
if work_order.track_semi_finished_goods:
|
||||||
|
doc.set_scrap_items()
|
||||||
|
|
||||||
if auto_create:
|
if auto_create:
|
||||||
doc.flags.ignore_mandatory = True
|
doc.flags.ignore_mandatory = True
|
||||||
|
|||||||
@@ -2716,6 +2716,9 @@ class StockEntry(StockController, SubcontractingInwardController):
|
|||||||
return item_dict
|
return item_dict
|
||||||
|
|
||||||
def get_scrap_items_from_job_card(self):
|
def get_scrap_items_from_job_card(self):
|
||||||
|
if not hasattr(self, "pro_doc"):
|
||||||
|
self.pro_doc = None
|
||||||
|
|
||||||
if not self.pro_doc:
|
if not self.pro_doc:
|
||||||
self.set_work_order_details()
|
self.set_work_order_details()
|
||||||
|
|
||||||
@@ -2742,9 +2745,17 @@ class StockEntry(StockController, SubcontractingInwardController):
|
|||||||
& (job_card.docstatus == 1)
|
& (job_card.docstatus == 1)
|
||||||
)
|
)
|
||||||
.groupby(job_card_scrap_item.item_code)
|
.groupby(job_card_scrap_item.item_code)
|
||||||
).run(as_dict=1)
|
)
|
||||||
|
|
||||||
pending_qty = flt(self.get_completed_job_card_qty()) - flt(self.pro_doc.produced_qty)
|
if self.job_card:
|
||||||
|
scrap_items = scrap_items.where(job_card.name == self.job_card)
|
||||||
|
|
||||||
|
scrap_items = scrap_items.run(as_dict=1)
|
||||||
|
|
||||||
|
if self.job_card:
|
||||||
|
pending_qty = flt(self.fg_completed_qty)
|
||||||
|
else:
|
||||||
|
pending_qty = flt(self.get_completed_job_card_qty()) - flt(self.pro_doc.produced_qty)
|
||||||
|
|
||||||
used_scrap_items = self.get_used_scrap_items()
|
used_scrap_items = self.get_used_scrap_items()
|
||||||
for row in scrap_items:
|
for row in scrap_items:
|
||||||
|
|||||||
Reference in New Issue
Block a user