From 856c2e9008f1af7bc1327d9c2900db1e109ab0fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Warnon?= Date: Thu, 30 Aug 2018 11:59:54 +0200 Subject: [IMP] product,(website_)sale: Move product options configurator into sale module Task #1871557 Purpose ======= - Configure a product from a sales order as easily as in the ecommerce The backend uses the same template as the frontend to configure a products and its options - Display optionnal products of optionnal products in the "sale options" section - Allow adding exlusions to some combinations of the product and/or to some combinations of the optionnal and accessory products Specification ============= PHASE I 1. Improve the "Add to cart" with optional products - When you add an option to cart, move the product to the cart & show the options of this option - Don't open the option wizard if no option available (in case this module becomes generic, it's better to skip this step when it's not needed) - Display the options right under their related product in the cart 2. Do not allow to add the product as an optional product for itself Why ? - No functional sense - Creates issues in the add to cart wizard 3. Exclude some attribute combinations within the product or with related options and accessory products - Rename VARIANT PRICES button -> CONFIGURE VARIANTS - When you click this button and select a value, open form view rather than inline edition - Form view of variant values: - Attribute - Value - HTML Color Index - Attribute Price Extra - Not Compatible with: o2m tab with 2 fields: Product AND Attribute Value (of this product) [m2m tag selection] - in any new line, autocomplete the current product by default - Tooltip: A list of product and attribute values that you want to exclude for this product's attribue value. Also applies on optionnal and accessory products. 4. New option to configure a product in a sales order line - This option is only visible if the corresponding option is activated in the sales settings - It opens a wizard to select a product template, configure related attribute values and select optional products (based on frontend view) - Attributes not compatible with other selected attributes should not be selectable - Must work like in the frontend --- addons/web/static/src/js/fields/abstract_field.js | 1 + addons/web/static/src/js/fields/relational_fields.js | 10 ++++++++-- addons/web/static/src/js/views/basic/basic_model.js | 6 ++++-- addons/web/static/src/js/views/field_manager_mixin.js | 2 +- addons/web/static/src/js/views/list/list_editable_renderer.js | 2 +- 5 files changed, 15 insertions(+), 6 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/fields/abstract_field.js b/addons/web/static/src/js/fields/abstract_field.js index 2ea40a2602b..37d2f22ef55 100644 --- a/addons/web/static/src/js/fields/abstract_field.js +++ b/addons/web/static/src/js/fields/abstract_field.js @@ -496,6 +496,7 @@ var AbstractField = Widget.extend({ viewType: this.viewType, doNotSetDirty: options && options.doNotSetDirty, notifyChange: !options || options.notifyChange !== false, + allowWarning: options && options.allowWarning, onSuccess: def.resolve.bind(def), onFailure: def.reject.bind(def), }); diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js index 7a428923608..3f64c0249cb 100644 --- a/addons/web/static/src/js/fields/relational_fields.js +++ b/addons/web/static/src/js/fields/relational_fields.js @@ -1461,7 +1461,7 @@ var FieldOne2Many = FieldX2Many.extend({ // we don't want interference with the components upstream. ev.stopPropagation(); - if (this.editable) { + if (this.editable || data.forceEditable) { if (!this.activeActions.create) { if (data.onFail) { data.onFail(); @@ -1471,10 +1471,16 @@ var FieldOne2Many = FieldX2Many.extend({ this.trigger_up('edited_list', { id: this.value.id }); this._setValue({ operation: 'CREATE', - position: this.editable, + position: this.editable || data.forceEditable, context: data.context, + }, { + allowWarning: data.allowWarning }).always(function () { self.creatingRecord = false; + }).done(function(){ + if(data.onSuccess){ + data.onSuccess(); + } }); } } else { diff --git a/addons/web/static/src/js/views/basic/basic_model.js b/addons/web/static/src/js/views/basic/basic_model.js index ac7187c3874..84e900021e8 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -1344,6 +1344,7 @@ var BasicModel = AbstractModel.extend({ parentID: list.id, position: position, viewType: list.viewType, + allowWarning: options && options.allowWarning }; return this._makeDefaultRecord(list.model, params).then(function (id) { list._changes.push({operation: 'ADD', id: id, position: position, isNew: true}); @@ -1395,7 +1396,7 @@ var BasicModel = AbstractModel.extend({ for (var fieldName in changes) { field = record.fields[fieldName]; if (field.type === 'one2many' || field.type === 'many2many') { - defs.push(this._applyX2ManyChange(record, fieldName, changes[fieldName], options.viewType)); + defs.push(this._applyX2ManyChange(record, fieldName, changes[fieldName], options.viewType, options.allowWarning)); } else if (field.type === 'many2one' || field.type === 'reference') { defs.push(this._applyX2OneChange(record, fieldName, changes[fieldName])); } else { @@ -1724,7 +1725,7 @@ var BasicModel = AbstractModel.extend({ * main viewType from the record * @returns {Deferred} */ - _applyX2ManyChange: function (record, fieldName, command, viewType) { + _applyX2ManyChange: function (record, fieldName, command, viewType, allowWarning) { if (command.operation === 'TRIGGER_ONCHANGE') { // the purpose of this operation is to trigger an onchange RPC, so // there is no need to apply any change on the record (the changes @@ -1819,6 +1820,7 @@ var BasicModel = AbstractModel.extend({ var options = { context: command.context, position: command.position, + allowWarning: allowWarning }; def = this._addX2ManyDefaultRecord(list, options).then(function (id) { if (command.position === 'bottom' && list.orderedResIDs && list.orderedResIDs.length >= list.limit) { diff --git a/addons/web/static/src/js/views/field_manager_mixin.js b/addons/web/static/src/js/views/field_manager_mixin.js index cf67b9dd18d..343730cc7a4 100644 --- a/addons/web/static/src/js/views/field_manager_mixin.js +++ b/addons/web/static/src/js/views/field_manager_mixin.js @@ -46,7 +46,7 @@ var FieldManagerMixin = { */ _applyChanges: function (dataPointID, changes, event) { var self = this; - var options = _.pick(event.data, 'context', 'doNotSetDirty', 'notifyChange', 'viewType'); + var options = _.pick(event.data, 'context', 'doNotSetDirty', 'notifyChange', 'viewType', 'allowWarning'); return this.model.notifyChanges(dataPointID, changes, options) .then(function (result) { if (event.data.force_save) { diff --git a/addons/web/static/src/js/views/list/list_editable_renderer.js b/addons/web/static/src/js/views/list/list_editable_renderer.js index 33224a0fec2..841a8e7d4d8 100644 --- a/addons/web/static/src/js/views/list/list_editable_renderer.js +++ b/addons/web/static/src/js/views/list/list_editable_renderer.js @@ -61,7 +61,7 @@ ListRenderer.include({ } _.each(child.children, function (child) { - if (child.tag !== 'create') { + if (child.tag !== 'create' || child.attrs.invisible) { return; } -- cgit v1.2.3