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 @@
+
+
+
+
+
+
+ Deposit Required:
+
+
+
+
+
+
+
+
+
+
+ not line.is_deposit_line
+
+
+