diff --git a/.copier-answers.yml b/.copier-answers.yml index bbacbe9d933..48c84e4a437 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -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: {} diff --git a/.gitignore b/.gitignore index 0090721f5d2..6ec07a054bd 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 16880062953..d54bb26b799 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -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) @@ -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 @@ -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: @@ -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: - "prettier@2.7.1" - "@prettier/plugin-xml@2.2.0" - 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: + - "eslint@8.24.0" + - "eslint-plugin-jsdoc@" - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.3.0 hooks: @@ -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 diff --git a/sale_blanket_order/models/blanket_orders.py b/sale_blanket_order/models/blanket_orders.py index d8db2241243..745fa4e429a 100644 --- a/sale_blanket_order/models/blanket_orders.py +++ b/sale_blanket_order/models/blanket_orders.py @@ -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" ) ), diff --git a/sale_blanket_order/models/sale_orders.py b/sale_blanket_order/models/sale_orders.py index 1df8a51840e..10d5038333b 100644 --- a/sale_blanket_order/models/sale_orders.py +++ b/sale_blanket_order/models/sale_orders.py @@ -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] diff --git a/sale_blanket_order/tests/test_blanket_orders.py b/sale_blanket_order/tests/test_blanket_orders.py index b7bc6c9aed7..371c07bdf95 100644 --- a/sale_blanket_order/tests/test_blanket_orders.py +++ b/sale_blanket_order/tests/test_blanket_orders.py @@ -390,10 +390,10 @@ 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() @@ -401,10 +401,10 @@ def test_06_create_sale_orders_from_blanket_order(self): 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() @@ -412,7 +412,7 @@ def test_06_create_sale_orders_from_blanket_order(self): 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() diff --git a/sale_blanket_order/tests/test_sale_order.py b/sale_blanket_order/tests/test_sale_order.py index 49f302c1ab7..c91d478e050 100644 --- a/sale_blanket_order/tests/test_sale_order.py +++ b/sale_blanket_order/tests/test_sale_order.py @@ -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( [ diff --git a/sale_blanket_order/wizard/create_sale_orders.py b/sale_blanket_order/wizard/create_sale_orders.py index 13eff9342c1..18464c6274e 100644 --- a/sale_blanket_order/wizard/create_sale_orders.py +++ b/sale_blanket_order/wizard/create_sale_orders.py @@ -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 @@ -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) diff --git a/sale_block_no_stock/wizard/sale_order_block_wizard.py b/sale_block_no_stock/wizard/sale_order_block_wizard.py index 23a52e663a5..aa1275a441b 100644 --- a/sale_block_no_stock/wizard/sale_order_block_wizard.py +++ b/sale_block_no_stock/wizard/sale_order_block_wizard.py @@ -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): diff --git a/sale_elaboration/tests/test_sale_elaboration.py b/sale_elaboration/tests/test_sale_elaboration.py index f7fc139a66d..5941fc0354e 100644 --- a/sale_elaboration/tests/test_sale_elaboration.py +++ b/sale_elaboration/tests/test_sale_elaboration.py @@ -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() diff --git a/sale_global_discount/models/sale_order.py b/sale_global_discount/models/sale_order.py index 513c52e1d5f..fa503a3dc19 100644 --- a/sale_global_discount/models/sale_order.py +++ b/sale_global_discount/models/sale_order.py @@ -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( diff --git a/sale_invoice_policy/models/sale_order_line.py b/sale_invoice_policy/models/sale_order_line.py index a00f8204e02..8b9254cd8a8 100644 --- a/sale_invoice_policy/models/sale_order_line.py +++ b/sale_invoice_policy/models/sale_order_line.py @@ -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: @@ -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 ( diff --git a/sale_manual_delivery/models/sale_order_line.py b/sale_manual_delivery/models/sale_order_line.py index c84ffb4fda2..7b68ccd7e39 100644 --- a/sale_manual_delivery/models/sale_order_line.py +++ b/sale_manual_delivery/models/sale_order_line.py @@ -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 diff --git a/sale_mrp_bom/models/sale_order_line.py b/sale_mrp_bom/models/sale_order_line.py index 8a227d181c9..eb0f85b0a5e 100644 --- a/sale_mrp_bom/models/sale_order_line.py +++ b/sale_mrp_bom/models/sale_order_line.py @@ -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: @@ -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 diff --git a/sale_mrp_bom/static/description/manufacturing_order_1.png b/sale_mrp_bom/static/description/manufacturing_order_1.png index 356c652ed63..26b8c7b509f 100644 Binary files a/sale_mrp_bom/static/description/manufacturing_order_1.png and b/sale_mrp_bom/static/description/manufacturing_order_1.png differ diff --git a/sale_mrp_bom/static/description/sale_order_1.png b/sale_mrp_bom/static/description/sale_order_1.png index 4335d510521..4fdbf8ad539 100644 Binary files a/sale_mrp_bom/static/description/sale_order_1.png and b/sale_mrp_bom/static/description/sale_order_1.png differ diff --git a/sale_mrp_bom/views/sale_order.xml b/sale_mrp_bom/views/sale_order.xml index f75a6ecd18f..ddc9e7548ab 100644 --- a/sale_mrp_bom/views/sale_order.xml +++ b/sale_mrp_bom/views/sale_order.xml @@ -9,10 +9,12 @@ expr="//field[@name='order_line']//tree//field[@name='name']" position="after" > + + diff --git a/sale_mrp_bom/views/sale_order_line.xml b/sale_mrp_bom/views/sale_order_line.xml index fabfd97ac0d..56cc4535c26 100644 --- a/sale_mrp_bom/views/sale_order_line.xml +++ b/sale_mrp_bom/views/sale_order_line.xml @@ -6,7 +6,12 @@ - + + diff --git a/sale_order_carrier_auto_assign/tests/test_sale_order_carrier_auto_assign.py b/sale_order_carrier_auto_assign/tests/test_sale_order_carrier_auto_assign.py index c5733286a42..06cb2c95e42 100644 --- a/sale_order_carrier_auto_assign/tests/test_sale_order_carrier_auto_assign.py +++ b/sale_order_carrier_auto_assign/tests/test_sale_order_carrier_auto_assign.py @@ -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"]) diff --git a/sale_order_line_sequence/models/sale_order_line.py b/sale_order_line_sequence/models/sale_order_line.py index 0d234765c38..832776b8d6e 100644 --- a/sale_order_line_sequence/models/sale_order_line.py +++ b/sale_order_line_sequence/models/sale_order_line.py @@ -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 diff --git a/sale_order_lot_generator/models/sale_order.py b/sale_order_lot_generator/models/sale_order.py index dd98c63da7d..f69f8192bb1 100644 --- a/sale_order_lot_generator/models/sale_order.py +++ b/sale_order_lot_generator/models/sale_order.py @@ -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 + "-", "")