From b772cb4e1a51e51444ad01815cb7004888d988bb Mon Sep 17 00:00:00 2001 From: roen-odoo <roen@odoo.com> Date: Thu, 11 May 2023 12:31:21 +0000 Subject: [PATCH] [FIX] pos_sale: downpayment refund correctly added to origin order Current behavior: When you refund a downpayment in the PoS, the downpayment is not added to the original order. Steps to reproduce: - Create an order in the sales app - Open the PoS and make a downpayment for the order - Refund the downpayment you just made - Go back to the original order in the sales app, the downpayment is correctly added, but the refund of the downpayment is not added. - The order should contain : The original product, the downpayment and the refund of the downpayment. opw-3275708 closes odoo/odoo#125357 X-original-commit: 02a67b42071e5be14975b8aa745b37ff0e9e9e46 Signed-off-by: Joseph Caburnay (jcb) <jcb@odoo.com> Signed-off-by: Robin Engels (roen) <roen@odoo.com> --- addons/pos_sale/models/pos_order.py | 7 +++-- .../tests/helpers/ProductScreenTourMethods.js | 21 ++++++++++++++ .../static/tests/tours/pos_sale_tours.js | 23 +++++++++++++++ addons/pos_sale/tests/test_pos_sale_flow.py | 28 +++++++++++++++++++ 4 files changed, 76 insertions(+), 3 deletions(-) diff --git a/addons/pos_sale/models/pos_order.py b/addons/pos_sale/models/pos_order.py index 84b8ae61c58d..44302ca6706e 100644 --- a/addons/pos_sale/models/pos_order.py +++ b/addons/pos_sale/models/pos_order.py @@ -48,10 +48,11 @@ class PosOrder(models.Model): def create_from_ui(self, orders, draft=False): order_ids = super(PosOrder, self).create_from_ui(orders, draft) for order in self.sudo().browse([o['id'] for o in order_ids]): - for line in order.lines.filtered(lambda l: l.product_id == order.config_id.down_payment_product_id and l.qty > 0 and l.sale_order_origin_id): - sale_lines = line.sale_order_origin_id.order_line + for line in order.lines.filtered(lambda l: l.product_id == order.config_id.down_payment_product_id and l.qty != 0 and (l.sale_order_origin_id or l.refunded_orderline_id.sale_order_origin_id)): + sale_lines = line.sale_order_origin_id.order_line or line.refunded_orderline_id.sale_order_origin_id.order_line + sale_order_origin = line.sale_order_origin_id or line.refunded_orderline_id.sale_order_origin_id sale_line = self.env['sale.order.line'].create({ - 'order_id': line.sale_order_origin_id.id, + 'order_id': sale_order_origin.id, 'product_id': line.product_id.id, 'price_unit': line.price_unit, 'product_uom_qty': 0, diff --git a/addons/pos_sale/static/tests/helpers/ProductScreenTourMethods.js b/addons/pos_sale/static/tests/helpers/ProductScreenTourMethods.js index b24abaca629b..170e45758e2c 100644 --- a/addons/pos_sale/static/tests/helpers/ProductScreenTourMethods.js +++ b/addons/pos_sale/static/tests/helpers/ProductScreenTourMethods.js @@ -39,6 +39,27 @@ odoo.define('pos_sale.tour.ProductScreenTourMethods', function (require) { } ]; } + + downPaymentFirstOrder() { + return [ + { + content: `select order`, + trigger: `.order-row .col.name:first`, + }, + { + content: `click on select the order`, + trigger: `.selection-item:contains('Apply a down payment')`, + }, + { + content: `click on +10 button`, + trigger: `.mode-button.add:contains('+10')`, + }, + { + content: `click on ok button`, + trigger: `.button.confirm`, + } + ]; + } } return createTourMethods('ProductScreen', DoExt, Check, Execute); }); diff --git a/addons/pos_sale/static/tests/tours/pos_sale_tours.js b/addons/pos_sale/static/tests/tours/pos_sale_tours.js index 5611761491d7..f43d75f6665a 100644 --- a/addons/pos_sale/static/tests/tours/pos_sale_tours.js +++ b/addons/pos_sale/static/tests/tours/pos_sale_tours.js @@ -5,6 +5,7 @@ odoo.define('pos_sale.tour', function (require) { const { PaymentScreen } = require('point_of_sale.tour.PaymentScreenTourMethods'); const { ProductScreen } = require('pos_sale.tour.ProductScreenTourMethods'); const { ReceiptScreen } = require('point_of_sale.tour.ReceiptScreenTourMethods'); + const { TicketScreen } = require('point_of_sale.tour.TicketScreenTourMethods'); const { getSteps, startSteps } = require('point_of_sale.tour.utils'); const Tour = require('web_tour.tour'); @@ -74,4 +75,26 @@ odoo.define('pos_sale.tour', function (require) { Chrome.do.clickTicketButton(); Tour.register('PosSettleOrderRealTime', { test: true, url: '/pos/ui' }, getSteps()); + + startSteps(); + + ProductScreen.do.clickQuotationButton(); + ProductScreen.do.downPaymentFirstOrder(); + ProductScreen.do.clickPayButton(); + PaymentScreen.do.clickPaymentMethod('Cash'); + PaymentScreen.do.clickValidate(); + ReceiptScreen.do.clickNextOrder(); + ProductScreen.do.clickRefund(); + // Filter should be automatically 'Paid'. + TicketScreen.check.filterIs('Paid'); + TicketScreen.do.selectOrder('-0001'); + TicketScreen.do.clickOrderline('Down Payment'); + TicketScreen.do.pressNumpad('1'); + TicketScreen.do.confirmRefund(); + ProductScreen.do.clickPayButton(); + PaymentScreen.do.clickPaymentMethod('Cash'); + PaymentScreen.do.clickValidate(); + ReceiptScreen.do.clickNextOrder(); + + Tour.register('PosRefundDownpayment', { test: true, url: '/pos/ui' }, getSteps()); }); diff --git a/addons/pos_sale/tests/test_pos_sale_flow.py b/addons/pos_sale/tests/test_pos_sale_flow.py index 4aee005bb682..25182cc501a8 100644 --- a/addons/pos_sale/tests/test_pos_sale_flow.py +++ b/addons/pos_sale/tests/test_pos_sale_flow.py @@ -228,3 +228,31 @@ class TestPoSSale(TestPointOfSaleHttpCommon): self.assertEqual(pos_order.picking_ids.move_line_ids[1].qty_done, 2) self.assertEqual(pos_order.picking_ids.move_line_ids[1].location_id.id, self.shelf_2.id) self.assertEqual(sale_order.order_line.move_ids.move_lines_count, 0) + + def test_downpayment_refund(self): + #create a sale order + sale_order = self.env['sale.order'].create({ + 'partner_id': self.env.ref('base.res_partner_2').id, + 'order_line': [(0, 0, { + 'product_id': self.product_a.id, + 'name': self.product_a.name, + 'product_uom_qty': 1, + 'price_unit': 100, + 'product_uom': self.product_a.uom_id.id + })], + }) + sale_order.action_confirm() + #set downpayment product in pos config + self.downpayment_product = self.env['product.product'].create({ + 'name': 'Down Payment', + 'available_in_pos': True, + 'type': 'service', + }) + self.main_pos_config.write({ + 'down_payment_product_id': self.downpayment_product.id, + }) + self.main_pos_config.open_ui() + self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'PosRefundDownpayment', login="accountman") + self.assertEqual(len(sale_order.order_line), 3) + self.assertEqual(sale_order.order_line[1].qty_invoiced, 1) + self.assertEqual(sale_order.order_line[2].qty_invoiced, -1) -- GitLab