Skip to content

Commit

Permalink
ADD Refactoring getting bom date from bom and input line
Browse files Browse the repository at this point in the history
  • Loading branch information
FranzPoize committed Mar 7, 2024
1 parent 3423820 commit be7e336
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 130 deletions.
86 changes: 7 additions & 79 deletions mrp_bom_configurable/models/input_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,86 +31,19 @@ def ui_clone(self):
vals = {"name": "%s copy" % self.name}
self.copy(vals)

def _get_filtered_components_from_values(self):
def _get_input_line_values(self):
elements = dict()
conf_names = dict()
for elm in self._get_config_elements():
if self._fields[elm].type == "many2one":
value = self[elm].id
value = self[elm].display_name
else:
value = self[elm]
elements[elm] = value
conf_names[self._fields[elm].string] = value
lines = self.bom_id.check_domain(elements)
return lines, conf_names

def get_values_with_field_desc(self):
self.ensure_one()
values = [
{
"name": "name",
"string": "Name",
"value": self.name,
}
]
for field in self._get_config_elements():
field_vals = {
"name": field,
"string": self._fields[field].string,
"type": self._fields[field].type,
}

if self._fields[field].type == "many2one":
fieldinfo = self._fields[field]
field_vals["value"] = self[field].id
field_vals["display_name"] = self[field].display_name
field_vals["model"] = fieldinfo.comodel_name
if isinstance(fieldinfo.domain, list) or fieldinfo.domain is None:
field_vals["domain"] = fieldinfo.domain
else:
field_vals["domain"] = fieldinfo.domain(self)
else:
field_vals["value"] = self[field]

if self._fields[field].type == "selection":
if self._fields[field].related:
field_vals["possible_values"] = self._fields[field].selection(self)
else:
field_vals["possible_values"] = self._fields[field].selection

values.append(field_vals)

return values
return elements

def check_one_data(self):
pass

def _create_report_dict_from_line(self, line):
return {
"id": line.id,
"component": line.product_id.display_name,
"quantity": line.product_qty,
"unit": line.product_uom_id.display_name,
}

def _create_bom_data_preview(self):
self.ensure_one()
lines, conf_names = self._get_filtered_components_from_values()
return {
"config_data": [
{"name": key, "display_name": conf_names[key]} for key in conf_names
],
"data": [self._create_report_dict_from_line(line) for line in lines],
}

def populate_bom_data_preview(self):
self.bom_data_preview = self._create_bom_data_preview()

def get_json(self):
self.ensure_one()
self.populate_bom_data_preview()
return self.bom_data_preview

def open_form_pop_up(self):
self.ensure_one()
return {
Expand All @@ -124,19 +57,14 @@ def open_form_pop_up(self):

def create_bom_line_data(self):
self.ensure_one()
components, _ = self._get_filtered_components_from_values()
components = self.bom_id.get_bom_configured_data(self)
bom_lines_data = []

for comp in components:
quantity = (
comp.compute_qty_from_formula(self)
if comp.use_formula_compute_qty
else comp.product_qty
)
bom_line_data = {
"product_tmpl_id": comp.product_tmpl_id,
"product_id": comp.product_id,
"product_qty": quantity,
"product_tmpl_id": comp["line"].product_tmpl_id,
"product_id": comp["line"].product_id,
"product_qty": comp["product_qty"],
}
bom_lines_data.append(bom_line_data)

Expand Down
19 changes: 16 additions & 3 deletions mrp_bom_configurable/models/mrp_bom.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,26 @@ class MrpBom(models.Model):
required=True,
)

def check_domain(self, values):
def get_bom_configured_data(self, input_line, quantity=1.0):
result = []
values = input_line._get_input_line_values()
for line in self.bom_line_ids.filtered(lambda s: s.execute(values)):
line_quantity = (
line.compute_qty_from_formula(input_line)
if line.use_formula_compute_qty
else line.product_qty
) * quantity
if line.child_bom_id:
result = result + line.child_bom_id.check_domain(values)
result = result + line.child_bom_id.get_bom_configured_data(
input_line, line_quantity
)
else:
result.append(line)
result.append(
{
"line": line,
"product_qty": line_quantity,
}
)

return result

Expand Down
13 changes: 5 additions & 8 deletions mrp_bom_configurable/models/mrp_bom_configured.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,18 @@ def _default_product_id(self):

def _default_line_ids(self):
input_line_id = self.env["input.line"].browse(self.env.context.get("active_id"))
components, _ = input_line_id._get_filtered_components_from_values()
components = input_line_id.create_bom_line_data()
lines = []
# TODO(franz): since quantity is tree dependent _get_filtered_components_from_values
# should take this into account to allow for proper quantity computation
for comp in components:
quantity = (
comp.compute_qty_from_formula(input_line_id)
if comp.use_formula_compute_qty
else comp.product_qty
)
# price += quantity * comp.product_id.lst_price
lines.append(
self.env["mrp.bom.line.configured"]
.create(
{
"product_id": comp.product_id.id,
"product_qty": quantity,
"product_id": comp["product_id"].id,
"product_qty": comp["product_qty"],
}
)
.id
Expand Down
94 changes: 54 additions & 40 deletions mrp_bom_configurable/models/mrp_bom_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,57 @@
logger = logging.getLogger(__name__)


def check_domain(domain, values, current_name, parent_name):
domain = domain.replace("'", '"')
domain = domain.replace('"="', '"=="')
domain = domain.replace('"&", ', "")
domain = domain.replace('"&",', "")
domain = safe_eval(domain.replace("!==", "!="))

return execute_domain(domain, values, current_name, parent_name)


def execute_domain_element(element, values, current_name, parent_name):
# TODO support len(element) == 1, because element can be '&' and '|'
if len(element) != 3:
logger.warning("Domain element %s" % element)
param, operator, value = element
if param not in values:
raise UserError(
f"Wrong param name ({param}) for domain {current_name}"
+ f"in {parent_name}"
)
code = f"{repr(values[param])} {operator} {repr(value)}"

result = None

result = safe_eval(code)

return result


def execute_domain(domain, values, current_name, parent_name):
if len(domain) == 0:
return True
if domain[0] == "OR":
return any(
execute_domain(domain_elm, values, current_name, parent_name)
for domain_elm in domain[1:]
)
elif isinstance(domain, list):
return all(
execute_domain(domain_elm, values, current_name, parent_name)
for domain_elm in domain
)
else:
try:
return execute_domain_element(domain, values, current_name, parent_name)
except SyntaxError:
raise exceptions.ValidationError(
f"Domain {domain} is incorrect on {current_name}"
) from None


class MrpBomLine(models.Model):
_inherit = "mrp.bom.line"

Expand Down Expand Up @@ -58,51 +109,14 @@ def goto_configurable_bom_report(self):
"target": "new",
}

def execute_domain_element(self, element, values):
# TODO support len(element) == 1, because element can be '&' and '|'
if len(element) != 3:
logger.warning("Domain element %s" % element)
param, operator, value = element
if param not in values:
raise UserError(
f"Wrong param name ({param}) in domain {self.product_tmpl_id.name}"
+ f"in BoM {self.bom_id.product_tmpl_id.name}"
)
code = f"{repr(values[param])} {operator} {repr(value)}"

result = None

try:
result = safe_eval(code)
except SyntaxError:
raise exceptions.ValidationError(
f"Domain {self.domain} is incorrect on {self.product_id.name}"
) from None

return result

def execute_domain(self, domain, values):
if domain[0] == "OR":
return any(
self.execute_domain(domain_elm, values) for domain_elm in domain[1:]
)
elif isinstance(domain, list):
return all(self.execute_domain(domain_elm, values) for domain_elm in domain)
else:
return self.execute_domain_element(domain, values)

def execute(self, values):
self.ensure_one()
if not self.domain:
return True
else:
# TODO clean to support '&' and '|' in domain
domain = self.domain.replace("'", '"')
domain = domain.replace('"="', '"=="')
domain = domain.replace('"&", ', "")
domain = domain.replace('"&",', "")
domain = safe_eval(domain.replace("!==", "!="))
return self.execute_domain(domain, values)
return check_domain(
self.domain, values, self.product_id.name, self.bom_id.product_id.name
)

def ui_update_domain(self):
self.ensure_one()
Expand Down

0 comments on commit be7e336

Please sign in to comment.