From 11dd17dd40b8d3a9f8eeac43df88c1f6f821152e Mon Sep 17 00:00:00 2001 From: Eric Antones Date: Thu, 2 Apr 2026 18:54:05 +0200 Subject: [PATCH 1/2] [FIX] rental_base_extension: show rental service button on multi-variant products The "Create Rental Service" button and the "Rentals" section were hidden on product templates with more than one variant, preventing users from creating rental services for existing products with variants (e.g. regulators with sizes, wetsuits with sizes). Now the "Rentals" section is visible for all storable products regardless of variant count. For single-variant products, the original wizard is used. For multi-variant products, a new button creates rental services for all variants at once. Also restrict the "Can be Rented" checkbox and the "Rentals" section to storable products only (type == 'product'), hiding them for consumables and services. --- rental_base_extension/models/__init__.py | 1 + rental_base_extension/models/product.py | 45 +++++++++++++++++++ rental_base_extension/views/product_views.xml | 15 +++++-- 3 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 rental_base_extension/models/product.py diff --git a/rental_base_extension/models/__init__.py b/rental_base_extension/models/__init__.py index ba1c090c8..7baeb4153 100644 --- a/rental_base_extension/models/__init__.py +++ b/rental_base_extension/models/__init__.py @@ -1,3 +1,4 @@ +from . import product from . import res_company from . import res_config_settings from . import sale_order diff --git a/rental_base_extension/models/product.py b/rental_base_extension/models/product.py new file mode 100644 index 000000000..79b9756cf --- /dev/null +++ b/rental_base_extension/models/product.py @@ -0,0 +1,45 @@ +# Copyright 2026 NuoBiT Solutions SL - Eric Antones +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) + +from odoo import _, models +from odoo.exceptions import UserError + + +class ProductTemplate(models.Model): + _inherit = "product.template" + + def action_create_rental_services(self): + self.ensure_one() + day_uom = self.env.ref("uom.product_uom_day") + variants_without_service = self.product_variant_ids.filtered( + lambda v: not v.rental_service_ids + ) + if not variants_without_service: + raise UserError(_("All variants already have a rental service.")) + created_products = self.env["product.product"] + for variant in variants_without_service: + variant_ctx = variant.with_context(display_default_code=False) + vals = { + "type": "service", + "sale_ok": True, + "purchase_ok": False, + "uom_id": day_uom.id, + "uom_po_id": day_uom.id, + "list_price": 1.0, + "name": _("Rental of %s") % variant_ctx.display_name, + "rented_product_id": variant.id, + "must_have_dates": True, + "categ_id": self.categ_id.id, + "invoice_policy": "order", + } + if variant.default_code: + vals["default_code"] = _("RENT-%s") % variant.default_code + created_products |= self.env["product.product"].create(vals) + return { + "type": "ir.actions.act_window", + "name": _("Created Rental Services"), + "res_model": "product.product", + "view_mode": "tree,form", + "domain": [("id", "in", created_products.ids)], + "target": "current", + } diff --git a/rental_base_extension/views/product_views.xml b/rental_base_extension/views/product_views.xml index 56ac2d067..eee441cda 100644 --- a/rental_base_extension/views/product_views.xml +++ b/rental_base_extension/views/product_views.xml @@ -2,7 +2,7 @@ - + product.template.form.inherit.rental_base_extension product.template @@ -13,7 +13,7 @@ position="attributes" > - {'invisible': [('type', '=', 'service')]} + {'invisible': [('type', '!=', 'product')]} @@ -56,7 +56,7 @@