diff --git a/rental/__init__.py b/rental/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/rental/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/rental/__manifest__.py b/rental/__manifest__.py new file mode 100644 index 00000000000..031035d7af3 --- /dev/null +++ b/rental/__manifest__.py @@ -0,0 +1,19 @@ +{ + 'name': 'Rental App', + 'category': '', + 'description': """This module is rental app module""", + 'depends': ['sale_renting', 'website_sale_renting'], + 'data': [ + "views/res_config_settings_views.xml", + "views/product_template_views.xml", + "views/templates.xml", + ], + 'assets': { + 'web.assets_frontend': [ + 'rental_deposit/static/src/js/rental_deposit.js', + ], + }, + 'application': True, + 'license': 'OEEL-1', + "sequence": 1, +} diff --git a/rental/models/__init__.py b/rental/models/__init__.py new file mode 100644 index 00000000000..8cceeeb6df9 --- /dev/null +++ b/rental/models/__init__.py @@ -0,0 +1,4 @@ +from . import res_config_settings +from . import res_company +from . import product_template +from . import sale_order_line diff --git a/rental/models/product_template.py b/rental/models/product_template.py new file mode 100644 index 00000000000..e40b03c8b7e --- /dev/null +++ b/rental/models/product_template.py @@ -0,0 +1,8 @@ +from odoo import fields, models + + +class ProductTemplate(models.Model): + _inherit = 'product.template' + + required_deposit = fields.Boolean(default=False) + amount_deposit = fields.Float(string="Deposit Amount") diff --git a/rental/models/res_company.py b/rental/models/res_company.py new file mode 100644 index 00000000000..0bd9263ed75 --- /dev/null +++ b/rental/models/res_company.py @@ -0,0 +1,8 @@ +from odoo import fields, models + + +class ResCompany(models.Model): + _inherit = "res.company" + + product_deposit = fields.Many2one('product.product', string="Product", + domain=[("rent_ok", "=", True)]) diff --git a/rental/models/res_config_settings.py b/rental/models/res_config_settings.py new file mode 100644 index 00000000000..c81326fbcce --- /dev/null +++ b/rental/models/res_config_settings.py @@ -0,0 +1,9 @@ +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = 'res.config.settings' + + product_deposit = fields.Many2one('product.product', string="Deposit", + related="company_id.product_deposit", + readonly=False, domain=[("rent_ok", "=", True)]) diff --git a/rental/models/sale_order_line.py b/rental/models/sale_order_line.py new file mode 100644 index 00000000000..ce55dd7dec2 --- /dev/null +++ b/rental/models/sale_order_line.py @@ -0,0 +1,46 @@ +from odoo import fields, models, api + + +class SaleOrderLine(models.Model): + _inherit = 'sale.order.line' + + is_deposit_line = fields.Boolean(default=False) + deposit_link_id = fields.Many2one("sale.order.line", ondelete="cascade") + + @api.model_create_multi + def create(self, vals_list): + lines = super().create(vals_list) + + deposit_product = self.env.company.product_deposit + deposit_lines = [] + for line in lines: + if (line.product_id == deposit_product) and line.product_id.product_tmpl_id.required_deposit: + deposit_price = line.product_id.product_tmpl_id.amount_deposit * line.product_uom_qty + deposit_lines.append({ + "is_deposit_line": True, + "order_id": line.order_id.id, + "product_id": deposit_product.id, + "name": f"Deposit for {line.product_id.name}", + "product_uom_qty": line.product_uom_qty, + "price_unit": deposit_price, + "deposit_link_id": line.id, + }) + if deposit_lines: + super().create(deposit_lines) + return lines + + def write(self, vals): + res = super().write(vals) + if "product_uom_qty" in vals: + for line in self: + if not line.is_deposit_line: + deposit_line = self.search([ + ("order_id", "=", line.order_id.id), + ("deposit_link_id", "=", line.id), + ]) + if deposit_line: + deposit_line.write({ + "product_uom_qty": vals["product_uom_qty"], + "price_unit": line.product_template_id.amount_deposit, + }) + return res diff --git a/rental/static/srs/js/rental_deposit.js b/rental/static/srs/js/rental_deposit.js new file mode 100644 index 00000000000..e0641ce980f --- /dev/null +++ b/rental/static/srs/js/rental_deposit.js @@ -0,0 +1,26 @@ +import publicWidget from "@web/legacy/js/public/public_widget"; + +publicWidget.registry.WebsiteSale.include({ + start: function () { + this._super.apply(this, arguments); + this.changeDepositAmount({ target: document.querySelector('input[name="add_qty"]') }); + }, + + _onChangeAddQuantity: function (ev) { + this._super.apply(this, arguments); + this.changeDepositAmount(ev); + }, + + changeDepositAmount: function(ev){ + const input = ev.target || document.querySelector('input[name="add_qty"]'); + if (!input) return; + const qty = parseFloat(input.value || 1); + const depositSpan = document.getElementById('product_amount_deposit'); + if (!depositSpan) return; + + const baseDeposit = parseFloat(depositSpan.dataset.baseAmount || 0); + const currencySymbol = depositSpan.dataset.currencySymbol || ''; + const totalDeposit = (baseDeposit * qty).toFixed(2); + depositSpan.textContent = `${currencySymbol} ${totalDeposit}`; + } +}); diff --git a/rental/views/product_template_views.xml b/rental/views/product_template_views.xml new file mode 100644 index 00000000000..e32cefae362 --- /dev/null +++ b/rental/views/product_template_views.xml @@ -0,0 +1,14 @@ + + + + product.template.form.view.rental.inherit + product.template + + + + + + + + + diff --git a/rental/views/res_config_settings_views.xml b/rental/views/res_config_settings_views.xml new file mode 100644 index 00000000000..ac8cb1a8440 --- /dev/null +++ b/rental/views/res_config_settings_views.xml @@ -0,0 +1,16 @@ + + + + res.config.settings.inherit.view.form + res.config.settings + + + + + + + + + + + diff --git a/rental/views/templates.xml b/rental/views/templates.xml new file mode 100644 index 00000000000..4f34bef1f39 --- /dev/null +++ b/rental/views/templates.xml @@ -0,0 +1,38 @@ + + + + + + + Deposit Required: + + + + + + + + + + + + + + #{'d-none' if line.is_deposit_line else 'js_delete_product'} + + + + + + This deposit is for + + + + + + +