From 696ea173d3f6cb1230444c34d6f19bc4519fda04 Mon Sep 17 00:00:00 2001 From: Prakash Prajapati Date: Tue, 16 Jun 2020 13:00:28 +0000 Subject: [PATCH] [IMP] sale: Apply discount on all SO lines onchage of first SO line Purpose fo the task is to Allow changing a discount for the whole SO. So in this commit, On a quotation, with "discount per line" option enabled, if the user changes the discount on the first SO line, display a pop-up requesting if they want to apply the change to all the lines of the SO. There is condition to open the confirmation dialog to change on all SO lines: 1. There should be 3 or more lines in SO 2. Happens only when changing the discount of the first SO line 3. The initial discount is the same on all lines For Ex: Example : a SO with a discount of 10% on all 6 SO lines. The user clicks the discount field on the first so line, changes to 20%. A pop-up "apply this discount to all quotation lines" -> if yes, apply 20% to all SO lines. closes odoo/odoo#54262 Taskid: 2276759 Closes: #54262 Signed-off-by: Yannick Tivisse (yti) --- .../static/src/js/product_discount_widget.js | 37 ++++++++++++ addons/sale/static/src/js/sale_order_view.js | 56 +++++++++++++++++++ addons/sale/views/assets.xml | 2 + addons/sale/views/sale_views.xml | 4 +- 4 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 addons/sale/static/src/js/product_discount_widget.js create mode 100644 addons/sale/static/src/js/sale_order_view.js diff --git a/addons/sale/static/src/js/product_discount_widget.js b/addons/sale/static/src/js/product_discount_widget.js new file mode 100644 index 00000000000..ede118000c0 --- /dev/null +++ b/addons/sale/static/src/js/product_discount_widget.js @@ -0,0 +1,37 @@ +odoo.define('sale.product_discount', function (require) { + "use strict"; + + const BasicFields = require('web.basic_fields'); + const FieldsRegistry = require('web.field_registry'); + + /** + * The sale.product_discount widget is a simple widget extending FieldFloat + * + * + * !!! WARNING !!! + * + * This widget is only designed for sale_order_line creation/updates. + * !!! It should only be used on a discount field !!! + */ + const ProductDiscountWidget = BasicFields.FieldFloat.extend({ + + /** + * Override changes at a discount. + * + * @override + * @param {OdooEvent} ev + * + */ + async reset(record, ev) { + if (ev && ev.data.changes && ev.data.changes.discount >= 0) { + this.trigger_up('open_discount_wizard'); + } + this._super(...arguments); + }, + }); + + FieldsRegistry.add('product_discount', ProductDiscountWidget); + + return ProductDiscountWidget; + +}); diff --git a/addons/sale/static/src/js/sale_order_view.js b/addons/sale/static/src/js/sale_order_view.js new file mode 100644 index 00000000000..6956f277e16 --- /dev/null +++ b/addons/sale/static/src/js/sale_order_view.js @@ -0,0 +1,56 @@ +odoo.define('sale.SaleOrderView', function (require) { + "use strict"; + + const FormController = require('web.FormController'); + const FormView = require('web.FormView'); + const viewRegistry = require('web.view_registry'); + const Dialog = require('web.Dialog'); + const core = require('web.core'); + const _t = core._t; + + const SaleOrderFormController = FormController.extend({ + custom_events: _.extend({}, FormController.prototype.custom_events, { + open_discount_wizard: '_onOpenDiscountWizard', + }), + + // ------------------------------------------------------------------------- + // Handlers + // ------------------------------------------------------------------------- + + /** + * Handler called if user changes the discount field in the sale order line. + * The wizard will open only if + * (1) Sale order line is 3 or more + * (2) First sale order line is changed to discount + * (3) Discount is the same in all sale order line + */ + _onOpenDiscountWizard(ev) { + const orderLines = this.renderer.state.data.order_line.data; + const recordData = ev.target.recordData; + const isEqualDiscount = orderLines.slice(1).every(line => line.data.discount === recordData.discount); + if (orderLines.length >= 3 && recordData.sequence === orderLines[0].data.sequence && isEqualDiscount) { + Dialog.confirm(this, _t("Do you want to apply this discount to all order lines?"), { + confirm_callback: () => { + orderLines.slice(1).forEach((line) => { + this.trigger_up('field_changed', { + dataPointID: this.renderer.state.id, + changes: {order_line: {operation: "UPDATE", id: line.id, data: {discount: orderLines[0].data.discount}}}, + }); + }); + }, + }); + } + }, + }); + + const SaleOrderView = FormView.extend({ + config: _.extend({}, FormView.prototype.config, { + Controller: SaleOrderFormController, + }), + }); + + viewRegistry.add('sale_discount_form', SaleOrderView); + + return SaleOrderView; + +}); diff --git a/addons/sale/views/assets.xml b/addons/sale/views/assets.xml index cc7b45a960f..2b78d5cc411 100644 --- a/addons/sale/views/assets.xml +++ b/addons/sale/views/assets.xml @@ -9,6 +9,8 @@