Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added deposit for rental products #500

Draft
wants to merge 1 commit into
base: 18.0
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions deposit_renting/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
18 changes: 18 additions & 0 deletions deposit_renting/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
'name': "Deposit Rental Products",
'depends': ['sale_renting', 'website_sale'],
'application': False,
'installable': True,
'license': 'LGPL-3',
'data': [
'views/product_template_views.xml',
'views/res_config_settings_views.xml',
'views/templates.xml',
'views/sale_order_view.xml',
],
'assets': {
'web.assets_frontend': [
'deposit_renting/static/src/js/product_deposit.js',
],
}
}
4 changes: 4 additions & 0 deletions deposit_renting/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from . import product_template
from . import res_config_settings
from . import sale_order
from . import sale_order_line
8 changes: 8 additions & 0 deletions deposit_renting/models/product_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from odoo import fields, models


class ProductTemplate(models.Model):
_inherit = "product.template"

require_deposit = fields.Boolean(string='Require Deposit')
deposit_amount = fields.Float(string='Deposit Amount', help="Deposit amount for single unit.")
17 changes: 17 additions & 0 deletions deposit_renting/models/res_config_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from odoo import fields, models


class ResConfigSettings(models.TransientModel):
_inherit = "res.config.settings"

deposit_product_id = fields.Many2one("product.product", string="Deposit Product", help="Product to be used for deposit on sale order.")

def set_values(self):
super().set_values()
self.env['ir.config_parameter'].sudo().set_param('deposit_product_id', self.deposit_product_id.id)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is sudo used?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By using sudo(), it gets the access rights to superuser level, temporarily bypassing regular access rules, sometimes it is possible to not have the access right to admin of configuration settings. I have seen it in codebase too.


def get_values(self):
res = super().get_values()
product_id = int(self.env['ir.config_parameter'].sudo().get_param('deposit_product_id', default=False))
res['deposit_product_id'] = self.env['product.product'].browse(product_id)
return res
17 changes: 17 additions & 0 deletions deposit_renting/models/sale_order.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from odoo import api, fields, models


class SaleOrder(models.Model):
_inherit = "sale.order"

require_deposit_config = fields.Boolean(string="Require Deposit Configuration", default=False, compute="_compute_has_deposit_line_without_config", help="Has line that require deposit, without configuring the deposit product in settings.")

@api.depends('order_line')
def _compute_has_deposit_line_without_config(self):
deposit_product_id = self.env['ir.config_parameter'].get_param('deposit_product_id')
for sale_order in self:
has_line_require_deposit_config = True if len(sale_order.order_line.filtered(lambda line: line.product_id.require_deposit)) > 0 else False
if has_line_require_deposit_config and not deposit_product_id:
sale_order.require_deposit_config = True
else:
sale_order.require_deposit_config = False
45 changes: 45 additions & 0 deletions deposit_renting/models/sale_order_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from odoo import api, fields, models


class SaleOrderLine(models.Model):
_inherit = "sale.order.line"

is_deposit_line = fields.Boolean(string="Is Deposit Line", default=False)

def _add_deposit_line(self):
deposit_product_id = int(self.env['ir.config_parameter'].get_param('deposit_product_id'))
deposit_product = self.env['product.product'].browse(deposit_product_id)
for line in self:
if line.order_id and line.product_id.rent_ok and line.product_id.require_deposit:
deposit_line = line.order_id.order_line.filtered(lambda line: line.linked_line_id == self.id)
if deposit_line:
deposit_line.product_uom_qty = line.product_uom_qty
deposit_line.price_unit = line.product_id.deposit_amount
else:
self.env["sale.order.line"].create({
'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': line.product_id.deposit_amount,
'linked_line_id': line.id,
'price_subtotal': line.product_uom_qty * line.product_id.deposit_amount,
'is_deposit_line': True,
})

@api.model_create_multi
def create(self, vals_list):
res = super().create(vals_list)
res._add_deposit_line()
return res

def write(self, vals):
res = super().write(vals)
if 'product_uom_qty' in vals:
for line in self:
linked_lines = self.search([('linked_line_id', '=', line.id)])
for linked_line in linked_lines:
linked_line.product_uom_qty = line.product_uom_qty
linked_line.price_subtotal = line.product_uom_qty * line.product_id.deposit_amount

return res
20 changes: 20 additions & 0 deletions deposit_renting/static/src/js/product_deposit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import publicWidget from "@web/legacy/js/public/public_widget";

publicWidget.registry.WebsiteSale.include({
_onChangeAddQuantity: function (ev) {
this._super.apply(this, arguments);
this.changeDepositAmount(ev);
},

changeDepositAmount: function(ev){
const input = ev.target;
const qty = parseFloat(input.value || 1);
const depositSpan = document.getElementById('product_deposit_amount');
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}`;
}
})
13 changes: 13 additions & 0 deletions deposit_renting/views/product_template_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<odoo>
<record id="product_template_form_view_deposit_renting" model="ir.ui.view">
<field name="name">product.template.deposit.renting.form</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="sale_renting.product_template_form_view_rental" />
<field name="arch" type="xml">
<group name="extra_rental" position="inside">
<field name="require_deposit" />
<field name="deposit_amount" invisible="not require_deposit" />
</group>
</field>
</record>
</odoo>
15 changes: 15 additions & 0 deletions deposit_renting/views/res_config_settings_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<odoo>
<record id="res_config_settings_view_form_deposit_renting" model="ir.ui.view">
<field name="name">res.config.settings.deposit.renting.form</field>
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="sale_renting.res_config_settings_view_form" />
<field name="arch" type="xml">
<xpath expr="//setting[@name='rental_delay_costs']" position="after">
<setting string="Deposit Product" help="Product to be used for deposit on sale order">
<label string="Deposit" for="deposit_product_id" class="o_light_label me-3" />
<field name="deposit_product_id" />
</setting>
</xpath>
</field>
</record>
</odoo>
14 changes: 14 additions & 0 deletions deposit_renting/views/sale_order_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<odoo>
<record id="view_order_form_inherited" model="ir.ui.view">
<field name="name">sale.order.view.order.form.inherited</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<xpath expr="//form/header" position="before">
<div class="alert alert-warning" role="alert" invisible="not require_deposit_config">
<span>Deposit product is not configured in setting.</span>
</div>
</xpath>
</field>
</record>
</odoo>
26 changes: 26 additions & 0 deletions deposit_renting/views/templates.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<odoo>
<template id="ecom_extra_deposit_field" inherit_id="website_sale.product">
<xpath expr="//div[@id='o_wsale_cta_wrapper']" position="after">
<t t-if="product.require_deposit">
<div class="mt-3 d-flex justify-content-between" id="product_deposit_section">
<strong>Deposit Required:</strong>
<span id="product_deposit_amount"
t-att-data-base-amount="product.deposit_amount"
t-att-data-currency-symbol="website.company_id.currency_id.symbol">
<t t-out="website.company_id.currency_id.symbol" />
<t t-out="product.deposit_amount" />
</span>
</div>
</t>
</xpath>
</template>

<template id="cart_line_readonly_quantity" inherit_id="website_sale.cart_lines" name="Readonly Quantity in Cart">
<xpath expr="//div[@name='website_sale_cart_line_quantity']" position="before">
<t t-set="show_qty" t-value="not line.is_deposit_line" />
</xpath>
<xpath expr="//div[@name='o_wsale_cart_line_button_container']/a[hasclass('js_delete_product')]" position="attributes">
<attribute name="t-attf-class">#{'d-none' if line.is_deposit_line else 'js_delete_product'}</attribute>
</xpath>
</template>
</odoo>