mirror of https://github.com/OCA/web.git
[FIX] web_widget_one2many_product_picker: Auto save
parent
c78bdf4acc
commit
94c8c6553b
|
@ -179,6 +179,7 @@ odoo.define("web_widget_one2many_product_picker.ProductPickerQuickModifPriceForm
|
||||||
this.trigger_up("update_quick_record", {
|
this.trigger_up("update_quick_record", {
|
||||||
id: record.id,
|
id: record.id,
|
||||||
});
|
});
|
||||||
|
self.model.unsetDirty(self.handle);
|
||||||
this.getParent().destroy();
|
this.getParent().destroy();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -213,6 +213,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
|
||||||
is_virtual: this.is_virtual,
|
is_virtual: this.is_virtual,
|
||||||
modified: record && record.context.product_picker_modified,
|
modified: record && record.context.product_picker_modified,
|
||||||
active_model: '',
|
active_model: '',
|
||||||
|
auto_save: this.options.autoSave,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -493,11 +494,12 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
|
||||||
_calcPriceReduced: function () {
|
_calcPriceReduced: function () {
|
||||||
var price_reduce = 0;
|
var price_reduce = 0;
|
||||||
var field_map = this.options.fieldMap;
|
var field_map = this.options.fieldMap;
|
||||||
var state_data = this.state.data;
|
var model = this.options.basicFieldParams.model;
|
||||||
if (state_data && state_data[field_map.discount]) {
|
var record = model.get(this.state.id);
|
||||||
|
if (record && record.data[field_map.discount]) {
|
||||||
price_reduce = tools.priceReduce(
|
price_reduce = tools.priceReduce(
|
||||||
state_data[field_map.price_unit],
|
record.data[field_map.price_unit],
|
||||||
state_data[field_map.discount]);
|
record.data[field_map.discount]);
|
||||||
}
|
}
|
||||||
return price_reduce && tools.monetary(
|
return price_reduce && tools.monetary(
|
||||||
price_reduce,
|
price_reduce,
|
||||||
|
@ -516,28 +518,36 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
|
||||||
var model = this.options.basicFieldParams.model;
|
var model = this.options.basicFieldParams.model;
|
||||||
var record = model.get(this.state.id);
|
var record = model.get(this.state.id);
|
||||||
return model.save(record.id, {
|
return model.save(record.id, {
|
||||||
|
stayInEdit: true,
|
||||||
|
reload: true,
|
||||||
savePoint: true,
|
savePoint: true,
|
||||||
|
viewType: "form",
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
var record = model.get(self.state.id);
|
var record = model.get(self.state.id);
|
||||||
self.trigger_up("create_quick_record", {
|
self.trigger_up("create_quick_record", {
|
||||||
id: record.id,
|
id: record.id,
|
||||||
|
callback: function () {
|
||||||
|
self.$card.find('.o_catch_attention').removeClass('o_catch_attention');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
model.unsetDirty(self.state.id);
|
model.unsetDirty(self.state.id);
|
||||||
self.$card.find('.o_catch_attention').removeClass('o_catch_attention');
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_updateRecord: function (changes) {
|
_updateRecord: function () {
|
||||||
|
var self = this;
|
||||||
var model = this.options.basicFieldParams.model;
|
var model = this.options.basicFieldParams.model;
|
||||||
var record = model.get(this.state.id);
|
var record = model.get(this.state.id);
|
||||||
this.trigger_up("update_quick_record", {
|
this.trigger_up("update_quick_record", {
|
||||||
id: record.id,
|
id: record.id,
|
||||||
|
callback: function () {
|
||||||
|
self.$card.find('.o_catch_attention').removeClass('o_catch_attention');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
model.unsetDirty(this.state.id);
|
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 () {
|
_addProduct: function () {
|
||||||
var self = this;
|
var self = this;
|
||||||
var changes = {};
|
var model = this.options.basicFieldParams.model;
|
||||||
if (this.state.data[this.options.fieldMap.product_uom_qty] === 0) {
|
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;
|
changes[this.options.fieldMap.product_uom_qty] = 1;
|
||||||
}
|
}
|
||||||
var model = this.options.basicFieldParams.model;
|
var model = this.options.basicFieldParams.model;
|
||||||
this.$card.addClass("blocked");
|
this.$card.addClass("blocked");
|
||||||
return model.notifyChanges(this.state.id, changes).then(function () {
|
return model.notifyChanges(record.id, changes).then(function () {
|
||||||
self._saveRecord();
|
self._saveRecord();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -564,12 +576,10 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu
|
||||||
*/
|
*/
|
||||||
_incProductQty: function (amount) {
|
_incProductQty: function (amount) {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.state.data[this.options.fieldMap.product_uom_qty] += amount;
|
|
||||||
var model = this.options.basicFieldParams.model;
|
var model = this.options.basicFieldParams.model;
|
||||||
var record = model.get(this.state.id);
|
var record = model.get(this.state.id);
|
||||||
var state_data = record.data;
|
var changes = _.pick(record.data, this.options.fieldMap.product_uom_qty);
|
||||||
state_data[this.options.fieldMap.product_uom_qty] += amount;
|
changes[this.options.fieldMap.product_uom_qty] += amount;
|
||||||
var changes = _.pick(state_data, this.options.fieldMap.product_uom_qty);
|
|
||||||
|
|
||||||
return model.notifyChanges(record.id, changes).then(function () {
|
return model.notifyChanges(record.id, changes).then(function () {
|
||||||
self._processDynamicFields();
|
self._processDynamicFields();
|
||||||
|
|
|
@ -104,8 +104,10 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer",
|
||||||
*/
|
*/
|
||||||
updateState: function (state, params) {
|
updateState: function (state, params) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
var force_update = params.force;
|
||||||
|
delete params.force;
|
||||||
var sparams = _.extend({}, params, {noRender: true});
|
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);
|
return this._super(state, sparams);
|
||||||
}
|
}
|
||||||
var old_state = _.clone(this.state.data);
|
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
|
* @private
|
||||||
* @param {Array[Object]} states
|
* @param {Array[Object]} states
|
||||||
|
@ -206,7 +224,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer",
|
||||||
var found = false;
|
var found = false;
|
||||||
for (var e in this.state.data) {
|
for (var e in this.state.data) {
|
||||||
var current_state = this.state.data[e];
|
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;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -215,6 +233,8 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer",
|
||||||
states_to_destroy.push(old_state);
|
states_to_destroy.push(old_state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.state.data = _.compact(this.state.data);
|
||||||
this._removeRecords(states_to_destroy, this.state.data);
|
this._removeRecords(states_to_destroy, this.state.data);
|
||||||
|
|
||||||
// Records to Update or Create
|
// Records to Update or Create
|
||||||
|
@ -232,7 +252,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer",
|
||||||
// Already processed widget (deleted)
|
// Already processed widget (deleted)
|
||||||
continue;
|
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);
|
widget.recreate(state);
|
||||||
exists = true;
|
exists = true;
|
||||||
break;
|
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?
|
// Need add a new one?
|
||||||
if (!exists && search_record_index !== -1) {
|
if (!exists && search_record_index !== -1) {
|
||||||
var new_search_record = _.extend({}, search_record, {__id: state.id});
|
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,
|
showDiscount: this.options.show_discount,
|
||||||
editDiscount: this.options.edit_discount,
|
editDiscount: this.options.edit_discount,
|
||||||
editPrice: this.options.edit_price,
|
editPrice: this.options.edit_price,
|
||||||
|
autoSave: this.options.auto_save,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun
|
||||||
update_subtotal: "_onUpdateSubtotal",
|
update_subtotal: "_onUpdateSubtotal",
|
||||||
load_more: "_onLoadMore",
|
load_more: "_onLoadMore",
|
||||||
loading_records: "_onLoadingRecords",
|
loading_records: "_onLoadingRecords",
|
||||||
|
list_record_remove: "_onListRecordRemove",
|
||||||
}),
|
}),
|
||||||
|
|
||||||
_auto_search_delay: 450,
|
_auto_search_delay: 450,
|
||||||
|
@ -438,6 +439,7 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun
|
||||||
discount: "discount",
|
discount: "discount",
|
||||||
},
|
},
|
||||||
auto_save: false,
|
auto_save: false,
|
||||||
|
allow_warning: true,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -525,7 +527,7 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun
|
||||||
'name': 'main_lines',
|
'name': 'main_lines',
|
||||||
};
|
};
|
||||||
this._searchContext.domain = this._getLinesDomain();
|
this._searchContext.domain = this._getLinesDomain();
|
||||||
this._searchContext.order = false;
|
this._searchContext.order = [{'name': 'sequence'}, {'name': 'id'}];
|
||||||
this._searchContext.activeTest = false;
|
this._searchContext.activeTest = false;
|
||||||
this.doRenderSearchRecords();
|
this.doRenderSearchRecords();
|
||||||
},
|
},
|
||||||
|
@ -580,20 +582,45 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun
|
||||||
* @param {CustomEvent} evt
|
* @param {CustomEvent} evt
|
||||||
*/
|
*/
|
||||||
_onCreateQuickRecord: function (evt) {
|
_onCreateQuickRecord: function (evt) {
|
||||||
|
evt.stopPropagation();
|
||||||
var self = this;
|
var self = this;
|
||||||
this.parent_controller.model.setPureVirtual(evt.data.id, false);
|
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,
|
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
|
* @param {CustomEevent} evt
|
||||||
*/
|
*/
|
||||||
_onUpdateQuickRecord: function (evt) {
|
_onUpdateQuickRecord: function (evt) {
|
||||||
|
evt.stopPropagation();
|
||||||
var self = this;
|
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,
|
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) {
|
if (self.options.auto_save) {
|
||||||
self.parent_controller.saveRecord(undefined, {stayInEdit: true}).then(function () {
|
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();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -70,7 +70,7 @@
|
||||||
|
|
||||||
<t t-name="One2ManyProductPicker.FlipCard">
|
<t t-name="One2ManyProductPicker.FlipCard">
|
||||||
<div class="oe_flip_container p-1 col-12 col-sm-8 col-md-6 col-lg-4 col-xl-3 col-xxl-2">
|
<div class="oe_flip_container p-1 col-12 col-sm-8 col-md-6 col-lg-4 col-xl-3 col-xxl-2">
|
||||||
<div t-attf-class="oe_flip_card {{!state && 'disabled' || ''}}">
|
<div t-attf-class="oe_flip_card {{!state && 'disabled' || (auto_save && !is_virtual && !state.data.id && 'blocked') || ''}}">
|
||||||
<div class="oe_flip_card_inner text-center">
|
<div class="oe_flip_card_inner text-center">
|
||||||
<div t-attf-class="oe_flip_card_front p-0 {{(modified && 'border-warning') || (state && !is_virtual && 'border-success') || ''}}">
|
<div t-attf-class="oe_flip_card_front p-0 {{(modified && 'border-warning') || (state && !is_virtual && 'border-success') || ''}}">
|
||||||
<t t-if="state">
|
<t t-if="state">
|
||||||
|
|
Loading…
Reference in New Issue