[FIX] pos_sale: correctly update move qty when settling a pos order

Current behavior:
When settling a pos order containing 2 different product, the qty of the
2 products would be modified even if you only deliver one of them
through the pos order.

Steps to reproduce:
- Create 2 product A and B
- Create a sale order with 1 product A and 1 product B
- Open a PoS session, and settle the order you just created
- Deliver only 1 product A
- Close the PoS session
- Go the the sale order delivery, you will see that the qty are not
  correct

opw-3227053

closes odoo/odoo#120898

X-original-commit: c1f905111060fff6e6bdfae1849e1a633a88ae02
Signed-off-by: Joseph Caburnay (jcb) <jcb@odoo.com>
Signed-off-by: Engels Robin (roen) <roen@odoo.com>
This commit is contained in:
roen-odoo
2023-05-10 16:36:49 +02:00
parent 9575aba9ca
commit a25d20ee3e
3 changed files with 74 additions and 1 deletions
+5 -1
View File
@@ -76,7 +76,8 @@ class PosOrder(models.Model):
# track the waiting pickings
waiting_picking_ids = set()
for so_line in so_lines:
for stock_move in so_line.move_ids.group_id.stock_move_ids:
so_line_stock_move_ids = so_line.move_ids.group_id.stock_move_ids
for stock_move in so_line.move_ids:
picking = stock_move.picking_id
if not picking.state in ['waiting', 'confirmed', 'assigned']:
continue
@@ -84,6 +85,9 @@ class PosOrder(models.Model):
if float_compare(new_qty, 0, precision_rounding=stock_move.product_uom.rounding) <= 0:
new_qty = 0
stock_move.product_uom_qty = so_line.compute_uom_qty(new_qty, stock_move, False)
#If the product is delivered with more than one step, we need to update the quantity of the other steps
for move in so_line_stock_move_ids.filtered(lambda m: m.state in ['waiting', 'confirmed'] and m.product_id == stock_move.product_id):
move.product_uom_qty = stock_move.product_uom_qty
waiting_picking_ids.add(picking.id)
def is_product_uom_qty_zero(move):
@@ -44,3 +44,21 @@ ProductScreen.check.selectedOrderlineHas('product2', 1);
ProductScreen.check.totalAmountIs("11.00");
registry.category("web_tour.tours").add('PosSettleOrderIncompatiblePartner', { test: true, url: '/pos/ui', steps: getSteps() });
startSteps();
ProductScreen.do.confirmOpeningPopup();
ProductScreen.do.clickQuotationButton();
ProductScreen.do.selectFirstOrder();
ProductScreen.do.clickOrderline("Product A", "1");
ProductScreen.check.selectedOrderlineHas('Product A', '1.00');
ProductScreen.do.clickOrderline("Product B", "1");
ProductScreen.do.pressNumpad('Qty 0');
ProductScreen.check.selectedOrderlineHas('Product B', '0.00');
ProductScreen.do.clickPayButton();
PaymentScreen.do.clickPaymentMethod('Bank');
PaymentScreen.check.remainingIs('0.0');
PaymentScreen.do.clickValidate();
ReceiptScreen.check.isShown();
registry.category("web_tour.tours").add('PosSettleOrder2', { test: true, url: '/pos/ui', steps: getSteps() });
@@ -102,3 +102,54 @@ class TestPoSSale(TestPointOfSaleHttpCommon):
})
self.main_pos_config.open_ui()
self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'PosSettleOrderIncompatiblePartner', login="accountman")
def test_settle_order_with_different_product(self):
"""This test create an order and settle it in the PoS. But only one of the product is delivered.
And we need to make sure the quantity are correctly updated on the sale order.
"""
#create 2 products
product_a = self.env['product.product'].create({
'name': 'Product A',
'available_in_pos': True,
'type': 'product',
'lst_price': 10.0,
})
product_b = self.env['product.product'].create({
'name': 'Product B',
'available_in_pos': True,
'type': 'product',
'lst_price': 10.0,
})
#create a sale order with 2 lines
sale_order = self.env['sale.order'].create({
'partner_id': self.env.ref('base.res_partner_2').id,
'order_line': [(0, 0, {
'product_id': product_a.id,
'name': product_a.name,
'product_uom_qty': 1,
'product_uom': product_a.uom_id.id,
'price_unit': product_a.lst_price,
}), (0, 0, {
'product_id': product_b.id,
'name': product_b.name,
'product_uom_qty': 1,
'product_uom': product_b.uom_id.id,
'price_unit': product_b.lst_price,
})],
})
sale_order.action_confirm()
self.assertEqual(sale_order.order_line[0].qty_delivered, 0)
self.assertEqual(sale_order.order_line[1].qty_delivered, 0)
self.main_pos_config.open_ui()
self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'PosSettleOrder2', login="accountman")
self.assertEqual(sale_order.order_line[0].qty_delivered, 1)
self.assertEqual(sale_order.order_line[1].qty_delivered, 0)
orderline_product_a = sale_order.order_line.filtered(lambda l: l.product_id.id == product_a.id)
orderline_product_b = sale_order.order_line.filtered(lambda l: l.product_id.id == product_b.id)
# nothing to deliver for product a because already handled in pos.
self.assertEqual(orderline_product_a.move_ids.product_uom_qty, 0)
# 1 item to deliver for product b.
self.assertEqual(orderline_product_b.move_ids.product_uom_qty, 1)