From 05e927c81e8cfbc9769dc1ce6f3505a8e2155755 Mon Sep 17 00:00:00 2001 From: rodh-odoo Date: Mon, 28 Jul 2025 14:20:39 +0530 Subject: [PATCH] [ADD] rental_deposit: implement deposit amount feature for rental products -Introduced configuration option to select a deposit product for rental orders -Added Require Deposit checkbox and amount field on rental product form -Automatically add deposit line with specified amount when adding rental product to orders -Display deposit price on website product page, updating with quantity changes -Show deposit amount with currency in order overview and checkout --- rental_deposit/__init__.py | 1 + rental_deposit/__manifest__.py | 17 +++++++++ rental_deposit/models/__init__.py | 4 +++ rental_deposit/models/product_template.py | 31 ++++++++++++++++ rental_deposit/models/res_config_settings.py | 12 +++++++ rental_deposit/models/sale_order.py | 35 +++++++++++++++++++ rental_deposit/models/sale_order_line.py | 28 +++++++++++++++ rental_deposit/security/ir.model.access.csv | 2 ++ .../views/product_template_views.xml | 16 +++++++++ .../views/res_config_settings_views.xml | 13 +++++++ rental_deposit/views/website_sale_product.xml | 29 +++++++++++++++ 11 files changed, 188 insertions(+) create mode 100644 rental_deposit/__init__.py create mode 100644 rental_deposit/__manifest__.py create mode 100644 rental_deposit/models/__init__.py create mode 100644 rental_deposit/models/product_template.py create mode 100644 rental_deposit/models/res_config_settings.py create mode 100644 rental_deposit/models/sale_order.py create mode 100644 rental_deposit/models/sale_order_line.py create mode 100644 rental_deposit/security/ir.model.access.csv create mode 100644 rental_deposit/views/product_template_views.xml create mode 100644 rental_deposit/views/res_config_settings_views.xml create mode 100644 rental_deposit/views/website_sale_product.xml diff --git a/rental_deposit/__init__.py b/rental_deposit/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/rental_deposit/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/rental_deposit/__manifest__.py b/rental_deposit/__manifest__.py new file mode 100644 index 00000000000..17179067cce --- /dev/null +++ b/rental_deposit/__manifest__.py @@ -0,0 +1,17 @@ +{ + 'name': 'Rental Deposit', + 'version': '1.0', + 'category': 'Rental', + 'author': 'rodh', + 'license': "LGPL-3", + 'summary': 'Add deposit product functionality for rentals', + 'depends': ['sale_renting', 'website_sale'], + 'data': [ + 'views/res_config_settings_views.xml', + 'views/product_template_views.xml', + 'views/website_sale_product.xml', + ], + 'installable': True, + 'auto_install': False, + 'application': False, +} diff --git a/rental_deposit/models/__init__.py b/rental_deposit/models/__init__.py new file mode 100644 index 00000000000..3b8e35bd3bc --- /dev/null +++ b/rental_deposit/models/__init__.py @@ -0,0 +1,4 @@ +from . import product_template +from . import res_config_settings +from . import sale_order +from . import sale_order_line diff --git a/rental_deposit/models/product_template.py b/rental_deposit/models/product_template.py new file mode 100644 index 00000000000..53eac0bfce5 --- /dev/null +++ b/rental_deposit/models/product_template.py @@ -0,0 +1,31 @@ +from odoo import api, fields, models + + +class ProductTemplate(models.Model): + _inherit = 'product.template' + + require_deposit = fields.Boolean(string="Require Deposit") + deposit_amount = fields.Monetary(string="Deposit Amount", currency_field='currency_id') + + @api.onchange('require_deposit') + def _onchange_requires_deposit(self): + if self.require_deposit: + param_obj = self.env['ir.config_parameter'].sudo() + deposit_product_id = param_obj.get_param('rental_deposit.deposit_product_id') + if deposit_product_id: + deposit_product = self.env['product.product'].browse(int(deposit_product_id)) + if deposit_product: + self.deposit_amount = deposit_product.list_price + else: + self.deposit_amount = 0.0 + else: + self.deposit_amount = 0.0 + else: + self.deposit_amount = 0.0 + + +class ProductProduct(models.Model): + _inherit = 'product.product' + + require_deposit = fields.Boolean(related='product_tmpl_id.require_deposit', readonly=False) + deposit_amount = fields.Monetary(related='product_tmpl_id.deposit_amount', currency_field='currency_id', readonly=False) diff --git a/rental_deposit/models/res_config_settings.py b/rental_deposit/models/res_config_settings.py new file mode 100644 index 00000000000..8e6e207f397 --- /dev/null +++ b/rental_deposit/models/res_config_settings.py @@ -0,0 +1,12 @@ +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = 'res.config.settings' + + rental_deposit_product_id = fields.Many2one( + 'product.product', + string='Deposit Product', + domain=[('sale_ok', '=', True)], + config_parameter='rental_deposit.product_id' + ) diff --git a/rental_deposit/models/sale_order.py b/rental_deposit/models/sale_order.py new file mode 100644 index 00000000000..66d176f6210 --- /dev/null +++ b/rental_deposit/models/sale_order.py @@ -0,0 +1,35 @@ +from odoo import api, models + + +class SaleOrder(models.Model): + _inherit = 'sale.order' + + @api.model_create_multi + def create(self, vals_list): + orders = super().create(vals_list) + for order in orders: + order._add_deposit_lines() + return orders + + def _add_deposit_lines(self): + for line in self.order_line: + product = line.product_id + if product.require_deposit: + exists = self.order_line.filtered( + lambda l: l.is_deposit_line and l.product_id == product + ) + if not exists: + self.env['sale.order.line'].create({ + 'order_id': self.id, + 'product_id': product.id, + 'name': f"Deposit for {product.display_name}", + 'product_uom_qty': line.product_uom_qty, + 'price_unit': product.deposit_amount, + 'is_deposit_line': True, + }) + + def _cart_update(self, product_id=None, line_id=None, add_qty=0, set_qty=0, **kwargs): + res = super()._cart_update(product_id=product_id, line_id=line_id, add_qty=add_qty, set_qty=set_qty, **kwargs) + self._add_deposit_lines() + + return res diff --git a/rental_deposit/models/sale_order_line.py b/rental_deposit/models/sale_order_line.py new file mode 100644 index 00000000000..2b9c47b0560 --- /dev/null +++ b/rental_deposit/models/sale_order_line.py @@ -0,0 +1,28 @@ +from odoo import api, fields, models + + +class SaleOrderLine(models.Model): + _inherit = "sale.order.line" + + deposit_amount = fields.Monetary( + string="Deposit Amount", + compute="_compute_deposit_amount", + currency_field="currency_id" + ) + is_deposit_line = fields.Boolean( + string="Is Deposit Line", + help="Indicates whether this line is for a rental deposit", + default=False + ) + + @api.depends('product_id') + def _compute_is_deposit_line(self): + for line in self: + line.is_deposit_line = line.product_id and line.product_id.is_deposit_product + + def _compute_deposit_amount(self): + for line in self: + if line.product_id.rent_ok: + line.deposit_amount = line.product_id.deposit_amount or (line.price_unit * 0.5) + else: + line.deposit_amount = 0.0 diff --git a/rental_deposit/security/ir.model.access.csv b/rental_deposit/security/ir.model.access.csv new file mode 100644 index 00000000000..ebabe9415c5 --- /dev/null +++ b/rental_deposit/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_sale_order_line_deposit,sale.order.line.deposit,model_sale_order_line,,1,1,1,1 diff --git a/rental_deposit/views/product_template_views.xml b/rental_deposit/views/product_template_views.xml new file mode 100644 index 00000000000..9de6c703838 --- /dev/null +++ b/rental_deposit/views/product_template_views.xml @@ -0,0 +1,16 @@ + + + + product.template.inherit + product.template + + + + + + + + + + + diff --git a/rental_deposit/views/res_config_settings_views.xml b/rental_deposit/views/res_config_settings_views.xml new file mode 100644 index 00000000000..cd9f2335787 --- /dev/null +++ b/rental_deposit/views/res_config_settings_views.xml @@ -0,0 +1,13 @@ + + + res.config.settings.view.form.deposit + res.config.settings + + + + + + + diff --git a/rental_deposit/views/website_sale_product.xml b/rental_deposit/views/website_sale_product.xml new file mode 100644 index 00000000000..8a498c1c167 --- /dev/null +++ b/rental_deposit/views/website_sale_product.xml @@ -0,0 +1,29 @@ + + + + +