mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-22 06:29:20 +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 set_transferred_qty_in_job_card_item(self, ste_doc):
|
||||||
def _get_job_card_items_transferred_qty(ste_doc):
|
def _get_job_card_items_transferred_qty(ste_doc):
|
||||||
from frappe.query_builder.functions import Sum
|
from frappe.query_builder.functions import Sum
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
"required_qty",
|
"required_qty",
|
||||||
"column_break_9",
|
"column_break_9",
|
||||||
"transferred_qty",
|
"transferred_qty",
|
||||||
|
"consumed_qty",
|
||||||
"allow_alternative_item"
|
"allow_alternative_item"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
@@ -100,20 +101,28 @@
|
|||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "consumed_qty",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"label": "Consumed Qty",
|
||||||
|
"no_copy": 1,
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2024-03-27 13:09:56.943741",
|
"modified": "2025-12-04 14:30:19.472294",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Manufacturing",
|
"module": "Manufacturing",
|
||||||
"name": "Job Card Item",
|
"name": "Job Card Item",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
|
"row_format": "Dynamic",
|
||||||
"sort_field": "creation",
|
"sort_field": "creation",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"states": [],
|
"states": [],
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ class JobCardItem(Document):
|
|||||||
from frappe.types import DF
|
from frappe.types import DF
|
||||||
|
|
||||||
allow_alternative_item: DF.Check
|
allow_alternative_item: DF.Check
|
||||||
|
consumed_qty: DF.Float
|
||||||
description: DF.Text | None
|
description: DF.Text | None
|
||||||
item_code: DF.Link | None
|
item_code: DF.Link | None
|
||||||
item_group: 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) {
|
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(update_status=True)
|
||||||
job_doc.set_transferred_qty_in_job_card_item(self)
|
job_doc.set_transferred_qty_in_job_card_item(self)
|
||||||
else:
|
else:
|
||||||
|
job_doc.set_consumed_qty_in_job_card_item(self)
|
||||||
job_doc.set_manufactured_qty()
|
job_doc.set_manufactured_qty()
|
||||||
|
|
||||||
if self.work_order:
|
if self.work_order:
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt
|
||||||
|
|
||||||
@@ -99,22 +100,26 @@ class ManufactureEntry:
|
|||||||
def add_raw_materials(self):
|
def add_raw_materials(self):
|
||||||
if self.job_card:
|
if self.job_card:
|
||||||
item_dict = {}
|
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:
|
if not item_dict:
|
||||||
item_dict = self.get_items_from_job_card()
|
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():
|
for item_code, _dict in item_dict.items():
|
||||||
_dict.from_warehouse = self.source_wh.get(item_code) or self.wip_warehouse
|
_dict.from_warehouse = self.source_wh.get(item_code) or self.wip_warehouse
|
||||||
_dict.to_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)
|
self.stock_entry.add_to_stock_entry_detail(item_dict)
|
||||||
|
|
||||||
def get_items_from_job_card(self):
|
def get_items_from_job_card(self):
|
||||||
@@ -122,9 +127,12 @@ class ManufactureEntry:
|
|||||||
items = frappe.get_all(
|
items = frappe.get_all(
|
||||||
"Job Card Item",
|
"Job Card Item",
|
||||||
fields=[
|
fields=[
|
||||||
|
"name as job_card_item",
|
||||||
"item_code",
|
"item_code",
|
||||||
"source_warehouse",
|
"source_warehouse",
|
||||||
"required_qty as qty",
|
"required_qty as qty",
|
||||||
|
"transferred_qty",
|
||||||
|
"consumed_qty",
|
||||||
"item_name",
|
"item_name",
|
||||||
"uom",
|
"uom",
|
||||||
"stock_uom",
|
"stock_uom",
|
||||||
|
|||||||
Reference in New Issue
Block a user