diff --git a/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/quick_create_form_view.js b/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/quick_create_form_view.js index d42a19482..579d79f89 100644 --- a/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/quick_create_form_view.js +++ b/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/quick_create_form_view.js @@ -255,6 +255,7 @@ odoo.define("web_widget_one2many_product_picker.ProductPickerQuickCreateFormView viewType: "form", }).then(function () { var record = self.model.get(self.handle); + self.model.updateRecordContext(self.handle, {saving: true}); self.trigger_up("restore_flip_card", { success_callback: function () { self.trigger_up("create_quick_record", { diff --git a/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/record.js b/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/record.js index f65ecc85b..40502edab 100644 --- a/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/record.js +++ b/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/record.js @@ -108,11 +108,13 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu if (state) { this._setState(state); } - this.$card.removeClass("blocked"); - // Avoid recreate active record - if (this.$card.hasClass("active")) { - this._processDynamicFields(); - return $.when(); + if (this.$card && this.$card.length) { + this.$card.removeClass("blocked"); + // Avoid recreate active record + if (this.$card.hasClass("active")) { + this._processDynamicFields(); + return $.when(); + } } this.on_detach_callback(); @@ -187,6 +189,17 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu } var model = this.options.basicFieldParams.model; this.is_virtual = this.state && model.isPureVirtual(this.state.id) || false; + + // Check if has cached qty + if (this.state && this.state.id) { + const record = model.get(this.state.id); + const lazy_qty = record && record.context.lazy_qty || 0; + if (lazy_qty) { + model.updateRecordContext(this.state.id, {lazy_qty: 0}); + // Record already has 1 + this._incProductQty(lazy_qty - 1); + } + } }, /** @@ -214,6 +227,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu modified: record && record.context.product_picker_modified, active_model: '', auto_save: this.options.autoSave, + is_saving: record && record.context.saving, }; }, @@ -429,6 +443,12 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu }); }, + _updateLazyQty: function () { + var model = this.options.basicFieldParams.model; + var record = model.get(this.state.id); + this.$el.find(".lazy_product_qty").text(record.context.lazy_qty); + }, + /** * This is a special handle for display the non-fields. * Similar 't-esc' behaviour. @@ -516,6 +536,8 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu _saveRecord: function () { var self = this; var model = this.options.basicFieldParams.model; + model.updateRecordContext(this.state.id, {saving: true}); + this.recreate(); var record = model.get(this.state.id); return model.save(record.id, { stayInEdit: true, @@ -559,6 +581,12 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu var model = this.options.basicFieldParams.model; model.updateRecordContext(this.state.id, {ignore_warning: this.options.ignoreWarning}); var record = model.get(this.state.id); + + // Because we don't hide the 'add' button when the product is added form back form + // we check if the record is in "saving" mode to prevent duplicate it. + if (record.context.saving) { + return Promise.resolve(); + } var changes = _.pick(record.data, this.options.fieldMap.product_uom_qty); if (changes[this.options.fieldMap.product_uom_qty] === 0) { changes[this.options.fieldMap.product_uom_qty] = 1; @@ -583,16 +611,23 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu var model = this.options.basicFieldParams.model; model.updateRecordContext(this.state.id, {ignore_warning: this.options.ignoreWarning}); var record = model.get(this.state.id); - var changes = _.pick(record.data, this.options.fieldMap.product_uom_qty); - changes[this.options.fieldMap.product_uom_qty] += amount; - return model.notifyChanges( - record.id, - changes - ).then(function () { - self._processDynamicFields(); - self._lazyUpdateRecord(); - }); + if (this.options.autoSave && !this.state.data.id) { + let lazy_qty = record.context.lazy_qty || 1; + lazy_qty += amount; + model.updateRecordContext(this.state.id, {lazy_qty: lazy_qty}); + self._updateLazyQty(); + } else { + var changes = _.pick(record.data, this.options.fieldMap.product_uom_qty); + changes[this.options.fieldMap.product_uom_qty] += amount; + return model.notifyChanges( + record.id, + changes + ).then(function () { + self._processDynamicFields(); + self._lazyUpdateRecord(); + }); + } }, /** @@ -603,11 +638,6 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu var $currentTarget = $(currentTarget); var $img = $currentTarget.find(".oe_flip_card_front img"); $target.addClass('o_catch_attention'); - $img.addClass('oe_product_picker_catch_attention'); - $img.on('animationend', function () { - $img.removeClass('oe_product_picker_catch_attention'); - $img.off('animationend'); - }); }, /** @@ -645,7 +675,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu */ _onClickFlipCard: function (evt) { // Avoid clicks on form elements - if (['INPUT', 'BUTTON', 'A'].indexOf(evt.target.tagName) !== -1 || this.$card.hasClass('blocked')) { + if (['INPUT', 'BUTTON', 'A'].indexOf(evt.target.tagName) !== -1) { return; } var $target = $(evt.target); @@ -672,6 +702,11 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu return; } } + + if (this.$card.hasClass('blocked')) { + return; + } + if (!this._clickFlipCardDelayed) { this._clickFlipCardDelayed = setTimeout( this._onClickDelayedFlipCard.bind(this, evt), diff --git a/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/renderer.js b/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/renderer.js index 71750434d..1b675747c 100644 --- a/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/renderer.js +++ b/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/renderer.js @@ -260,9 +260,14 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer", widget.recordSearch.id === state.data[this.options.field_map.product].data.id ) { - // Is a new record + // Is a new record (a replace for pure virtual) search_record_index = widget.$el.index(); search_record = widget.recordSearch; + var model = this.getParent().getBasicFieldParams().model; + var record = model.get(widget.state.id); + model.updateRecordContext(state.id, { + lazy_qty: record.context.lazy_qty || 0, + }); } // Remove "pure virtual" records that have the same product that the new record diff --git a/web_widget_one2many_product_picker/static/src/js/widgets/field_one2many_product_picker.js b/web_widget_one2many_product_picker/static/src/js/widgets/field_one2many_product_picker.js index 7c5249d2a..8d97dede8 100644 --- a/web_widget_one2many_product_picker/static/src/js/widgets/field_one2many_product_picker.js +++ b/web_widget_one2many_product_picker/static/src/js/widgets/field_one2many_product_picker.js @@ -604,6 +604,9 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun } }); }); + if (evt.data.callback) { + evt.data.callback(); + } }); } else { // This is used to know when need use 'yellow' color @@ -619,6 +622,45 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun } }, + _doUpdateQuickRecord: function (id, data, callback) { + if (this.options.auto_save) { + var self = this; + // Dont trigger state update + this._setValue( + {operation: "UPDATE", id: id, data: data}, + {notifyChange: false} + ).then(function () { + self.parent_controller.saveRecord(undefined, {stayInEdit: true}).then(function () { + // Workaround to get updated values + self.parent_controller.model.reload(self.value.id).then(function (result) { + var new_data = self.parent_controller.model.get(result); + self.value.data = new_data.data; + self.renderer.updateState(self.value, {force: true}); + if (callback) { + callback(); + } + }); + }); + if (callback) { + callback(); + } + }); + } else { + // This is used to know when need use 'yellow' color + this.parent_controller.model.updateRecordContext(id, { + product_picker_modified: true, + }); + // This will trigger an "state" update + this._setValue( + {operation: "UPDATE", id: id, data: data}, + ).then(function () { + if (callback) { + callback(); + } + }); + } + }, + /** * Runs the x2many (1,id,values) command. * @@ -627,44 +669,7 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun */ _onUpdateQuickRecord: function (evt) { evt.stopPropagation(); - var self = this; - - if (this.options.auto_save) { - // Dont trigger state update - this._setValue( - {operation: "UPDATE", id: evt.data.id, data: evt.data.data}, - {notifyChange: false} - ).then(function () { - if (self.options.auto_save) { - self.parent_controller.saveRecord(undefined, {stayInEdit: true}).then(function () { - // Workaround to get updated values - self.parent_controller.model.reload(self.value.id).then(function (result) { - var new_data = self.parent_controller.model.get(result); - self.value.data = new_data.data; - self.renderer.updateState(self.value, {force: true}); - if (evt.data.callback) { - evt.data.callback(); - } - }); - }); - } else if (evt.data.callback) { - evt.data.callback(); - } - }); - } else { - // This is used to know when need use 'yellow' color - this.parent_controller.model.updateRecordContext(evt.data.id, { - product_picker_modified: true, - }); - // This will trigger an "state" update - this._setValue( - {operation: "UPDATE", id: evt.data.id, data: evt.data.data}, - ).then(function () { - if (evt.data.callback) { - evt.data.callback(); - } - }); - } + this._doUpdateQuickRecord(evt.data.id, evt.data.data, evt.data.callback); }, /** diff --git a/web_widget_one2many_product_picker/static/src/scss/one2many_product_picker.scss b/web_widget_one2many_product_picker/static/src/scss/one2many_product_picker.scss index ef0479347..6b997bd19 100644 --- a/web_widget_one2many_product_picker/static/src/scss/one2many_product_picker.scss +++ b/web_widget_one2many_product_picker/static/src/scss/one2many_product_picker.scss @@ -61,10 +61,6 @@ transition: top $one2many-product-picker-transition-3d-time, left $one2many-product-picker-transition-3d-time, width $one2many-product-picker-transition-3d-time, height $one2many-product-picker-transition-3d-time; height: $one2many-product-picker-card-min-height; - &.blocked { - filter: blur(2px); - } - &.disabled { filter: grayscale(100%); opacity: 0.5; @@ -239,20 +235,3 @@ text-align: center; } } - -.oe_product_picker_catch_attention { - position: relative; - animation: productPickerCatchAttention 200ms normal forwards; -} - -@keyframes productPickerCatchAttention { - 0% { - transform: scale(1.0); - } - 50% { - transform: scale(1.5); - } - 100% { - transform: scale(1.0); - } -} diff --git a/web_widget_one2many_product_picker/static/src/xml/one2many_product_picker.xml b/web_widget_one2many_product_picker/static/src/xml/one2many_product_picker.xml index 50133fa6a..d3146f6de 100644 --- a/web_widget_one2many_product_picker/static/src/xml/one2many_product_picker.xml +++ b/web_widget_one2many_product_picker/static/src/xml/one2many_product_picker.xml @@ -70,15 +70,20 @@
-
+
-
+
+ +
+ 1 x +
+
1