-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FIX] Add a module to restrict salesperson to allow more discount tha…
…n allowed
- Loading branch information
Showing
6 changed files
with
268 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
from . import models | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
from . import sale_discount | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |