物料申请过程做库存预留
物料申请阶段直接实现库存预留
在物料申请阶段直接实现库存预留,并根据不同的业务场景进行分类。我们可以扩展 Material Request
功能,结合生产计划和生产工单的预留逻辑。
下述方法为AI提供, 最终并未实践。
实现步骤-方法1
1. 添加自定义字段
为 Material Request
和 Material Request Item
添加自定义字段 reserved_qty
,用于记录预留数量。
- 路径:
自定义化 ➔ 自定义字段
- 为
Material Request Item
添加字段reserved_qty
(类型为 Float)
2. 编写自定义脚本
在提交物料申请时,根据不同的业务场景创建相应的库存预留逻辑。例如,如果物料申请类型是“Material Issue”,将其归类为生产计划,并创建库存预留。
python复制代码#
客户端脚本(Custom Script)
frappe.ui.form.on('Material Request', {
on_submit: function(frm) {
if (frm.doc.material_request_type === 'Material Issue') {
frm.doc.items.forEach(function(item) {
frappe.call({
method: 'erpnext.stock.doctype.stock_entry.stock_entry.make_stock_entry',
args: {
source_name: frm.doc.name,
target_doc: null,
args: {
item_code: item.item_code,
reserved_qty: item.qty,
purpose: 'Material Issue'
}
},
callback: function(r) {
if(!r.exc) {
frappe.msgprint(__('Stock Entry created for item {0}', [item.item_code]));
}
}
});
});
}
}
});
3. 修改服务器端逻辑
在服务器端处理库存预留逻辑时,根据 Material Request
的类型进行不同的处理。例如,对于“Material Issue”类型,将其处理为生产计划预留。
修改 make_stock_entry
方法:
python复制代码# 在 erpnext/stock/doctype/stock_entry/stock_entry.py 中
@frappe.whitelist()
def make_stock_entry(source_name, target_doc=None, args=None):
if args is None:
args = {}
if isinstance(args, str):
args = json.loads(args)
def update_item(obj, target, source_parent):
qty = flt(args.get('reserved_qty')) / target.conversion_factor
target.qty = qty
target.transfer_qty = qty * obj.conversion_factor
target.conversion_factor = obj.conversion_factor
if args.get('purpose') == 'Material Issue':
target.s_warehouse = obj.warehouse
elif args.get('purpose') == 'Material Transfer':
target.t_warehouse = obj.warehouse
doclist = get_mapped_doc(
"Material Request",
source_name,
{
"Material Request": {
"doctype": "Stock Entry",
"validation": {
"docstatus": ["=", 1],
"material_request_type": ["in", ["Material Transfer", "Material Issue", "Customer Provided"]],
},
},
"Material Request Item": {
"doctype": "Stock Entry Detail",
"field_map": {
"name": "material_request_item",
"parent": "material_request",
"uom": "stock_uom",
},
"postprocess": update_item,
"condition": lambda doc: (
flt(doc.ordered_qty, doc.precision("ordered_qty"))
< flt(doc.stock_qty, doc.precision("ordered_qty"))
),
},
},
target_doc,
set_missing_values,
)
return doclist
实现步骤-方法2
1. 服务端创建库存预留逻辑, 采用钩子中调用
在系统中创建一个处理库存预留的函数,根据 Material Request
的类型进行分类处理。
python复制代码
def reserve_stock_for_material_request(material_request):
for item in material_request.items:
reserve_stock(item.item_code, item.qty, material_request.company, material_request.material_request_type)
def reserve_stock(item_code, qty, company, request_type):
bin = frappe.get_doc('Bin', {'item_code': item_code, 'company': company})
if request_type == 'Material Issue':
bin.reserved_qty_for_production += qty
elif request_type == 'Purchase':
bin.reserved_qty_for_purchase += qty
# 其他类型的预留逻辑
bin.save()
# 在 Material Request 的提交钩子中调用
def on_submit(self):
self.reserve_stock_for_material_request(self)
总结
通过以上步骤,我们可以在物料申请阶段实现库存预留,并根据不同的业务场景(如生产计划、生产工单、采购等)进行分类处理。这样可以确保在物料申请提交时,系统会自动为相应的数量进行预留,从而满足业务需求。