diff --git a/addons/point_of_sale/static/tests/tours/helpers/ProductScreenTourMethods.js b/addons/point_of_sale/static/tests/tours/helpers/ProductScreenTourMethods.js index f495068e6ae..02a082c8954 100644 --- a/addons/point_of_sale/static/tests/tours/helpers/ProductScreenTourMethods.js +++ b/addons/point_of_sale/static/tests/tours/helpers/ProductScreenTourMethods.js @@ -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}`); + } + }, + }, + ]; +} diff --git a/addons/pos_sale/static/src/app/order_management_screen/sale_order_management_screen/sale_order_management_screen.js b/addons/pos_sale/static/src/app/order_management_screen/sale_order_management_screen/sale_order_management_screen.js index 20ee787f496..0d2f3b384b9 100644 --- a/addons/pos_sale/static/src/app/order_management_screen/sale_order_management_screen/sale_order_management_screen.js +++ b/addons/pos_sale/static/src/app/order_management_screen/sale_order_management_screen/sale_order_management_screen.js @@ -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 diff --git a/addons/pos_sale/static/tests/tours/PosSaleTour.js b/addons/pos_sale/static/tests/tours/PosSaleTour.js index d8a1620becd..c32c86d461e 100644 --- a/addons/pos_sale/static/tests/tours/PosSaleTour.js +++ b/addons/pos_sale/static/tests/tours/PosSaleTour.js @@ -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(), + }); \ No newline at end of file diff --git a/addons/pos_sale/tests/test_pos_sale_flow.py b/addons/pos_sale/tests/test_pos_sale_flow.py index 435ae7c55e8..1f08ab13603 100644 --- a/addons/pos_sale/tests/test_pos_sale_flow.py +++ b/addons/pos_sale/tests/test_pos_sale_flow.py @@ -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")