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..4d397fa30cd
--- /dev/null
+++ b/rental_deposit/__manifest__.py
@@ -0,0 +1,16 @@
+{
+ 'name': 'Rental deposit',
+ 'author': "keman",
+ 'license': 'LGPL-3',
+ 'depends': ['sale_renting', 'website_sale'],
+ 'data': [
+ 'views/res_config_settings_views.xml',
+ 'views/product_template_views.xml',
+ 'views/website_sale_template_views.xml'
+ ],
+ 'assets': {
+ 'web.assets_frontend': [
+ 'rental_deposit/static/src/js/deposit.js',
+ ],
+ },
+}
diff --git a/rental_deposit/models/__init__.py b/rental_deposit/models/__init__.py
new file mode 100644
index 00000000000..2b5d0f43a47
--- /dev/null
+++ b/rental_deposit/models/__init__.py
@@ -0,0 +1,3 @@
+from . import res_config_settings
+from . import product_template
+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..54c1a69f68f
--- /dev/null
+++ b/rental_deposit/models/product_template.py
@@ -0,0 +1,8 @@
+from odoo import fields, models
+
+
+class ProductTemplate(models.Model):
+ _inherit = "product.template"
+
+ require_deposite = fields.Boolean()
+ amount = fields.Float()
diff --git a/rental_deposit/models/res_config_settings.py b/rental_deposit/models/res_config_settings.py
new file mode 100644
index 00000000000..38cf5257f31
--- /dev/null
+++ b/rental_deposit/models/res_config_settings.py
@@ -0,0 +1,11 @@
+from odoo import fields, models
+
+
+class ResConfigSettings(models.TransientModel):
+ _inherit = "res.config.settings"
+
+ deposit_product_id = fields.Many2one(
+ "product.product",
+ string="Deposit",
+ config_parameter="rental_deposit.deposit_product_id",
+ )
diff --git a/rental_deposit/models/sale_order_line.py b/rental_deposit/models/sale_order_line.py
new file mode 100644
index 00000000000..2f809cd907f
--- /dev/null
+++ b/rental_deposit/models/sale_order_line.py
@@ -0,0 +1,68 @@
+from odoo import api, fields, models
+
+
+class SaleOrderLine(models.Model):
+ _inherit = "sale.order.line"
+
+ is_deposit_line = fields.Boolean(default=False)
+
+ deposit_origin_line_id = fields.Many2one(
+ "sale.order.line",
+ ondelete="cascade",
+ )
+
+ def _get_line_header(self):
+ if self.is_deposit_line and self.name:
+ return self.name
+ return super()._get_line_header()
+
+ @api.model_create_multi
+ def create(self, vals_list):
+ order_lines = super().create(vals_list)
+ for line in order_lines:
+ if (
+ line.product_id.require_deposite
+ and not line.is_deposit_line
+ ):
+ deposit_product_param = (self.env["ir.config_parameter"].sudo().get_param("rental_deposit.deposit_product_id"))
+ if not deposit_product_param:
+ continue
+ deposit_product_id = int(
+ deposit_product_param
+ )
+ deposit_amount = line.product_id.amount
+ self.create({
+ "order_id": line.order_id.id,
+ "product_id": deposit_product_id,
+ "product_uom_qty": line.product_uom_qty,
+ "price_unit": deposit_amount,
+ "name": f"Deposit for {line.product_id.name}",
+ "is_deposit_line": True,
+ "deposit_origin_line_id": line.id,
+ })
+ return order_lines
+
+ def write(self, vals):
+ res = super().write(vals)
+
+ deposit_lines = self.env[
+ "sale.order.line"
+ ].search([("deposit_origin_line_id", "in", self.ids)])
+
+ for line in self:
+ if line.is_deposit_line:
+ continue
+
+ deposit_line = deposit_lines.filtered(lambda l: l.deposit_origin_line_id == line)
+ if not deposit_line:
+ continue
+ deposit_line.write({
+ "product_uom_qty":
+ line.product_uom_qty,
+ "price_unit":
+ line.product_id.amount,
+ "name":
+ f"Deposit for {line.product_id.name}",
+ })
+
+ return res
diff --git a/rental_deposit/static/src/js/deposit.js b/rental_deposit/static/src/js/deposit.js
new file mode 100644
index 00000000000..36bda5c2001
--- /dev/null
+++ b/rental_deposit/static/src/js/deposit.js
@@ -0,0 +1,18 @@
+document.addEventListener('change', function (ev) {
+ const input = ev.target;
+ if (!input.matches('.js_main_product input[name="add_qty"]')) {
+ return;
+ }
+ const productEl = input.closest('.js_product');
+ const depositEl = productEl?.querySelector('.o_deposit_wrapper');
+ if (!depositEl) {
+ return;
+ }
+ const depositUnit = parseFloat(depositEl.dataset.depositUnit) || 0;
+ const quantity = parseFloat(input.value) || 0;
+ const total = (depositUnit * quantity).toFixed(2);
+ const target = depositEl.querySelector('.o_deposit_amount_value');
+ if (target) {
+ target.textContent = total;
+ }
+});
diff --git a/rental_deposit/views/product_template_views.xml b/rental_deposit/views/product_template_views.xml
new file mode 100644
index 00000000000..f268731a762
--- /dev/null
+++ b/rental_deposit/views/product_template_views.xml
@@ -0,0 +1,16 @@
+
+
+
+
+ product.template.inherit.stock.rental
+ product.template
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
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..82dfdeff3d5
--- /dev/null
+++ b/rental_deposit/views/res_config_settings_views.xml
@@ -0,0 +1,19 @@
+
+
+
+
+ res.config.settings.view.form.inherit.rental
+ res.config.settings
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/rental_deposit/views/website_sale_template_views.xml b/rental_deposit/views/website_sale_template_views.xml
new file mode 100644
index 00000000000..af1ff995184
--- /dev/null
+++ b/rental_deposit/views/website_sale_template_views.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+ Deposit :
+
+
+
+
+
+
+