diff --git a/product_configurator/__manifest__.py b/product_configurator/__manifest__.py index 3173f22271..68b5c19e4b 100644 --- a/product_configurator/__manifest__.py +++ b/product_configurator/__manifest__.py @@ -29,9 +29,9 @@ "web.assets_backend": [ "/product_configurator/static/src/scss/form_widget.scss", "/product_configurator/static/src/js/form_widgets.js", - # "/product_configurator/static/src/js/boolean_button_widget.esm.js", - # "/product_configurator/static/src/js/boolean_button_widget.xml", - # "/product_configurator/static/src/js/relational_fields.js", + "/product_configurator/static/src/js/boolean_button_widget.esm.js", + "/product_configurator/static/src/js/boolean_button_widget.xml", + "/product_configurator/static/src/js/relational_fields.js", ] }, "demo": [ diff --git a/product_configurator/models/product_config.py b/product_configurator/models/product_config.py index d1569ae88b..43269e5573 100644 --- a/product_configurator/models/product_config.py +++ b/product_configurator/models/product_config.py @@ -548,7 +548,9 @@ def update_session_configuration_value(self, vals, product_tmpl_id=None): if not vals[field_name]: field_val = None else: - field_val = vals[field_name][0][2] + field_val = [ + i[1] for i in vals[field_name] if vals[field_name][0] + ] or vals[field_name][0][1] elif not attr_line.multi and isinstance(vals[field_name], int): field_val = vals[field_name] else: @@ -1482,7 +1484,7 @@ def flatten_val_ids(self, value_ids): :returns: flattened list of ids ([1, 2, 3, 4, 5, 6])""" flat_val_ids = set() if value_ids and value_ids[0]: - for val in value_ids[0]: + for val in value_ids: if not val: continue if isinstance(val, list): diff --git a/product_configurator/static/src/js/boolean_button_widget.esm.js b/product_configurator/static/src/js/boolean_button_widget.esm.js index f5b7a77038..f15f03eb32 100644 --- a/product_configurator/static/src/js/boolean_button_widget.esm.js +++ b/product_configurator/static/src/js/boolean_button_widget.esm.js @@ -1,38 +1,27 @@ /** @odoo-module **/ + +import {_t} from "@web/core/l10n/translation"; +import {registry} from "@web/core/registry"; import {onMounted, onRendered, useRef, useState} from "@odoo/owl"; import {booleanField, BooleanField} from "@web/views/fields/boolean/boolean_field"; -import {registry} from "@web/core/registry"; import {standardFieldProps} from "@web/views/fields/standard_field_props"; -console.log("\n\n====BooleanField======"); +export class BooleanButton extends BooleanField { + static template = "product_configurator.BooleanButtonField"; -export class BooleanButtonField extends BooleanField { setup() { super.setup(); - console.log("\n\n====BooleanField==setup===="); this.state1 = useState({value: 0}); this.root = useRef("root"); - // onMounted(() => { - // this.updateConfigurableButton(); - // }); - // onRendered(() => { - // this.updateConfigurableButton(); - // }); - onMounted(async () => { + onMounted(() => { this.updateConfigurableButton(); }); - onRendered(async () => { + onRendered(() => { this.updateConfigurableButton(); }); } - onChange() { - console.log("\n\n=========onChange==========", this.state1); - this.state1.value++; - } - updateConfigurableButton() { - console.log("\n\n=========updateConfigurableButton==========", this); this.text = this.props.value ? this.props.activeString : this.props.inactiveString; @@ -52,25 +41,21 @@ export class BooleanButtonField extends BooleanField { } } -//BooleanButtonField.props = { -// ...standardFieldProps, -// activeString: {type: String, optional: true}, -// inactiveString: {type: String, optional: true}, -//}; - -//BooleanButtonField.extractProps = ({attrs}) => { -// return { -// activeString: attrs.options.active, -// inactiveString: attrs.options.inactive, -// }; -//}; - export const BooleanButtonField = { - extractProps: ({attrs}) => ({ - activeString: attrs.options.active, - inactiveString: attrs.options.inactive, - }), + ...booleanField, + component: BooleanButton, + extractProps: ({options}) => { + return { + activeString: options.active, + inactiveString: options.inactive, + }; + }, +}; + +BooleanButton.props = { + ...standardFieldProps, + activeString: {type: String}, + inactiveString: {type: String, optional: true}, }; -BooleanButtonField.template = "product_configurator.BooleanButtonField"; registry.category("fields").add("boolean_button", BooleanButtonField); diff --git a/product_configurator/static/src/js/form_widgets.js b/product_configurator/static/src/js/form_widgets.js index d1eedfbaaa..478019c14f 100644 --- a/product_configurator/static/src/js/form_widgets.js +++ b/product_configurator/static/src/js/form_widgets.js @@ -1,106 +1,81 @@ -/** @odoo-module **/ +/* @odoo-module */ -import {registry} from "@web/core/registry"; +import {patch} from "@web/core/utils/patch"; import {FormController} from "@web/views/form/form_controller"; import {ListController} from "@web/views/list/list_controller"; import {KanbanController} from "@web/views/kanban/kanban_controller"; -import {pyUtils} from "@web/core/py_js/py_utils"; -import {formView} from "@web/views/form/form_view"; +import {onMounted} from "@odoo/owl"; -export class FieldBooleanButton extends FormController { +patch(FormController.prototype, { setup() { - super.setup(); - this.archInfo = this.props.archInfo; - const footers = this.archInfo; - console.log("================", footers); - } - - _onButtonClicked(event) { - alert("sssssss"); - } -} - -registry.category("views").add("product_template_form_view", { - ...formView, - Controller: FieldBooleanButton, + super.setup(...arguments); + onMounted(() => { + var form_element = this.rootRef.el; + var self = this; + if ( + self.model.config.resModel === "product.product" && + self.model.config.context.custom_create_variant + ) { + var buttons = form_element.querySelector( + ".o_control_panel_main_buttons" + ); + var createButtons = buttons.querySelectorAll(".o_form_button_create"); + createButtons.forEach((button) => { + button.style.display = "none"; + }); + } + }); + }, + async beforeExecuteActionButton(clickParams) { + console.log("beforeExecuteActionButton", clickParams); + if (clickParams.special === "no_save") { + delete clickParams.special; + return true; + } + return super.beforeExecuteActionButton(...arguments); + }, }); -// odoo.define("product_configurator.FieldBooleanButton", function (require) { -// "use strict"; - -// var FormController = require("web.FormController"); -// var ListController = require("web.ListController"); -// var KanbanController = require("web.KanbanController"); - -// var pyUtils = require("web.py_utils"); - -// FormController.include({ -// /* eslint-disable no-unused-vars*/ -// renderButtons: function ($node) { -// var self = this; -// this._super.apply(this, arguments); -// if ( -// self.modelName === "product.product" && -// self.initialState.context.custom_create_variant -// ) { -// this.$buttons.find(".o_form_button_create").css("display", "none"); -// } -// }, -// /* eslint-disable no-unused-vars*/ +patch(ListController.prototype, { + setup() { + super.setup(...arguments); + onMounted(() => { + var form_element = this.rootRef.el; + var self = this; + if ( + self.model.config.resModel === "product.product" && + self.model.config.context.custom_create_variant + ) { + var buttons = form_element.querySelector( + ".o_control_panel_main_buttons" + ); + var createButtons = buttons.querySelectorAll(".o_list_button_add"); + createButtons.forEach((button) => { + button.style.display = "none"; + }); + } + }); + }, +}); -// _onButtonClicked: function (event) { -// var self = this; -// var attrs = event.data.attrs; -// if (event.data.attrs.context) { -// var record_ctx = self.model.get(event.data.record.id).context; -// var btn_ctx = pyUtils.eval( -// "context", -// record_ctx, -// event.data.attrs.context -// ); -// self.model.localData[event.data.record.id].context = _.extend( -// {}, -// btn_ctx, -// record_ctx -// ); -// } -// if (attrs.special === "no_save") { -// this.canBeSaved = function () { -// return true; -// }; -// var event_no_save = $.extend(true, {}, event); -// event_no_save.data.attrs.special = false; -// return this._super(event_no_save); -// } -// this._super(event); -// }, -// }); -// ListController.include({ -// /* eslint-disable no-unused-vars*/ -// renderButtons: function ($node) { -// var self = this; -// this._super.apply(this, arguments); -// if ( -// self.modelName === "product.product" && -// self.initialState.context.custom_create_variant -// ) { -// this.$buttons.find(".o_list_button_add").css("display", "none"); -// } -// }, -// /* eslint-disable no-unused-vars*/ -// }); -// KanbanController.include({ -// /* eslint-disable no-unused-vars*/ -// renderButtons: function ($node) { -// var self = this; -// this._super.apply(this, arguments); -// if ( -// self.modelName === "product.product" && -// self.initialState.context.custom_create_variant -// ) { -// this.$buttons.find(".o-kanban-button-new").css("display", "none"); -// } -// }, -// /* eslint-disable no-unused-vars*/ -// }); -// }); +patch(KanbanController.prototype, { + setup() { + super.setup(...arguments); + onMounted(() => { + var form_element = this.rootRef.el; + var self = this; + if ( + self.model.config.resModel === "product.product" && + self.model.config.context.custom_create_variant + ) { + var buttons = form_element.querySelector( + ".o_control_panel_main_buttons" + ); + var createButtons = buttons.querySelectorAll(".o-kanban-button-new"); + createButtons.forEach((button) => { + button.style.display = "none"; + }); + } + }); + }, +}); diff --git a/product_configurator/static/src/js/relational_fields.js b/product_configurator/static/src/js/relational_fields.js index cabb0950e7..c6d5d0d640 100644 --- a/product_configurator/static/src/js/relational_fields.js +++ b/product_configurator/static/src/js/relational_fields.js @@ -1,26 +1,14 @@ -odoo.define("product_configurator.FieldStatus", function (require) { - "use strict"; +/** @odoo-module **/ - var fields = require("web.relational_fields"); - var FieldStatus = fields.FieldStatus; +import {patch} from "@web/core/utils/patch"; +import {Many2OneField} from "@web/views/fields/many2one/many2one_field"; - FieldStatus.include({ - /* Prase input as string in order to have a clickable statusbar*/ - _onClickStage: function (e) { - this._setValue(String($(e.currentTarget).data("value"))); - }, - }); - - /* Bug from odoo: in case of widget many2many_tags $input and $el do not exist - in 'this', so it returns 'undefine', but setIDForLabel(method in AbstractField) - expecting getFocusableElement always return object*/ - fields.FieldMany2One.include({ - getFocusableElement: function () { - var element = this._super.apply(this, arguments); - if (element === undefined) { - return $(); - } - return element; - }, - }); +patch(Many2OneField.prototype, { + computeActiveActions(props) { + var element = super.computeActiveActions(...arguments); + if (element === undefined) { + return $(); + } + return element; + }, }); diff --git a/product_configurator/wizard/product_configurator.py b/product_configurator/wizard/product_configurator.py index c71a54f038..5836033a6d 100644 --- a/product_configurator/wizard/product_configurator.py +++ b/product_configurator/wizard/product_configurator.py @@ -1,11 +1,9 @@ -from typing import Dict, List -from odoo.tools.misc import OrderedSet - from lxml import etree from odoo import _, api, fields, models, tools from odoo.exceptions import UserError, ValidationError from odoo.tools import frozendict +from odoo.tools.misc import OrderedSet from odoo.addons.base.models.ir_model import FIELD_TYPES @@ -232,7 +230,6 @@ def get_form_vals( if isinstance(v, list): # pass if any(type(el) != int for el in v): - v = v[0][1] value_ids = available_val_ids.append(v) dynamic_fields.update({k: value_ids}) @@ -244,7 +241,6 @@ def get_form_vals( vals[k] = v final_cfg_val_ids = list(dynamic_fields.values()) - print ("\n final_cfg_val_ids",final_cfg_val_ids) vals.update(self.get_onchange_vals(final_cfg_val_ids, config_session_id)) # To solve the Multi selection problem removing extra [] @@ -313,7 +309,7 @@ def apply_onchange_values(self, values, field_name, field_onchange): # Get the unstored values from the client view for k, v in dynamic_fields.items(): attr_id = int(k.split(field_prefix)[1]) - valve_ids = self.env['product.attribute.value'] + valve_ids = self.env["product.attribute.value"] if isinstance(v, list): for att in v: valve_ids |= product_tmpl_id.config_line_ids.filtered( @@ -770,7 +766,6 @@ def add_dynamic_fields(self, res, dynamic_fields, wiz): "wizard_id": wiz.id, "field_name": field_name, "is_m2m": attr_line.multi, - "value_ids": attr_line.value_ids.ids, } ), options=str( @@ -1107,7 +1102,7 @@ def action_config_done(self): } return action - def web_read(self, specification: Dict[str, Dict]) -> List[Dict]: + def web_read(self, specification: dict[str, dict]) -> list[dict]: fields_to_read = list(specification) or ["id"] if fields_to_read == ["id"]: @@ -1115,12 +1110,12 @@ def web_read(self, specification: Dict[str, Dict]) -> List[Dict]: # this also avoid a call to read on the co-model that might have different access rules values_list = [{"id": id_} for id_ in self._ids] else: - values_list: List[Dict] = self.read(fields_to_read, load=None) + values_list: list[dict] = self.read(fields_to_read, load=None) if not values_list: return values_list - def cleanup(vals: Dict) -> Dict: + def cleanup(vals: dict) -> dict: """Fixup vals['id'] of a new record.""" if not vals["id"]: vals["id"] = vals["id"].origin or False @@ -1137,11 +1132,7 @@ def cleanup(vals: Dict) -> Dict: if not field_spec: continue - if field_spec.get("context").get("value_ids"): - co_records = self.env["product.attribute.value"].browse( - field_spec.get("context").get("value_ids") - ) - + co_records = self.env["product.attribute.value"] if "order" in field_spec and field_spec["order"]: co_records = co_records.search( [("id", "in", co_records.ids)], order=field_spec["order"]