production plan generated material request has following 2 issues
- all purchase related items in one material request, convert material request to following documents such as supplier quotation, purchase order etc need to be done manually one by one, normally by selecting the supplier
- even though there is safety stock and min purchase quantity, both it is same concept as min pack qty.
solution highlight
- auto split material request by default supplier defined in item master
2.auto round up qty per defined min pack qty in item master
technical details
- add custom field Purchase Vendor into material request, will be auto filled by server script
- add min pack qty custom field into item master, maintain it accordingly
- create custom server script for doc event for material request, code as below
if doc.material_request_type == 'Purchase' and not (doc.purchase_vendor and doc.flags.split_mr):
item_code_list = [item.item_code for item in doc.items]
qty_list = frappe.get_all("Item",
filters = {'item_code':('in', item_code_list),
'min_pack_qty': ('>',0)},
fields =['item_code','purchase_uom', 'stock_uom', 'min_pack_qty'])
#轏ć˘ćĺĺ
¸
qty_dict = {(item.item_code, item.purchase_uom or item.stock_uom):item.min_pack_qty for item in qty_list}
item_default_list = frappe.get_all('Item Default',
filters = {'company': doc.company,
'parent':('in', item_code_list)},
fields=['default_supplier','parent'])
supplier_item_map = {}
for item_default in item_default_list:
item_list = supplier_item_map.setdefault(item_default.default_supplier, [])
item_list.append(item_default.parent)
i = False
for (supplier, item_list) in supplier_item_map.items():
if not i:
first_supplier = supplier
first_mr_item_list = item_list
else:
new_mr = frappe.copy_doc(doc,ignore_no_copy=False)
new_mr.purchase_vendor = supplier
new_mr.flags.split_mr = True
items = []
for row in new_mr.items:
if row.item_code in item_list:
min_pack_qty = qty_dict.get((row.item_code, row.uom), 0)
if min_pack_qty:
Quotient = row.qty / min_pack_qty
rounded_quotient = frappe.utils.floor(Quotient)
if Quotient > rounded_quotient:
row.qty = (rounded_quotient + 1) * min_pack_qty
row.stock_qty = row.qty * row.conversion_factor
items.append(row)
new_mr.items = items
new_mr.insert()
i = True
doc.purchase_vendor = first_supplier
items = []
for row in doc.items:
if row.item_code in first_mr_item_list:
min_pack_qty = qty_dict.get((row.item_code, row.uom), 0)
if min_pack_qty:
Quotient = row.qty / min_pack_qty
rounded_quotient = frappe.utils.floor(Quotient)
if Quotient > rounded_quotient:
row.qty = (rounded_quotient + 1) * min_pack_qty
row.stock_qty = row.qty * row.conversion_factor
items.append(row)
doc.items = items