[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:
@@ -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}`);
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
+26
-16
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user