Skip to content

Commit

Permalink
[FIX] Add a module to restrict salesperson to allow more discount tha…
Browse files Browse the repository at this point in the history
…n allowed
  • Loading branch information
hip-odoo committed Jun 23, 2021
1 parent c2b1ea0 commit 0199030
Show file tree
Hide file tree
Showing 6 changed files with 268 additions and 0 deletions.
4 changes: 4 additions & 0 deletions fiber_sale_discount/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-

from . import models

22 changes: 22 additions & 0 deletions fiber_sale_discount/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
{
'name': "Quotations/Sales Orders Discount Approval",
'summary': """
Sales Discount Control
""",
'description': """
Sales Discount Control
""",
'author': "Odoo S.A.",
'website': "http://www.odoo.com",
'category': 'Customization',
'version': '0.1',
'depends': ['sale'],
'data': [
'views/sale_views.xml',
'data/mail_data.xml',
],
'installable': True,
'application': False,
'auto_install': False
}
73 changes: 73 additions & 0 deletions fiber_sale_discount/data/mail_data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<data noupdate="1">

<record id="email_template_sale_discount_approval" model="mail.template">
<field name="name">Sales Order: Discount Approval</field>
<field name="model_id" ref="sale.model_sale_order"/>
<field name="subject">Discount approval for Sale Order (Ref ${object.name or 'n/a' })</field>
<field name="email_from">${(object.user_id.email_formatted or user.email_formatted) | safe}</field>
<field name="partner_to">${object.user_id.id}</field>
<field name="body_html" type="html">
<div style="margin:0px;padding: 0px;">
<p style="padding:0px;font-size: 13px;">
Hello,
<br/><br/>
Salesperson has given more discount to the customer on the products than the discount he/she can allow.
<br/><br/>
The discount he/she can allow is <strong>${object.user_id.discount_limit}</strong>.
<br/><br/>
</p>
</div>
</field>
<field name="lang">${object.partner_id.lang}</field>
<field name="auto_delete" eval="True"/>
</record>

<record id="email_template_sale_discount_approve" model="mail.template">
<field name="name">Sales Order: Discount Approved</field>
<field name="model_id" ref="sale.model_sale_order"/>
<field name="subject">Discount approved for Sale Order (Ref ${object.name or 'n/a' })</field>
<field name="email_from">${(object.user_id.email_formatted or user.email_formatted) | safe}</field>
<field name="partner_to">${object.user_id.id}</field>
<field name="body_html" type="html">
<div style="margin:0px;padding: 0px;">
<p style="padding:0px;font-size: 13px;">
Hello,
<br/><br/>
Responsible person has approved the higher discount to the customer on the products.
<br/><br/>
You can confirm the order.
<br/><br/>
</p>
</div>
</field>
<field name="lang">${object.partner_id.lang}</field>
<field name="auto_delete" eval="True"/>
</record>

<record id="email_template_sale_discount_reject" model="mail.template">
<field name="name">Sales Order: Discount Rejected</field>
<field name="model_id" ref="sale.model_sale_order"/>
<field name="subject">Discount rejected for Sale Order (Ref ${object.name or 'n/a' })</field>
<field name="email_from">${(object.user_id.email_formatted or user.email_formatted) | safe}</field>
<field name="partner_to">${object.user_id.id}</field>
<field name="body_html" type="html">
<div style="margin:0px;padding: 0px;">
<p style="padding:0px;font-size: 13px;">
Hello,
<br/><br/>
Responsible person has rejected the higher discount to the customer on the products.
<br/><br/>
You can either cancel the order or modify discount on the order.
<br/><br/>
</p>
</div>
</field>
<field name="lang">${object.partner_id.lang}</field>
<field name="auto_delete" eval="True"/>
</record>

</data>
</odoo>
4 changes: 4 additions & 0 deletions fiber_sale_discount/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-

from . import sale_discount

106 changes: 106 additions & 0 deletions fiber_sale_discount/models/sale_discount.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo import api, fields, models, _
from odoo.exceptions import ValidationError


class Users(models.Model):
_inherit = 'res.users'

discount_limit = fields.Float('Discount limit')
approver_ids = fields.Many2many('res.users', 'users_approver_rel', 'user_id1', 'user_id2', string='Approver')

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

confirm_so = fields.Boolean('Allow to confirm sale order', default=True, compute='_compute_confirm_so', store=True, readonly=True)
state = fields.Selection(selection_add=[('wait', 'Waiting for Approval'), ('approved', 'SO is Approved'), ('rejected', 'SO is Rejected')])

@api.depends('order_line.discount')
def _compute_confirm_so(self):
for order in self:
order.confirm_so = False if order.order_line.filtered(lambda o: o.discount > order.user_id.discount_limit) else True

def action_quotation_send(self):
if self.state == 'approved' or self.confirm_so == True:
return super(SaleOrder, self).action_quotation_send()
else:
if self.confirm_so == False:
if self.state in ('draft', 'sent'):
self.write({'state': 'wait'})
return

def action_confirm(self):
if self.state == 'approved' or self.confirm_so == True:
return super(SaleOrder, self).action_confirm()
else:
if self.confirm_so == False:
if self.state in ('draft', 'sent'):
self.write({'state': 'wait'})
return

def action_request_discout_email_send(self):
if self.confirm_so:
self.action_confirm()
else:
template = self.env.ref('fiber_sale_discount.email_template_sale_discount_approval', raise_if_not_found=False)
res = self.env['res.users'].search_read([('id', 'in', self.user_id.approver_ids.ids)], ['email'])
emails = set(r['email'] for r in res if r.get('email'))
email_values = {
'email_to': ','.join(emails)
}
if template and self.env.user.email and self.id:
template.with_context(is_reminder=True).send_mail(
self.id,
force_send=True,
raise_exception=False,
email_values=email_values,
notif_layout="mail.mail_notification_paynow")
return {'toast_message': _("A sample email has been sent to %s.") % self.env.user.email}

def action_authorize_discout_approve_email_send(self):
if (self.env.user in self.user_id.approver_ids):
template = self.env.ref('fiber_sale_discount.email_template_sale_discount_approve', raise_if_not_found=False)

if template and self.env.user.email and self.id:
template.with_context(is_reminder=True).send_mail(
self.id,
force_send=True,
raise_exception=False,
email_values={'email_to': self.env.user.email, 'recipient_ids': []},
notif_layout="mail.mail_notification_paynow")
self.write({'confirm_so': True, 'state': 'approved'})
return {'toast_message': _("A sample email has been sent to %s.") % self.env.user.email}
else:
raise ValidationError(_("You can't approve/reject the discount. Only approver has this rights."))

def action_authorize_discout_reject_email_send(self):
if (self.env.user in self.user_id.approver_ids):
template = self.env.ref('fiber_sale_discount.email_template_sale_discount_reject', raise_if_not_found=False)

if template and self.env.user.email and self.id:
template.with_context(is_reminder=True).send_mail(
self.id,
force_send=True,
raise_exception=False,
email_values={'email_to': self.env.user.email, 'recipient_ids': []},
notif_layout="mail.mail_notification_paynow")
self.write({'state': 'rejected'})
return {'toast_message': _("A sample email has been sent to %s.") % self.env.user.email}
else:
raise ValidationError(_("You can't approve/reject the discount. Only approver has this rights."))


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

@api.onchange('discount')
def _onchange_discount(self):
for line in self:
if line.discount > line.order_id.user_id.discount_limit:
warning = {
'title': 'Discount warning',
'message': 'The discount is higher than the allowed discount.',
}
return {'warning': warning}
59 changes: 59 additions & 0 deletions fiber_sale_discount/views/sale_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="fiber_view_res_users_form" model="ir.ui.view">
<field name="name">fiber.res.users.form</field>
<field name="model">res.users</field>
<field name="inherit_id" ref="base.view_users_form"/>
<field name="arch" type="xml">
<xpath expr="//form[1]/sheet[1]/div[not(@name)][2]/group[1]/field[@name='partner_id']" position="after">
<field name="discount_limit"/>
<field name="approver_ids" string="Approvers" widget="many2many_tags" domain="[('share','=',False)]"/>
</xpath>
</field>
</record>

<record id="fiber_view_order_form" model="ir.ui.view">
<field name="name">fiber.sale.order.form</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<xpath expr="//button[@name='action_confirm'][1]" position="replace">
<button name="action_confirm" id="action_confirm"
string="Confirm" class="btn-primary" type="object"
attrs="{'invisible': [('state', 'not in', ['sent', 'approved'])]}"/>
</xpath>
<xpath expr="//button[@name='action_quotation_send'][1]" position="replace">
<button name="action_quotation_send" string="Send by Email" type="object" states="draft,approved" class="btn-primary"/>
</xpath>

<xpath expr="//field[@name='sale_order_template_id']" position="after">
<field name="confirm_so" invisible="1" force_save="1"/>
</xpath>
<xpath expr="//button[@name='action_quotation_send']" position="after">
<button name="action_request_discout_email_send"
string="Request Authorization"
type="object"
class="btn-primary"
attrs="{'invisible': [('state', 'not in', ('wait', 'rejected'))]}"/>
<button name="action_authorize_discout_approve_email_send"
string="Approve Discount"
type="object"
class="btn-primary"
attrs="{'invisible': [('state', '!=', 'wait')]}"/>
<button name="action_authorize_discout_reject_email_send"
string="Reject Discount"
type="object"
class="btn-primary"
attrs="{'invisible': [('state', '!=', 'wait')]}"
/>
</xpath>
<xpath expr="//button[@name='action_cancel']" position="replace">
<button name="action_cancel" type="object" string="Cancel" attrs="{'invisible': ['|', ('state', 'not in', ['draft', 'wait', 'approved', 'rejected','sent','sale']), ('id', '=', False)]}"/>
</xpath>
<xpath expr="//button[@name='preview_sale_order']" position="attributes">
<attribute name="attrs">{'invisible': [('state', 'in', ['draft', 'wait', 'rejected', 'cancel'])]}</attribute>
</xpath>
</field>
</record>

</odoo>

0 comments on commit 0199030

Please sign in to comment.