diff --git a/erpnext/manufacturing/doctype/work_order/services/required_items.py b/erpnext/manufacturing/doctype/work_order/services/required_items.py index 9d1b02fd440..544c779e938 100644 --- a/erpnext/manufacturing/doctype/work_order/services/required_items.py +++ b/erpnext/manufacturing/doctype/work_order/services/required_items.py @@ -24,12 +24,14 @@ from erpnext.manufacturing.doctype.work_order.services.reservation import ( get_row_wise_serial_batch, ) from erpnext.manufacturing.doctype.work_order.services.status import StatusService +from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults from erpnext.stock.utils import get_bin, get_latest_stock_qty class RequiredItemsService: def __init__(self, doc): self.doc = doc + self._item_group_warehouses = {} def update_required_items(self): """ @@ -116,7 +118,21 @@ class RequiredItemsService: def _item_source_warehouse(self, item, reset_source_warehouse): if reset_source_warehouse: return self.doc.source_warehouse - return self.doc.source_warehouse or item.source_warehouse or item.default_warehouse + return ( + self.doc.source_warehouse + or item.source_warehouse + or item.default_warehouse + or self._item_group_warehouse(item) + ) + + def _item_group_warehouse(self, item): + # components of a bom commonly share a group, look it up once for all of them + if item.item_group not in self._item_group_warehouses: + self._item_group_warehouses[item.item_group] = get_item_group_defaults( + item.item_code, self.doc.company + ).get("default_warehouse") + + return self._item_group_warehouses[item.item_group] def _required_item_row(self, item, operation, source_warehouse): return { diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py index 39fc7d16171..3101c0dc30b 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order.py +++ b/erpnext/manufacturing/doctype/work_order/work_order.py @@ -60,8 +60,9 @@ from erpnext.manufacturing.doctype.work_order.services.reservation import ( from erpnext.manufacturing.doctype.work_order.services.status import ( StatusService, ) +from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults from erpnext.stock.doctype.batch.batch import make_batch -from erpnext.stock.doctype.item.item import validate_end_of_life +from erpnext.stock.doctype.item.item import get_item_defaults, validate_end_of_life from erpnext.stock.doctype.serial_no.serial_no import get_available_serial_nos from erpnext.stock.utils import validate_warehouse_company from erpnext.utilities.transaction_base import validate_uom_is_integer @@ -568,7 +569,18 @@ class WorkOrder(Document): if not self.wip_warehouse and not self.skip_transfer: self.wip_warehouse = frappe.get_cached_value("Company", self.company, "default_wip_warehouse") if not self.fg_warehouse: - self.fg_warehouse = frappe.get_cached_value("Company", self.company, "default_fg_warehouse") + self.fg_warehouse = ( + frappe.get_cached_value("Company", self.company, "default_fg_warehouse") + or self.get_production_item_warehouse() + ) + + def get_production_item_warehouse(self): + if not self.production_item: + return None + + return get_item_defaults(self.production_item, self.company).get( + "default_warehouse" + ) or get_item_group_defaults(self.production_item, self.company).get("default_warehouse") def check_wip_warehouse_skip(self): if self.skip_transfer and not self.from_wip_warehouse: