feat: company wise default warehouses

This commit is contained in:
Mihir Kandoi
2025-11-13 12:51:07 +05:30
parent 9b303a2272
commit 84af60da7f
15 changed files with 70 additions and 65 deletions

View File

@@ -1085,7 +1085,7 @@ class JobCard(Document):
def set_wip_warehouse(self):
if not self.wip_warehouse:
self.wip_warehouse = frappe.db.get_single_value("Manufacturing Settings", "default_wip_warehouse")
self.wip_warehouse = frappe.get_cached_value("Company", self.company, "default_wip_warehouse")
def validate_operation_id(self):
if (

View File

@@ -18,18 +18,6 @@ frappe.tour["Manufacturing Settings"] = [
"The Stock Entry of type 'Manufacture' is known as backflush. Raw materials being consumed to manufacture finished goods is known as backflushing. <br><br> When creating Manufacture Entry, raw-material items are backflushed based on BOM of production item. If you want raw-material items to be backflushed based on Material Transfer entry made against that Work Order instead, then you can set it under this field."
),
},
{
fieldname: "default_wip_warehouse",
title: __("Work In Progress Warehouse"),
description: __(
"This Warehouse will be auto-updated in the Work In Progress Warehouse field of Work Orders."
),
},
{
fieldname: "default_fg_warehouse",
title: __("Finished Goods Warehouse"),
description: __("This Warehouse will be auto-updated in the Target Warehouse field of Work Order."),
},
{
fieldname: "update_bom_costs_automatically",
title: __("Update BOM Cost Automatically"),

View File

@@ -16,11 +16,6 @@
"update_bom_costs_automatically",
"column_break_lhyt",
"allow_editing_of_items_and_quantities_in_work_order",
"section_break_6",
"default_wip_warehouse",
"default_fg_warehouse",
"column_break_11",
"default_scrap_warehouse",
"over_production_for_sales_and_work_order_section",
"overproduction_percentage_for_sales_order",
"column_break_16",
@@ -86,11 +81,6 @@
"fieldtype": "Int",
"label": "Time Between Operations (Mins)"
},
{
"fieldname": "section_break_6",
"fieldtype": "Section Break",
"label": "Default Warehouses for Production"
},
{
"fieldname": "overproduction_percentage_for_sales_order",
"fieldtype": "Percent",
@@ -122,34 +112,12 @@
"fieldtype": "Check",
"label": "Update BOM Cost Automatically"
},
{
"fieldname": "column_break_11",
"fieldtype": "Column Break"
},
{
"fieldname": "default_wip_warehouse",
"fieldtype": "Link",
"label": "Default Work In Progress Warehouse",
"options": "Warehouse"
},
{
"fieldname": "default_fg_warehouse",
"fieldtype": "Link",
"label": "Default Finished Goods Warehouse",
"options": "Warehouse"
},
{
"default": "0",
"fieldname": "disable_capacity_planning",
"fieldtype": "Check",
"label": "Disable Capacity Planning"
},
{
"fieldname": "default_scrap_warehouse",
"fieldtype": "Link",
"label": "Default Scrap Warehouse",
"options": "Warehouse"
},
{
"fieldname": "over_production_for_sales_and_work_order_section",
"fieldtype": "Section Break",
@@ -275,7 +243,7 @@
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2025-11-07 14:52:56.241459",
"modified": "2025-11-13 12:30:29.006822",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Manufacturing Settings",

View File

@@ -23,9 +23,6 @@ class ManufacturingSettings(Document):
allow_production_on_holidays: DF.Check
backflush_raw_materials_based_on: DF.Literal["BOM", "Material Transferred for Manufacture"]
capacity_planning_for_days: DF.Int
default_fg_warehouse: DF.Link | None
default_scrap_warehouse: DF.Link | None
default_wip_warehouse: DF.Link | None
disable_capacity_planning: DF.Check
enforce_time_logs: DF.Check
get_rm_cost_from_consumption_entry: DF.Check

View File

@@ -756,7 +756,7 @@ class ProductionPlan(Document):
wo_list, po_list = [], []
subcontracted_po = {}
default_warehouses = get_default_warehouse()
default_warehouses = get_default_warehouse(self.company)
self.make_work_order_for_finished_goods(wo_list, default_warehouses)
self.make_work_order_for_subassembly_items(wo_list, subcontracted_po, default_warehouses)

View File

@@ -932,6 +932,9 @@ erpnext.work_order = {
if (!(frm.doc.wip_warehouse || frm.doc.fg_warehouse)) {
frappe.call({
method: "erpnext.manufacturing.doctype.work_order.work_order.get_default_warehouse",
args: {
company: frm.doc.company,
},
callback: function (r) {
if (!r.exe) {
frm.set_value("wip_warehouse", r.message.wip_warehouse);

View File

@@ -453,9 +453,9 @@ class WorkOrder(Document):
def set_default_warehouse(self):
if not self.wip_warehouse and not self.skip_transfer:
self.wip_warehouse = frappe.db.get_single_value("Manufacturing Settings", "default_wip_warehouse")
self.wip_warehouse = frappe.get_cached_value("Company", self.company, "default_wip_warehouse")
if not self.fg_warehouse:
self.fg_warehouse = frappe.db.get_single_value("Manufacturing Settings", "default_fg_warehouse")
self.fg_warehouse = frappe.get_cached_value("Company", self.company, "default_fg_warehouse")
def check_wip_warehouse_skip(self):
if self.skip_transfer and not self.from_wip_warehouse:
@@ -2318,13 +2318,14 @@ def make_stock_entry(
@frappe.whitelist()
def get_default_warehouse():
doc = frappe.get_cached_doc("Manufacturing Settings")
def get_default_warehouse(company):
wip, fg, scrap = frappe.get_cached_value(
"Company", company, ["default_wip_warehouse", "default_fg_warehouse", "default_scrap_warehouse"]
)
return {
"wip_warehouse": doc.default_wip_warehouse,
"fg_warehouse": doc.default_fg_warehouse,
"scrap_warehouse": doc.default_scrap_warehouse,
"wip_warehouse": wip,
"fg_warehouse": fg,
"scrap_warehouse": scrap,
}

View File

@@ -446,3 +446,4 @@ erpnext.patches.v16_0.add_new_stock_entry_types
erpnext.patches.v15_0.set_asset_status_if_not_already_set
erpnext.patches.v15_0.toggle_legacy_controller_for_period_closing
erpnext.patches.v16_0.update_serial_batch_entries
erpnext.patches.v16_0.set_company_wise_warehouses

View File

@@ -0,0 +1,14 @@
import frappe
def execute():
warehouses = frappe.get_single_value(
"Manufacturing Settings",
["default_wip_warehouse", "default_fg_warehouse", "default_scrap_warehouse"],
as_dict=True,
)
for name, warehouse in warehouses.items():
if warehouse:
company = frappe.get_value("Warehouse", warehouse, "company")
frappe.db.set_value("Company", company, name, warehouse)

View File

@@ -1796,7 +1796,7 @@ class TestSalesOrder(AccountsTestMixin, IntegrationTestCase):
mr.submit()
# WO from MR
wo_name = raise_work_orders(mr.name)[0]
wo_name = raise_work_orders(mr.name, mr.company)[0]
wo = frappe.get_doc("Work Order", wo_name)
wo.wip_warehouse = "Work In Progress - _TC"
wo.skip_transfer = True

View File

@@ -124,6 +124,10 @@
"default_in_transit_warehouse",
"manufacturing_section",
"default_operating_cost_account",
"column_break_9prc",
"default_wip_warehouse",
"default_fg_warehouse",
"default_scrap_warehouse",
"dashboard_tab"
],
"fields": [
@@ -885,6 +889,31 @@
"fieldname": "enable_item_wise_inventory_account",
"fieldtype": "Check",
"label": "Enable Item-wise Inventory Account"
},
{
"fieldname": "default_wip_warehouse",
"fieldtype": "Link",
"label": " Default Work In Progress Warehouse ",
"link_filters": "[[\"Warehouse\",\"disabled\",\"=\",0]]",
"options": "Warehouse"
},
{
"fieldname": "default_fg_warehouse",
"fieldtype": "Link",
"label": "Default Finished Goods Warehouse",
"link_filters": "[[\"Warehouse\",\"disabled\",\"=\",0]]",
"options": "Warehouse"
},
{
"fieldname": "default_scrap_warehouse",
"fieldtype": "Link",
"label": "Default Scrap Warehouse",
"link_filters": "[[\"Warehouse\",\"disabled\",\"=\",0]]",
"options": "Warehouse"
},
{
"fieldname": "column_break_9prc",
"fieldtype": "Column Break"
}
],
"icon": "fa fa-building",
@@ -892,7 +921,7 @@
"image_field": "company_logo",
"is_tree": 1,
"links": [],
"modified": "2025-10-23 13:15:52.411984",
"modified": "2025-11-16 16:50:27.624096",
"modified_by": "Administrator",
"module": "Setup",
"name": "Company",

View File

@@ -59,6 +59,7 @@ class Company(NestedSet):
default_deferred_revenue_account: DF.Link | None
default_discount_account: DF.Link | None
default_expense_account: DF.Link | None
default_fg_warehouse: DF.Link | None
default_finance_book: DF.Link | None
default_holiday_list: DF.Link | None
default_in_transit_warehouse: DF.Link | None
@@ -69,8 +70,10 @@ class Company(NestedSet):
default_payable_account: DF.Link | None
default_provisional_account: DF.Link | None
default_receivable_account: DF.Link | None
default_scrap_warehouse: DF.Link | None
default_selling_terms: DF.Link | None
default_warehouse_for_sales_return: DF.Link | None
default_wip_warehouse: DF.Link | None
depreciation_cost_center: DF.Link | None
depreciation_expense_account: DF.Link | None
disposal_account: DF.Link | None

View File

@@ -495,6 +495,7 @@ frappe.ui.form.on("Material Request", {
method: "erpnext.stock.doctype.material_request.material_request.raise_work_orders",
args: {
material_request: frm.doc.name,
company: frm.doc.company,
},
freeze: true,
callback: function (r) {

View File

@@ -833,11 +833,11 @@ def make_stock_entry(source_name, target_doc=None):
@frappe.whitelist()
def raise_work_orders(material_request):
def raise_work_orders(material_request, company):
mr = frappe.get_doc("Material Request", material_request)
errors = []
work_orders = []
default_wip_warehouse = frappe.db.get_single_value("Manufacturing Settings", "default_wip_warehouse")
default_wip_warehouse = frappe.get_cached_value("Company", company, "default_wip_warehouse")
for d in mr.items:
if (d.stock_qty - d.ordered_qty) > 0:

View File

@@ -747,7 +747,7 @@ class TestMaterialRequest(IntegrationTestCase):
(mr.items[0].item_code, mr.items[0].warehouse),
)[0][0]
prod_order = raise_work_orders(mr.name)
prod_order = raise_work_orders(mr.name, mr.company)
po = frappe.get_doc("Work Order", prod_order[0])
po.wip_warehouse = "_Test Warehouse 1 - _TC"
po.submit()
@@ -789,7 +789,7 @@ class TestMaterialRequest(IntegrationTestCase):
self.assertEqual(requested_qty, existing_requested_qty + 120)
work_order = raise_work_orders(mr.name)
work_order = raise_work_orders(mr.name, mr.company)
wo = frappe.get_doc("Work Order", work_order[0])
wo.qty = 50
wo.wip_warehouse = "_Test Warehouse 1 - _TC"
@@ -924,7 +924,7 @@ class TestMaterialRequest(IntegrationTestCase):
item_code="_Test FG Item", material_request_type="Manufacture", do_not_submit=False
)
work_order = raise_work_orders(mr.name)
work_order = raise_work_orders(mr.name, mr.company)
wo = frappe.get_doc("Work Order", work_order[0])
wo.wip_warehouse = "_Test Warehouse 1 - _TC"
wo.submit()