[FIX] pos_sale: Correctly split lines when product are not groupable

Current behavior:
When importing a sale order with a product that is not groupable, the
line is not split and the whole quantity is added to one line.

Steps to reproduce:
- Create a new uom category that is not groupable
- Add a new uom to the category
- Create a new product with the uom
- Create a new sale order with the product
- Settle the order in the PoS
- All quantity is on one line

This is also an issue if the product is tracked by serial number. The
popup to fill the serial number will only have one field, even if the
quantity is greater than 1.

opw-3493378

closes odoo/odoo#141302

X-original-commit: 957942fe64391f9df7bee38d179cd1ce75fff787
Signed-off-by: Vlad Stroia (vlst) <vlst@odoo.com>
Signed-off-by: Robin Engels (roen) <roen@odoo.com>
This commit is contained in:
roen-odoo
2023-11-13 16:17:53 +00:00
parent bc81230311
commit 631dea3998
4 changed files with 88 additions and 16 deletions
@@ -412,3 +412,18 @@ export function addCustomerNote(note) {
].flat()
);
}
export function checkOrderlinesNumber(number) {
return [
{
content: `check orderlines number`,
trigger: `.order .orderlines .orderline`,
run: () => {
const orderline_amount = $('.order .orderlines .orderline').length;
if (orderline_amount !== number) {
throw new Error(`Expected ${number} orderlines, got ${orderline_amount}`);
}
},
},
];
}
@@ -207,21 +207,19 @@ export class SaleOrderManagementScreen extends ControlButtonsMixin(Component) {
continue;
}
const new_line = new Orderline(
{ env: this.env },
{
pos: this.pos,
order: this.pos.get_order(),
product: this.pos.db.get_product_by_id(line.product_id[0]),
description: line.name,
price: line.price_unit,
tax_ids: orderFiscalPos ? undefined : line.tax_id,
price_type: "manual",
sale_order_origin_id: clickedOrder,
sale_order_line_id: line,
customer_note: line.customer_note,
}
);
const line_values = {
pos: this.pos,
order: this.pos.get_order(),
product: this.pos.db.get_product_by_id(line.product_id[0]),
description: line.name,
price: line.price_unit,
tax_ids: orderFiscalPos ? undefined : line.tax_id,
price_manually_set: false,
sale_order_origin_id: clickedOrder,
sale_order_line_id: line,
customer_note: line.customer_note,
};
let new_line = new Orderline({ env: this.env }, line_values);
if (
new_line.get_product().tracking !== "none" &&
@@ -254,7 +252,19 @@ export class SaleOrderManagementScreen extends ControlButtonsMixin(Component) {
new_line.setQuantityFromSOL(line);
new_line.set_unit_price(line.price_unit);
new_line.set_discount(line.discount);
this.pos.get_order().add_orderline(new_line);
const product = this.pos.db.get_product_by_id(line.product_id[0]);
const product_unit = product.get_unit();
if (product_unit && !product.get_unit().is_pos_groupable) {
//loop for value of quantity
for (let j = 0; j < new_line.quantity; j++) {
let splitted_line = new Orderline({}, line_values);
splitted_line.quantity = 1;
this.pos.get_order().add_orderline(splitted_line);
}
}
else {
this.pos.get_order().add_orderline(new_line);
}
}
} else {
// apply a downpayment
@@ -134,3 +134,17 @@ registry.category("web_tour.tours").add("PosSettleOrder3", {
ReceiptScreen.isShown(),
].flat(),
});
registry
.category("web_tour.tours")
.add('PosSettleOrderNotGroupable', {
test: true,
url: '/pos/ui',
steps: () => [
ProductScreen.confirmOpeningPopup(),
ProductScreen.clickQuotationButton(),
ProductScreen.selectFirstOrder(),
ProductScreen.totalAmountIs(34.5),
ProductScreen.checkOrderlinesNumber(3),
].flat(),
});
@@ -294,3 +294,36 @@ class TestPoSSale(TestPointOfSaleHttpCommon):
self.assertEqual(sale_order.order_line[0].qty_delivered, 1)
self.assertEqual(sale_order.picking_ids.mapped('state'), ['cancel', 'cancel', 'cancel'])
def test_pos_not_groupable_product(self):
#Create a UoM Category that is not pos_groupable
uom_category = self.env['uom.category'].create({
'name': 'Test',
'is_pos_groupable': False,
})
uom = self.env['uom.uom'].create({
'name': 'Test',
'category_id': uom_category.id,
'uom_type': 'reference',
})
product_a = self.env['product.product'].create({
'name': 'Product A',
'available_in_pos': True,
'type': 'product',
'lst_price': 10.0,
'uom_id': uom.id,
'uom_po_id': uom.id,
})
#create a sale order with product_a
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': 3,
'product_uom': product_a.uom_id.id,
'price_unit': product_a.lst_price,
})],
})
self.main_pos_config.open_ui()
self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'PosSettleOrderNotGroupable', login="accountman")