diff --git a/addons/point_of_sale/models/stock_picking.py b/addons/point_of_sale/models/stock_picking.py index b08d9b5f926..281aa3312d9 100644 --- a/addons/point_of_sale/models/stock_picking.py +++ b/addons/point_of_sale/models/stock_picking.py @@ -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']: diff --git a/addons/point_of_sale/tests/test_point_of_sale_flow.py b/addons/point_of_sale/tests/test_point_of_sale_flow.py index 6d4e6d5931f..4b3fcf18beb 100644 --- a/addons/point_of_sale/tests/test_point_of_sale_flow.py +++ b/addons/point_of_sale/tests/test_point_of_sale_flow.py @@ -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)