mirror of
https://github.com/frappe/erpnext.git
synced 2026-02-16 08:05:00 +00:00
Merge pull request #50929 from rohitwaghchaure/fixed-backflushed-basedd-on-for-job-card
fix: backflush based on for job card
This commit is contained in:
@@ -940,6 +940,36 @@ class JobCard(Document):
|
||||
},
|
||||
)
|
||||
|
||||
def set_consumed_qty_in_job_card_item(self, ste_doc):
|
||||
jc_item_names = [row.job_card_item for row in ste_doc.get("items") if row.get("job_card_item")]
|
||||
|
||||
if not jc_item_names:
|
||||
return
|
||||
|
||||
se = frappe.qb.DocType("Stock Entry")
|
||||
sed = frappe.qb.DocType("Stock Entry Detail")
|
||||
|
||||
query = (
|
||||
frappe.qb.from_(sed)
|
||||
.join(se)
|
||||
.on(sed.parent == se.name)
|
||||
.select(sed.job_card_item, Sum(sed.qty))
|
||||
.where(
|
||||
(sed.job_card_item.isin(jc_item_names)) & (se.docstatus == 1) & (se.purpose == "Manufacture")
|
||||
)
|
||||
.groupby(sed.job_card_item)
|
||||
)
|
||||
|
||||
itemwise_consumed_qty = frappe._dict(query.run(as_list=True))
|
||||
|
||||
for row in ste_doc.items:
|
||||
if not row.get("job_card_item"):
|
||||
continue
|
||||
|
||||
consumed_qty = flt(itemwise_consumed_qty.get(row.job_card_item, 0.0))
|
||||
|
||||
frappe.db.set_value("Job Card Item", row.job_card_item, "consumed_qty", consumed_qty)
|
||||
|
||||
def set_transferred_qty_in_job_card_item(self, ste_doc):
|
||||
def _get_job_card_items_transferred_qty(ste_doc):
|
||||
from frappe.query_builder.functions import Sum
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"required_qty",
|
||||
"column_break_9",
|
||||
"transferred_qty",
|
||||
"consumed_qty",
|
||||
"allow_alternative_item"
|
||||
],
|
||||
"fields": [
|
||||
@@ -100,20 +101,28 @@
|
||||
"no_copy": 1,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "consumed_qty",
|
||||
"fieldtype": "Float",
|
||||
"label": "Consumed Qty",
|
||||
"no_copy": 1,
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2024-03-27 13:09:56.943741",
|
||||
"modified": "2025-12-04 14:30:19.472294",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Job Card Item",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"row_format": "Dynamic",
|
||||
"sort_field": "creation",
|
||||
"sort_order": "DESC",
|
||||
"states": [],
|
||||
"track_changes": 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ class JobCardItem(Document):
|
||||
from frappe.types import DF
|
||||
|
||||
allow_alternative_item: DF.Check
|
||||
consumed_qty: DF.Float
|
||||
description: DF.Text | None
|
||||
item_code: DF.Link | None
|
||||
item_group: DF.Link | None
|
||||
|
||||
@@ -162,6 +162,11 @@ frappe.ui.form.on("Stock Entry", {
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
if (frm.doc.job_card && frm.doc.purpose === "Manufacture") {
|
||||
frm.set_df_property("fg_completed_qty", "read_only", 1);
|
||||
frm.set_df_property("get_items", "hidden", 1);
|
||||
}
|
||||
},
|
||||
|
||||
setup_quality_inspection: function (frm) {
|
||||
|
||||
@@ -1920,6 +1920,7 @@ class StockEntry(StockController, SubcontractingInwardController):
|
||||
job_doc.set_transferred_qty(update_status=True)
|
||||
job_doc.set_transferred_qty_in_job_card_item(self)
|
||||
else:
|
||||
job_doc.set_consumed_qty_in_job_card_item(self)
|
||||
job_doc.set_manufactured_qty()
|
||||
|
||||
if self.work_order:
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import flt
|
||||
|
||||
@@ -99,22 +100,26 @@ class ManufactureEntry:
|
||||
def add_raw_materials(self):
|
||||
if self.job_card:
|
||||
item_dict = {}
|
||||
# if self.bom_no:
|
||||
# item_dict = get_bom_items_as_dict(
|
||||
# self.bom_no,
|
||||
# self.company,
|
||||
# qty=self.qty_to_manufacture,
|
||||
# fetch_exploded=False,
|
||||
# fetch_qty_in_stock_uom=False,
|
||||
# )
|
||||
|
||||
if not item_dict:
|
||||
item_dict = self.get_items_from_job_card()
|
||||
|
||||
backflush_based_on = frappe.db.get_single_value(
|
||||
"Manufacturing Settings", "backflush_raw_materials_based_on"
|
||||
)
|
||||
|
||||
for item_code, _dict in item_dict.items():
|
||||
_dict.from_warehouse = self.source_wh.get(item_code) or self.wip_warehouse
|
||||
_dict.to_warehouse = ""
|
||||
|
||||
if backflush_based_on != "BOM":
|
||||
calculated_qty = flt(_dict.transferred_qty) - flt(_dict.consumed_qty)
|
||||
if calculated_qty < 0:
|
||||
frappe.throw(
|
||||
_("Consumed quantity of item {0} exceeds transferred quantity.").format(item_code)
|
||||
)
|
||||
|
||||
_dict.qty = calculated_qty
|
||||
|
||||
self.stock_entry.add_to_stock_entry_detail(item_dict)
|
||||
|
||||
def get_items_from_job_card(self):
|
||||
@@ -122,9 +127,12 @@ class ManufactureEntry:
|
||||
items = frappe.get_all(
|
||||
"Job Card Item",
|
||||
fields=[
|
||||
"name as job_card_item",
|
||||
"item_code",
|
||||
"source_warehouse",
|
||||
"required_qty as qty",
|
||||
"transferred_qty",
|
||||
"consumed_qty",
|
||||
"item_name",
|
||||
"uom",
|
||||
"stock_uom",
|
||||
|
||||
Reference in New Issue
Block a user