Documentation Index Fetch the complete documentation index at: https://mintlify.com/frappe/erpnext/llms.txt
Use this file to discover all available pages before exploring further.
Manufacturing Module API
The Manufacturing module provides APIs for production planning, bill of materials (BOM) management, work orders, and job cards.
Work Order APIs
make_stock_entry
Create stock entries for work orders to record material consumption or finished goods.
import frappe
# Create material transfer for work order
stock_entry = frappe.call(
"erpnext.manufacturing.doctype.work_order.work_order.make_stock_entry" ,
work_order_id = "MFG-WO-2024-00001" ,
purpose = "Material Transfer for Manufacture" ,
qty = 10
)
Purpose: “Material Transfer for Manufacture”, “Material Consumption for Manufacture”, or “Manufacture”
Quantity for the stock entry (defaults to work order quantity)
Stock Entry document with pre-filled items from work order
stock_entry_type: Type of entry
purpose: Entry purpose
work_order: Reference to work order
from_bom: Whether items are from BOM
bom_no: BOM reference
fg_completed_qty: Finished goods quantity
items: List of items with quantities and warehouses
Bill of Materials (BOM) APIs
get_bom_items
Retrieve all items from a BOM including sub-assemblies.
items = frappe.call(
"erpnext.manufacturing.doctype.bom.bom.get_bom_items" ,
bom = "BOM-LAPTOP-001" ,
company = "Company A" ,
qty = 1 ,
fetch_exploded = 1
)
Quantity multiplier for calculating required materials
Whether to explode sub-assemblies (1) or show as-is (0)
List of BOM items
item_code: Item code
item_name: Item name
qty: Required quantity
rate: Item rate
amount: Total amount
stock_uom: Stock UOM
source_warehouse: Default source warehouse
description: Item description
get_children
Get child items in BOM tree structure for hierarchical display.
children = frappe.call(
"erpnext.manufacturing.doctype.bom.bom.get_children" ,
parent = "BOM-LAPTOP-001" ,
is_root = False
)
Parent BOM name (null for root level)
Whether fetching root level items
List of child items with tree structure information
get_bom_diff
Compare two BOMs and get differences.
diff = frappe.call(
"erpnext.manufacturing.doctype.bom.bom.get_bom_diff" ,
bom1 = "BOM-LAPTOP-001" ,
bom2 = "BOM-LAPTOP-002"
)
Dictionary containing added, removed, and changed items
Job Card APIs
make_stock_entry (Job Card)
Create stock entry from job card for semi-finished or finished goods.
stock_entry = frappe.call(
"erpnext.manufacturing.doctype.job_card.job_card.make_stock_entry" ,
source_name = "JOB-CARD-00001"
)
Existing stock entry document to update
Stock Entry document mapped from job card
BOM Operations
update_cost
Update BOM costs based on current rates.
bom = frappe.get_doc( "BOM" , "BOM-LAPTOP-001" )
bom.update_cost(
update_parent = True ,
from_child_bom = False ,
update_hour_rate = True ,
save = True
)
Whether update is triggered from child BOM
Update operation hour rates
Save the document after updating
Updates BOM costs in place
get_bom_material_detail
Get material details for adding items to BOM.
bom = frappe.get_doc( "BOM" , "BOM-LAPTOP-001" )
details = bom.get_bom_material_detail(
args = {
"item_code" : "CPU-INTEL-I7" ,
"bom_no" : "BOM-LAPTOP-001" ,
"qty" : 1
}
)
Dictionary with item_code, bom_no, and qty
Material details including rate, UOM, and description
Blanket Order APIs
make_order
Create sales or purchase order from blanket order.
order = frappe.call(
"erpnext.manufacturing.doctype.blanket_order.blanket_order.make_order" ,
source_name = "BLK-ORD-00001"
)
Sales Order or Purchase Order document
Usage Examples
Creating Work Order and Material Transfer
import frappe
# Create work order
work_order = frappe.get_doc({
"doctype" : "Work Order" ,
"production_item" : "LAPTOP-001" ,
"bom_no" : "BOM-LAPTOP-001" ,
"qty" : 10 ,
"company" : "Manufacturing Inc" ,
"wip_warehouse" : "Work In Progress - MI" ,
"fg_warehouse" : "Finished Goods - MI" ,
"source_warehouse" : "Stores - MI"
})
work_order.insert()
work_order.submit()
# Create material transfer
stock_entry = frappe.call(
"erpnext.manufacturing.doctype.work_order.work_order.make_stock_entry" ,
work_order_id = work_order.name,
purpose = "Material Transfer for Manufacture"
)
# Save and submit
se_doc = frappe.get_doc(stock_entry)
se_doc.insert()
se_doc.submit()
print ( f "Material transferred: { se_doc.name } " )
Getting BOM Details and Costs
import frappe
# Get BOM items
items = frappe.call(
"erpnext.manufacturing.doctype.bom.bom.get_bom_items" ,
bom = "BOM-LAPTOP-001" ,
company = "Manufacturing Inc" ,
qty = 100 , # For 100 laptops
fetch_exploded = 1 # Get all sub-assembly items
)
total_cost = 0
for item in items:
print ( f "Item: { item[ 'item_code' ] } , Qty: { item[ 'qty' ] } , Amount: { item[ 'amount' ] } " )
total_cost += item[ 'amount' ]
print ( f "Total Material Cost for 100 units: { total_cost } " )
Managing BOM Hierarchy
import frappe
# Get root level items
root_items = frappe.call(
"erpnext.manufacturing.doctype.bom.bom.get_children" ,
parent = None ,
is_root = True
)
# Get children of specific BOM
children = frappe.call(
"erpnext.manufacturing.doctype.bom.bom.get_children" ,
parent = "BOM-LAPTOP-001" ,
is_root = False
)
for child in children:
print ( f "Child Item: { child.get( 'value' ) } (Expandable: { child.get( 'expandable' ) } )" )
Comparing BOMs
import frappe
# Compare two BOM versions
diff = frappe.call(
"erpnext.manufacturing.doctype.bom.bom.get_bom_diff" ,
bom1 = "BOM-LAPTOP-001" ,
bom2 = "BOM-LAPTOP-002"
)
print ( "Added Items:" , diff.get( 'added' , []))
print ( "Removed Items:" , diff.get( 'removed' , []))
print ( "Changed Items:" , diff.get( 'changed' , []))
Recording Production with Stock Entry
import frappe
# Create manufacture entry (finish production)
stock_entry = frappe.call(
"erpnext.manufacturing.doctype.work_order.work_order.make_stock_entry" ,
work_order_id = "MFG-WO-2024-00001" ,
purpose = "Manufacture" ,
qty = 10 # Finished 10 units
)
se_doc = frappe.get_doc(stock_entry)
# Modify if needed
se_doc.posting_date = "2024-03-15"
# Submit
se_doc.insert()
se_doc.submit()
print ( f "Production recorded: { se_doc.name } " )
print ( f "Finished Goods: { se_doc.fg_completed_qty } units" )
Updating BOM Costs
import frappe
# Get BOM and update costs
bom = frappe.get_doc( "BOM" , "BOM-LAPTOP-001" )
# Update based on latest item rates
bom.update_cost(
update_parent = True ,
from_child_bom = False ,
update_hour_rate = True ,
save = True
)
print ( f "Updated BOM Cost: { bom.total_cost } " )
print ( f "Operating Cost: { bom.operating_cost } " )
print ( f "Raw Material Cost: { bom.raw_material_cost } " )
Advanced Operations
Creating Multi-level BOM
import frappe
# Create sub-assembly BOM
sub_bom = frappe.get_doc({
"doctype" : "BOM" ,
"item" : "MOTHERBOARD-001" ,
"quantity" : 1 ,
"company" : "Manufacturing Inc" ,
"items" : [
{
"item_code" : "CPU-INTEL-I7" ,
"qty" : 1 ,
"rate" : 300
},
{
"item_code" : "RAM-16GB" ,
"qty" : 2 ,
"rate" : 50
}
]
})
sub_bom.insert()
sub_bom.submit()
# Create main BOM using sub-assembly
main_bom = frappe.get_doc({
"doctype" : "BOM" ,
"item" : "LAPTOP-001" ,
"quantity" : 1 ,
"company" : "Manufacturing Inc" ,
"items" : [
{
"item_code" : "MOTHERBOARD-001" ,
"qty" : 1 ,
"bom_no" : sub_bom.name # Link to sub-assembly BOM
},
{
"item_code" : "LCD-SCREEN-15" ,
"qty" : 1 ,
"rate" : 150
}
]
})
main_bom.insert()
main_bom.submit()
print ( f "Main BOM: { main_bom.name } with sub-assembly: { sub_bom.name } " )