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 + "-", "")