mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-22 22:49:19 +00:00
fix: Batch selection logic
This commit is contained in:
@@ -77,7 +77,7 @@
|
|||||||
"options": "Pick List Item"
|
"options": "Pick List Item"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "work_order",
|
"depends_on": "eval:doc.purpose==='Material Transfer for Manufacture'",
|
||||||
"description": "Qty of raw materials will be decided based on the qty of the Finished Goods Item",
|
"description": "Qty of raw materials will be decided based on the qty of the Finished Goods Item",
|
||||||
"fieldname": "for_qty",
|
"fieldname": "for_qty",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
@@ -115,7 +115,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"modified": "2019-08-26 16:11:03.184637",
|
"modified": "2019-08-27 21:24:50.609986",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Pick List",
|
"name": "Pick List",
|
||||||
|
|||||||
@@ -55,13 +55,19 @@ class PickList(Document):
|
|||||||
def get_items_with_warehouse_and_quantity(item_doc, from_warehouses, item_location_map):
|
def get_items_with_warehouse_and_quantity(item_doc, from_warehouses, item_location_map):
|
||||||
available_locations = item_location_map.get(item_doc.item_code)
|
available_locations = item_location_map.get(item_doc.item_code)
|
||||||
locations = []
|
locations = []
|
||||||
|
skip_warehouse = None
|
||||||
|
|
||||||
|
if item_doc.material_request:
|
||||||
|
skip_warehouse = frappe.get_value('Material Request Item', item_doc.material_request_item, 'warehouse')
|
||||||
|
|
||||||
remaining_stock_qty = item_doc.stock_qty
|
remaining_stock_qty = item_doc.stock_qty
|
||||||
while remaining_stock_qty > 0 and available_locations:
|
while remaining_stock_qty > 0 and available_locations:
|
||||||
item_location = available_locations.pop(0)
|
item_location = available_locations.pop(0)
|
||||||
|
|
||||||
stock_qty = remaining_stock_qty if item_location.qty >= remaining_stock_qty else item_location.qty
|
stock_qty = remaining_stock_qty if item_location.qty >= remaining_stock_qty else item_location.qty
|
||||||
qty = stock_qty / (item_doc.conversion_factor or 1)
|
qty = stock_qty / (item_doc.conversion_factor or 1)
|
||||||
|
|
||||||
uom_must_be_whole_number = frappe.db.get_value("UOM", item_doc.uom, "must_be_whole_number")
|
uom_must_be_whole_number = frappe.db.get_value('UOM', item_doc.uom, 'must_be_whole_number')
|
||||||
if uom_must_be_whole_number:
|
if uom_must_be_whole_number:
|
||||||
qty = floor(qty)
|
qty = floor(qty)
|
||||||
stock_qty = qty * item_doc.conversion_factor
|
stock_qty = qty * item_doc.conversion_factor
|
||||||
@@ -131,7 +137,7 @@ def get_item_locations_based_on_serial_nos(item_doc):
|
|||||||
return locations
|
return locations
|
||||||
|
|
||||||
def get_item_locations_based_on_batch_nos(item_doc):
|
def get_item_locations_based_on_batch_nos(item_doc):
|
||||||
batch_qty = frappe.db.sql("""
|
batch_locations = frappe.db.sql("""
|
||||||
SELECT
|
SELECT
|
||||||
sle.`warehouse`,
|
sle.`warehouse`,
|
||||||
sle.`batch_no`,
|
sle.`batch_no`,
|
||||||
@@ -141,27 +147,30 @@ def get_item_locations_based_on_batch_nos(item_doc):
|
|||||||
WHERE
|
WHERE
|
||||||
sle.batch_no = batch.name
|
sle.batch_no = batch.name
|
||||||
and sle.`item_code`=%(item_code)s
|
and sle.`item_code`=%(item_code)s
|
||||||
and IFNULL(batch.expiry_date, '2200-01-01') > %(today)s
|
and IFNULL(batch.`expiry_date`, '2200-01-01') > %(today)s
|
||||||
GROUP BY
|
GROUP BY
|
||||||
`warehouse`,
|
`warehouse`,
|
||||||
`batch_no`,
|
`batch_no`,
|
||||||
`item_code`
|
`item_code`
|
||||||
HAVING `qty` > 0
|
HAVING `qty` > 0
|
||||||
ORDER BY IFNULL(batch.expiry_date, '2200-01-01')
|
ORDER BY IFNULL(batch.`expiry_date`, '2200-01-01'), batch.`creation`
|
||||||
""", {
|
""", {
|
||||||
'item_code': item_doc.item_code,
|
'item_code': item_doc.item_code,
|
||||||
'today': today()
|
'today': today()
|
||||||
}, as_dict=1)
|
}, as_dict=1)
|
||||||
|
|
||||||
locations = []
|
locations = []
|
||||||
required_qty = item_doc.qty
|
required_qty = item_doc.stock_qty
|
||||||
for d in batch_qty:
|
|
||||||
if d.qty > required_qty:
|
|
||||||
d.qty = required_qty
|
|
||||||
else:
|
|
||||||
required_qty -= d.qty
|
|
||||||
|
|
||||||
locations.append(d)
|
for batch_location in batch_locations:
|
||||||
|
if batch_location.qty >= required_qty:
|
||||||
|
# this batch should fulfill the required items
|
||||||
|
batch_location.qty = required_qty
|
||||||
|
required_qty = 0
|
||||||
|
else:
|
||||||
|
required_qty -= batch_location.qty
|
||||||
|
|
||||||
|
locations.append(batch_location)
|
||||||
|
|
||||||
if required_qty <= 0:
|
if required_qty <= 0:
|
||||||
break
|
break
|
||||||
@@ -171,7 +180,6 @@ def get_item_locations_based_on_batch_nos(item_doc):
|
|||||||
|
|
||||||
return locations
|
return locations
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def create_delivery_note(source_name, target_doc=None):
|
def create_delivery_note(source_name, target_doc=None):
|
||||||
pick_list = frappe.get_doc('Pick List', source_name)
|
pick_list = frappe.get_doc('Pick List', source_name)
|
||||||
@@ -199,7 +207,9 @@ def create_delivery_note(source_name, target_doc=None):
|
|||||||
|
|
||||||
if dn_item:
|
if dn_item:
|
||||||
dn_item.warehouse = location.warehouse
|
dn_item.warehouse = location.warehouse
|
||||||
dn_item.qty = location.qty
|
dn_item.qty = location.picked_qty
|
||||||
|
dn_item.batch_no = location.batch_no
|
||||||
|
dn_item.serial_no = location.serial_no
|
||||||
|
|
||||||
update_delivery_note_item(sales_order_item, dn_item, delivery_note)
|
update_delivery_note_item(sales_order_item, dn_item, delivery_note)
|
||||||
|
|
||||||
@@ -355,8 +365,8 @@ def update_stock_entry_based_on_work_order(pick_list, stock_entry):
|
|||||||
item.item_code = location.item_code
|
item.item_code = location.item_code
|
||||||
item.s_warehouse = location.warehouse
|
item.s_warehouse = location.warehouse
|
||||||
item.t_warehouse = wip_warehouse
|
item.t_warehouse = wip_warehouse
|
||||||
item.qty = location.qty
|
item.qty = location.picked_qty * location.conversion_factor
|
||||||
item.transfer_qty = location.stock_qty
|
item.transfer_qty = location.picked_qty
|
||||||
item.uom = location.uom
|
item.uom = location.uom
|
||||||
item.conversion_factor = location.conversion_factor
|
item.conversion_factor = location.conversion_factor
|
||||||
item.stock_uom = location.stock_uom
|
item.stock_uom = location.stock_uom
|
||||||
@@ -375,8 +385,8 @@ def update_stock_entry_based_on_material_request(pick_list, stock_entry):
|
|||||||
item.item_code = location.item_code
|
item.item_code = location.item_code
|
||||||
item.s_warehouse = location.warehouse
|
item.s_warehouse = location.warehouse
|
||||||
item.t_warehouse = target_warehouse
|
item.t_warehouse = target_warehouse
|
||||||
item.qty = location.qty
|
item.qty = location.picked_qty * location.conversion_factor
|
||||||
item.transfer_qty = location.stock_qty
|
item.transfer_qty = location.picked_qty
|
||||||
item.uom = location.uom
|
item.uom = location.uom
|
||||||
item.conversion_factor = location.conversion_factor
|
item.conversion_factor = location.conversion_factor
|
||||||
item.stock_uom = location.stock_uom
|
item.stock_uom = location.stock_uom
|
||||||
|
|||||||
Reference in New Issue
Block a user