diff --git a/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/quick_modif_price_form_view.js b/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/quick_modif_price_form_view.js index 7b6a8f7a2..bb128b730 100644 --- a/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/quick_modif_price_form_view.js +++ b/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/quick_modif_price_form_view.js @@ -179,6 +179,7 @@ odoo.define("web_widget_one2many_product_picker.ProductPickerQuickModifPriceForm this.trigger_up("update_quick_record", { id: record.id, }); + self.model.unsetDirty(self.handle); this.getParent().destroy(); } }, 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 ab5d15780..a91c9db8d 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 @@ -213,6 +213,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu is_virtual: this.is_virtual, modified: record && record.context.product_picker_modified, active_model: '', + auto_save: this.options.autoSave, }; }, @@ -493,11 +494,12 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu _calcPriceReduced: function () { var price_reduce = 0; var field_map = this.options.fieldMap; - var state_data = this.state.data; - if (state_data && state_data[field_map.discount]) { + var model = this.options.basicFieldParams.model; + var record = model.get(this.state.id); + if (record && record.data[field_map.discount]) { price_reduce = tools.priceReduce( - state_data[field_map.price_unit], - state_data[field_map.discount]); + record.data[field_map.price_unit], + record.data[field_map.discount]); } return price_reduce && tools.monetary( price_reduce, @@ -516,28 +518,36 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu var model = this.options.basicFieldParams.model; var record = model.get(this.state.id); return model.save(record.id, { + stayInEdit: true, + reload: true, savePoint: true, + viewType: "form", }).then(function () { var record = model.get(self.state.id); self.trigger_up("create_quick_record", { id: record.id, + callback: function () { + self.$card.find('.o_catch_attention').removeClass('o_catch_attention'); + } }); model.unsetDirty(self.state.id); - self.$card.find('.o_catch_attention').removeClass('o_catch_attention'); }); }, /** * @private */ - _updateRecord: function (changes) { + _updateRecord: function () { + var self = this; var model = this.options.basicFieldParams.model; var record = model.get(this.state.id); this.trigger_up("update_quick_record", { id: record.id, + callback: function () { + self.$card.find('.o_catch_attention').removeClass('o_catch_attention'); + } }); model.unsetDirty(this.state.id); - this.$card.find('.o_catch_attention').removeClass('o_catch_attention'); }, /** @@ -546,13 +556,15 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu */ _addProduct: function () { var self = this; - var changes = {}; - if (this.state.data[this.options.fieldMap.product_uom_qty] === 0) { + var model = this.options.basicFieldParams.model; + var record = model.get(this.state.id); + 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; } var model = this.options.basicFieldParams.model; this.$card.addClass("blocked"); - return model.notifyChanges(this.state.id, changes).then(function () { + return model.notifyChanges(record.id, changes).then(function () { self._saveRecord(); }); }, @@ -564,12 +576,10 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu */ _incProductQty: function (amount) { var self = this; - this.state.data[this.options.fieldMap.product_uom_qty] += amount; var model = this.options.basicFieldParams.model; var record = model.get(this.state.id); - var state_data = record.data; - state_data[this.options.fieldMap.product_uom_qty] += amount; - var changes = _.pick(state_data, this.options.fieldMap.product_uom_qty); + 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(); 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 48820a031..e5225d0a0 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 @@ -104,8 +104,10 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer", */ updateState: function (state, params) { var self = this; + var force_update = params.force; + delete params.force; var sparams = _.extend({}, params, {noRender: true}); - if (_.isEqual(this.state.data, state.data)) { + if (!force_update && _.isEqual(this.state.data, state.data)) { return this._super(state, sparams); } var old_state = _.clone(this.state.data); @@ -114,6 +116,22 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer", }); }, + /** + * Recreate the given widget by the state id + * + * @param {String} state_id + * @param {Object} new_state + */ + updateRecord: function (state_id, new_state) { + for (var eb = this.widgets.length-1; eb>=0; --eb) { + var widget = this.widgets[eb]; + if (widget.state.id === state_id) { + widget.recreate(new_state); + break; + } + } + }, + /** * @private * @param {Array[Object]} states @@ -206,7 +224,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer", var found = false; for (var e in this.state.data) { var current_state = this.state.data[e]; - if (current_state.id === old_state.id || (typeof current_state.data.id !== 'undefined' && current_state.data.id === old_state.data.id)) { + if (current_state.id === old_state.id) { found = true; break; } @@ -215,6 +233,8 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer", states_to_destroy.push(old_state); } } + + this.state.data = _.compact(this.state.data); this._removeRecords(states_to_destroy, this.state.data); // Records to Update or Create @@ -232,7 +252,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer", // Already processed widget (deleted) continue; } - if (widget.state.id === state.id || (typeof state.data.id !== 'undefined' && widget.state.data.id === state.data.id)) { + if (widget.state.id === state.id) { widget.recreate(state); exists = true; break; @@ -255,6 +275,8 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer", } } + this.state.data = _.compact(this.state.data); + // Need add a new one? if (!exists && search_record_index !== -1) { var new_search_record = _.extend({}, search_record, {__id: state.id}); @@ -362,6 +384,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer", showDiscount: this.options.show_discount, editDiscount: this.options.edit_discount, editPrice: this.options.edit_price, + autoSave: this.options.auto_save, }); }, 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 f6d089d69..3f2593c8e 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 @@ -37,6 +37,7 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun update_subtotal: "_onUpdateSubtotal", load_more: "_onLoadMore", loading_records: "_onLoadingRecords", + list_record_remove: "_onListRecordRemove", }), _auto_search_delay: 450, @@ -438,6 +439,7 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun discount: "discount", }, auto_save: false, + allow_warning: true, }; }, @@ -525,7 +527,7 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun 'name': 'main_lines', }; this._searchContext.domain = this._getLinesDomain(); - this._searchContext.order = false; + this._searchContext.order = [{'name': 'sequence'}, {'name': 'id'}]; this._searchContext.activeTest = false; this.doRenderSearchRecords(); }, @@ -580,20 +582,45 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun * @param {CustomEvent} evt */ _onCreateQuickRecord: function (evt) { + evt.stopPropagation(); var self = this; this.parent_controller.model.setPureVirtual(evt.data.id, false); - if (!self.options.auto_save) { - self.parent_controller.model.updateRecordContext(evt.data.id, { + + if (this.options.auto_save) { + // Dont trigger state update + this._setValue( + {operation: "ADD", id: evt.data.id}, + {notifyChange: false} + ).then(function () { + if (self.options.auto_save) { + self.parent_controller.saveRecord(undefined, {stayInEdit: true}).then(function (rrr) { + // Because 'create' generates a new state and we can't know these new id we + // need force update the all the current states. + self._setValue( + {operation: "UPDATE", id: evt.data.id}, + {doNotSetDirty: true} + ).then(function () { + 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: "ADD", id: evt.data.id}).then(function () { + if (evt.data.callback) { + evt.data.callback(); + } + }); } - this._setValue({operation: "ADD", id: evt.data.id}).then(function () { - if (self.options.auto_save) { - self.parent_controller.saveRecord(undefined, {stayInEdit: true}).then(function () { - self.renderer.updateState(self.value); - }); - } - }); }, /** @@ -603,17 +630,62 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun * @param {CustomEevent} evt */ _onUpdateQuickRecord: function (evt) { + evt.stopPropagation(); var self = this; - if (!self.options.auto_save) { - self.parent_controller.model.updateRecordContext(evt.data.id, { + + 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._setValue({operation: "UPDATE", id: evt.data.id, data: evt.data.data}).then(function () { + }, + + /** + * Handle auto_save when remove a record + */ + _onListRecordRemove: function (evt) { + evt.stopPropagation(); + var self = this; + this._setValue({operation: "DELETE", ids: [evt.data.id]}).then(function () { if (self.options.auto_save) { self.parent_controller.saveRecord(undefined, {stayInEdit: true}).then(function () { - self.renderer.updateState(self.value); + if (evt.data.callback) { + evt.data.callback(); + } }); + } else if (evt.data.callback) { + evt.data.callback(); } }); }, 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 481241e91..50133fa6a 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,7 +70,7 @@
-
+