Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[16.0] [IMP] sale_mrp_bom: ensure bom_id can only be selected if right routing (manufacturing) is settle #3405

Draft
wants to merge 2 commits into
base: 16.0
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .copier-answers.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Do NOT update manually; changes here will be overwritten by Copier
_commit: v1.21.1
_commit: v1.27
_src_path: gh:oca/oca-addons-repo-template
ci: GitHub
convert_readme_fragments_to_markdown: false
enable_checklog_odoo: false
generate_requirements_txt: true
github_check_license: true
github_ci_extra_env: {}
Expand Down
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,19 @@ var/
*.egg
*.eggs

# Windows installers
*.msi

# Debian packages
*.deb

# Redhat packages
*.rpm

# MacOS packages
*.dmg
*.pkg

# Installer logs
pip-log.txt
pip-delete-this-directory.txt
Expand Down
34 changes: 23 additions & 11 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ exclude: |
# Files and folders generated by bots, to avoid loops
^setup/|/static/description/index\.html$|
# We don't want to mess with tool-generated files
.svg$|/tests/([^/]+/)?cassettes/|^.copier-answers.yml$|^.github/|
.svg$|/tests/([^/]+/)?cassettes/|^.copier-answers.yml$|^.github/|^eslint.config.cjs|^prettier.config.cjs|
# Maybe reactivate this when all README files include prettier ignore tags?
^README\.md$|
# Library files can have extraneous formatting (even minimized)
Expand Down Expand Up @@ -39,7 +39,7 @@ repos:
language: fail
files: '[a-zA-Z0-9_]*/i18n/en\.po$'
- repo: https://github.com/oca/maintainer-tools
rev: 9a170331575a265c092ee6b24b845ec508e8ef75
rev: d5fab7ee87fceee858a3d01048c78a548974d935
hooks:
# update the NOT INSTALLABLE ADDONS section above
- id: oca-update-pre-commit-excluded-addons
Expand All @@ -58,6 +58,8 @@ repos:
hooks:
- id: oca-checks-odoo-module
- id: oca-checks-po
args:
- --disable=po-pretty-format
- repo: https://github.com/myint/autoflake
rev: v1.6.1
hooks:
Expand All @@ -73,25 +75,35 @@ repos:
rev: 22.8.0
hooks:
- id: black
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v2.7.1
- repo: local
hooks:
- id: prettier
name: prettier (with plugin-xml)
entry: prettier
args:
- --write
- --list-different
- --ignore-unknown
types: [text]
files: \.(css|htm|html|js|json|jsx|less|md|scss|toml|ts|xml|yaml|yml)$
language: node
additional_dependencies:
- "[email protected]"
- "@prettier/[email protected]"
args:
- --plugin=@prettier/plugin-xml
files: \.(css|htm|html|js|json|jsx|less|md|scss|toml|ts|xml|yaml|yml)$
- repo: https://github.com/pre-commit/mirrors-eslint
rev: v8.24.0
- repo: local
hooks:
- id: eslint
verbose: true
name: eslint
entry: eslint
args:
- --color
- --fix
verbose: true
types: [javascript]
language: node
additional_dependencies:
- "[email protected]"
- "eslint-plugin-jsdoc@"
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
hooks:
Expand Down Expand Up @@ -138,7 +150,7 @@ repos:
- --header
- "# generated from manifests external_dependencies"
- repo: https://github.com/PyCQA/flake8
rev: 3.9.2
rev: 7.1.1
hooks:
- id: flake8
name: flake8
Expand Down
2 changes: 1 addition & 1 deletion sale_blanket_order/models/blanket_orders.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ def _compute_state(self):
order.state = "expired"
elif float_is_zero(
sum(
order.line_ids.filtered(lambda l: not l.display_type).mapped(
order.line_ids.filtered(lambda line: not line.display_type).mapped(
"remaining_uom_qty"
)
),
Expand Down
4 changes: 2 additions & 2 deletions sale_blanket_order/models/sale_orders.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,14 @@ def _get_assigned_bo_line(self, bo_lines):
assigned_bo_line = False
date_planned = date.today()
date_delta = timedelta(days=365)
for line in bo_lines.filtered(lambda l: l.date_schedule):
for line in bo_lines.filtered(lambda line: line.date_schedule):
date_schedule = line.date_schedule
if date_schedule and abs(date_schedule - date_planned) < date_delta:
assigned_bo_line = line
date_delta = abs(date_schedule - date_planned)
if assigned_bo_line:
return assigned_bo_line
non_date_bo_lines = bo_lines.filtered(lambda l: not l.date_schedule)
non_date_bo_lines = bo_lines.filtered(lambda line: not line.date_schedule)
if non_date_bo_lines:
return non_date_bo_lines[0]

Expand Down
10 changes: 5 additions & 5 deletions sale_blanket_order/tests/test_blanket_orders.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,29 +390,29 @@ def test_06_create_sale_orders_from_blanket_order(self):
wizard1 = self.blanket_order_wiz_obj.with_context(
active_id=blanket_order.id, active_model="sale.blanket.order"
).create({})
wizard1.line_ids.filtered(lambda l: l.product_id == self.product).write(
wizard1.line_ids.filtered(lambda line: line.product_id == self.product).write(
{"qty": 10.0}
)
wizard1.line_ids.filtered(lambda l: l.product_id == self.product2).write(
wizard1.line_ids.filtered(lambda line: line.product_id == self.product2).write(
{"qty": 10.0}
)
wizard1.sudo().create_sale_order()

wizard2 = self.blanket_order_wiz_obj.with_context(
active_id=blanket_order.id, active_model="sale.blanket.order"
).create({})
wizard2.line_ids.filtered(lambda l: l.product_id == self.product).write(
wizard2.line_ids.filtered(lambda line: line.product_id == self.product).write(
{"qty": 20.0}
)
wizard2.line_ids.filtered(lambda l: l.product_id == self.product2).write(
wizard2.line_ids.filtered(lambda line: line.product_id == self.product2).write(
{"qty": 0}
)
wizard2.sudo().create_sale_order()

wizard3 = self.blanket_order_wiz_obj.with_context(
active_id=blanket_order.id, active_model="sale.blanket.order"
).create({})
wizard3.line_ids.filtered(lambda l: l.product_id == self.product2).write(
wizard3.line_ids.filtered(lambda line: line.product_id == self.product2).write(
{"qty": 10.0}
)
wizard3.sudo().create_sale_order()
Expand Down
2 changes: 1 addition & 1 deletion sale_blanket_order/tests/test_sale_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ def test_02_create_sale_order(self):
so_line.onchange_product_id()
self.assertEqual(
so_line._get_eligible_bo_lines(),
bo_lines.filtered(lambda l: l.product_id == self.product),
bo_lines.filtered(lambda line: line.product_id == self.product),
)
bo_line_assigned = self.blanket_order_line_obj.search(
[
Expand Down
4 changes: 2 additions & 2 deletions sale_blanket_order/wizard/create_sale_orders.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def _default_lines(self):
},
)
for bol in bo_lines.filtered(
lambda l: not l.display_type and l.remaining_uom_qty != 0.0
lambda line: not line.display_type and line.remaining_uom_qty != 0.0
)
]
return lines
Expand Down Expand Up @@ -137,7 +137,7 @@ def create_sale_order(self):
pricelist_id = 0
user_id = 0
payment_term_id = 0
for line in self.line_ids.filtered(lambda l: l.qty != 0.0):
for line in self.line_ids.filtered(lambda line: line.qty != 0.0):
if line.qty > line.remaining_uom_qty:
raise UserError(_("You can't order more than the remaining quantities"))
vals = self._prepare_so_line_vals(line)
Expand Down
6 changes: 4 additions & 2 deletions sale_block_no_stock/wizard/sale_order_block_wizard.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,12 @@ def _compute_is_adjustable(self):
for record in self:
lines = record.mapped("sale_line_block_ids")
record.is_packaging_adjustable = bool(
lines.filtered(lambda l: l.product_packaging_allowed_max_qty > 0.0)
lines.filtered(
lambda line: line.product_packaging_allowed_max_qty > 0.0
)
)
record.is_uom_adjustable = bool(
lines.filtered(lambda l: l.product_uom_allowed_max_qty > 0.0)
lines.filtered(lambda line: line.product_uom_allowed_max_qty > 0.0)
)

def confirm(self):
Expand Down
2 changes: 1 addition & 1 deletion sale_elaboration/tests/test_sale_elaboration.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def test_invoice_elaboration(self):
]
)
self.order.order_line.filtered(
lambda l: l.product_id == self.product_elaboration_B
lambda line: line.product_id == self.product_elaboration_B
).is_elaboration = False
self.order.action_confirm()
invoice = self.order._create_invoices()
Expand Down
2 changes: 1 addition & 1 deletion sale_global_discount/models/sale_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def _check_global_discounts_sanity(self):
return True
taxes_keys = {}
for line in self.order_line.filtered(
lambda l: not l.display_type and l.product_id
lambda line: not line.display_type and line.product_id
):
if not line.tax_id:
raise exceptions.UserError(
Expand Down
8 changes: 4 additions & 4 deletions sale_invoice_policy/models/sale_order_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ class SaleOrderLine(models.Model):
)
def _compute_qty_to_invoice(self):
other_lines = self.filtered(
lambda l: l.product_id.type == "service"
or not l.order_id.invoice_policy
or not l.order_id.invoice_policy_required
lambda line: line.product_id.type == "service"
or not line.order_id.invoice_policy
or not line.order_id.invoice_policy_required
)
super(SaleOrderLine, other_lines)._compute_qty_to_invoice()
for line in self - other_lines:
Expand Down Expand Up @@ -67,7 +67,7 @@ def _compute_untaxed_amount_to_invoice(self):
partner=line.order_id.partner_shipping_id,
)["total_excluded"]
inv_lines = line._get_invoice_lines()
if any(inv_lines.mapped(lambda l: l.discount != line.discount)):
if any(inv_lines.mapped(lambda line: line.discount != line.discount)):
amount = 0
for inv_line in inv_lines:
if (
Expand Down
2 changes: 1 addition & 1 deletion sale_manual_delivery/models/sale_order_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def _action_launch_stock_rule_manual(self, previous_product_uom_qty=False):
# Qty comes from the manual delivery wizard
# This is different than the original method
manual_line = manual_delivery.line_ids.filtered(
lambda l: l.order_line_id == line
lambda line: line.order_line_id == line
)
if not manual_line.quantity:
continue
Expand Down
15 changes: 15 additions & 0 deletions sale_mrp_bom/models/sale_order_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class SaleOrderLine(models.Model):
"('product_id', '=', False)]",
)

can_set_bom_id = fields.Boolean(store=True, compute="_compute_can_set_bom_id")

@api.constrains("bom_id", "product_id")
def _check_match_product_variant_ids(self):
for line in self:
Expand All @@ -32,3 +34,16 @@ def _check_match_product_variant_ids(self):
"Please select BoM that has matched product with the line `{}`"
).format(line_product.name)
)

@api.depends("product_id.route_ids", "is_mto")
def _compute_can_set_bom_id(self):
manufacture_route = self.env.ref(
"mrp.route_warehouse0_manufacture", raise_if_not_found=False
)
for line in self:
can_set_bom_id = False
if line.product_id and manufacture_route:
can_set_bom_id = (
manufacture_route in line.product_id.route_ids and line.is_mto
)
line.can_set_bom_id = can_set_bom_id
Binary file modified sale_mrp_bom/static/description/manufacturing_order_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified sale_mrp_bom/static/description/sale_order_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions sale_mrp_bom/views/sale_order.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,25 @@
expr="//field[@name='order_line']//tree//field[@name='name']"
position="after"
>
<field name="can_set_bom_id" invisible="1" />
<field
name="bom_id"
groups="sale_mrp_bom.sale_mrp_bom_group"
context="{'default_product_id': product_id, 'default_product_tmpl_id': product_template_id}"
attrs="{'readonly': [('can_set_bom_id', '=', False)]}"
/>
</xpath>
<xpath
expr="//field[@name='order_line']//form//field[@name='customer_lead']"
position="after"
>
<field name="product_template_id" invisible="1" />
<field name="can_set_bom_id" invisible="1" />
<field
name="bom_id"
groups="sale_mrp_bom.sale_mrp_bom_group"
context="{'default_product_id': product_id, 'default_product_tmpl_id': product_template_id}"
attrs="{'readonly': [('can_set_bom_id', '=', False)]}"
/>
</xpath>
</field>
Expand Down
7 changes: 6 additions & 1 deletion sale_mrp_bom/views/sale_order_line.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@
<field name="inherit_id" ref="sale.view_order_line_tree" />
<field name="arch" type="xml">
<field name="route_id" position="after">
<field name="bom_id" groups="sale_mrp_bom.sale_mrp_bom_group" />
<field name="can_set_bom_id" invisible="1" />
<field
name="bom_id"
groups="sale_mrp_bom.sale_mrp_bom_group"
attrs="{'readonly': [('can_set_bom_id', '=', False)]}"
/>
</field>
</field>
</record>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ def test_sale_order_carrier_auto_assign(self):
self.sale_order.action_confirm()
self.assertEqual(self.sale_order.state, "sale")
self.assertEqual(self.sale_order.carrier_id, self.delivery_local_delivery)
delivery_line = self.sale_order.order_line.filtered(lambda l: l.is_delivery)
delivery_line = self.sale_order.order_line.filtered(
lambda line: line.is_delivery
)
delivery_rate = self.delivery_local_delivery.rate_shipment(self.sale_order)
self.assertEqual(delivery_line.price_unit, delivery_rate["carrier_price"])

Expand Down
4 changes: 2 additions & 2 deletions sale_order_line_sequence/models/sale_order_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class SaleOrderLine(models.Model):
def _compute_visible_sequence(self):
for so in self.mapped("order_id"):
sequence = 1
order_lines = so.order_line.filtered(lambda l: not l.display_type)
for line in sorted(order_lines, key=lambda l: l.sequence):
order_lines = so.order_line.filtered(lambda line: not line.display_type)
for line in sorted(order_lines, key=lambda line: line.sequence):
line.visible_sequence = sequence
sequence += 1
2 changes: 1 addition & 1 deletion sale_order_lot_generator/models/sale_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def _get_max_lot_index(self):
# when a new line is added to confirmed sale order
# get the max index_lot from the other lines
index_lot = 0
lot_ids = self.order_line.filtered(lambda l: l.lot_id).mapped("lot_id")
lot_ids = self.order_line.filtered(lambda line: line.lot_id).mapped("lot_id")
for lot in lot_ids:
lot_name = lot.name
index_str = lot_name.replace(self.name + "-", "")
Expand Down
Loading