[FIX] point_of_sale: correctly order lots in picking

Current behavior:
When you make an order in the PoS with different lots for the same
product, the lots are not correctly selected in the picking. And only
one lot is affected by the order.

Steps to reproduce:
- Create a product with tracking by lot, and 2 lots with some quantity
- Create a PoS order with 2 lines of the same product, and select a
  different lot for each line
- Validate the order
- Close the PoS session
- Check the picking, and the lot quantities

Note:
This partly revert this part of commit :
https://github.com/odoo/odoo/commit/7dda6bb92715ea25b2818a62fec5e646f3678b81#diff-0ef4eb66998f308afe5f09748bc2af04ad79e9647507c25fe9007e03a79a1249L265-L303
And also make sure that the original created line quantity is set to 0
so that the each lot has a line, and the total quantity is correct.

opw-3621363

closes odoo/odoo#148517

Signed-off-by: Robin Heinz (rhe) <rhe@odoo.com>
This commit is contained in:
roen-odoo
2024-02-15 17:11:08 +00:00
parent 4f2975a662
commit a59e5f71cd
2 changed files with 108 additions and 1 deletions
+26 -1
View File
@@ -242,9 +242,34 @@ class StockMove(models.Model):
move.quantity = move.product_uom_qty
moves_remaining = self - moves_to_assign
existing_lots = moves_remaining._create_production_lots_for_pos_order(related_order_lines)
move_lines_to_create = []
mls_qties = []
if are_qties_done:
for move in moves_remaining:
move.quantity = move.product_uom_qty
move.move_line_ids.quantity = 0
for line in lines_data[move.product_id.id]['order_lines']:
sum_of_lots = 0
for lot in line.pack_lot_ids.filtered(lambda l: l.lot_name):
qty = 1 if line.product_id.tracking == 'serial' else abs(line.qty)
ml_vals = dict(move._prepare_move_line_vals(qty))
if existing_lots:
existing_lot = existing_lots.filtered_domain([('product_id', '=', line.product_id.id), ('name', '=', lot.lot_name)])
quant = self.env['stock.quant']
if existing_lot:
quant = self.env['stock.quant'].search(
[('lot_id', '=', existing_lot.id), ('quantity', '>', '0.0'), ('location_id', 'child_of', move.location_id.id)],
order='id desc',
limit=1
)
ml_vals.update({
'quant_id': quant.id,
})
else:
ml_vals.update({'lot_name': lot.lot_name})
move_lines_to_create.append(ml_vals)
mls_qties.append(qty)
sum_of_lots += qty
self.env['stock.move.line'].create(move_lines_to_create)
else:
for move in moves_remaining:
for line in lines_data[move.product_id.id]['order_lines']:
@@ -1918,3 +1918,85 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
self.assertEqual(refund.amount_total, -49.99)
self.assertEqual(refund.amount_paid, -50.0)
self.assertEqual(current_session.state, 'closed')
def test_order_different_lots(self):
self.pos_config.open_ui()
current_session = self.pos_config.current_session_id
self.stock_location = self.company_data['default_warehouse'].lot_stock_id
self.product2 = self.env['product.product'].create({
'name': 'Product A',
'type': 'product',
'tracking': 'lot',
})
lot1 = self.env['stock.lot'].create({
'name': '1001',
'product_id': self.product2.id,
})
lot2 = self.env['stock.lot'].create({
'name': '1002',
'product_id': self.product2.id,
})
quant1 = self.env['stock.quant'].with_context(inventory_mode=True).create({
'product_id': self.product2.id,
'inventory_quantity': 5,
'location_id': self.stock_location.id,
'lot_id': lot1.id
})
quant1.action_apply_inventory()
quant2 = self.env['stock.quant'].with_context(inventory_mode=True).create({
'product_id': self.product2.id,
'inventory_quantity': 5,
'location_id': self.stock_location.id,
'lot_id': lot2.id
})
quant2.action_apply_inventory()
order = self.PosOrder.create({
'company_id': self.env.company.id,
'session_id': current_session.id,
'partner_id': self.partner1.id,
'lines': [(0, 0, {
'name': "OL/0001",
'product_id': self.product2.id,
'price_unit': 6,
'discount': 0,
'qty': 2,
'tax_ids': [[6, False, []]],
'price_subtotal': 12,
'price_subtotal_incl': 12,
'pack_lot_ids': [
[0, 0, {'lot_name': '1001'}],
]
}),
(0, 0, {
'name': "OL/0002",
'product_id': self.product2.id,
'price_unit': 6,
'discount': 0,
'qty': 1,
'tax_ids': [[6, False, []]],
'price_subtotal': 6,
'price_subtotal_incl': 6,
'pack_lot_ids': [
[0, 0, {'lot_name': '1002'}],
]
})],
'pricelist_id': self.pos_config.pricelist_id.id,
'amount_paid': 18.0,
'amount_total': 18.0,
'amount_tax': 0.0,
'amount_return': 0.0,
'to_invoice': False,
'last_order_preparation_change': '{}'
})
payment_context = {"active_ids": order.ids, "active_id": order.id}
order_payment = self.PosMakePayment.with_context(**payment_context).create({
'amount': order.amount_total,
'payment_method_id': self.bank_payment_method.id
})
order_payment.with_context(**payment_context).check()
self.pos_config.current_session_id.action_pos_session_closing_control()
self.assertEqual(quant2.quantity, 4)
self.assertEqual(quant1.quantity, 3)