-
-
Notifications
You must be signed in to change notification settings - Fork 191
/
sale.py
133 lines (123 loc) · 4.85 KB
/
sale.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# Copyright 2016-2020 Tecnativa - Carlos Dauden
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import _, api, fields, models
from odoo.tools import float_round
class SaleOrder(models.Model):
_inherit = "sale.order"
def evaluate_risk_message(self, partner):
self.ensure_one()
risk_amount = self.currency_id._convert(
self.amount_total,
self.company_id.currency_id,
self.company_id,
self.date_order
and self.date_order.date()
or fields.Date.context_today(self),
round=False,
)
exception_msg = ""
if partner.risk_exception:
exception_msg = _("Financial risk exceeded.\n")
elif partner.risk_sale_order_limit and (
(partner.risk_sale_order + risk_amount) > partner.risk_sale_order_limit
):
exception_msg = _("This sale order exceeds the sales orders risk.\n")
elif partner.risk_sale_order_include and (
(partner.risk_total + risk_amount) > partner.credit_limit
):
exception_msg = _("This sale order exceeds the financial risk.\n")
return exception_msg
def action_confirm(self):
if not self.env.context.get("bypass_risk", False):
for order in self:
partner = order.partner_invoice_id.commercial_partner_id
exception_msg = order.evaluate_risk_message(partner)
if exception_msg:
return (
self.env["partner.risk.exceeded.wiz"]
.create(
{
"exception_msg": exception_msg,
"partner_id": partner.id,
"origin_reference": "%s,%s" % ("sale.order", order.id),
"continue_method": "action_confirm",
}
)
.action_show()
)
return super().action_confirm()
@api.model
def _get_risk_states(self):
risk_states = ["sale"]
ICP = self.env["ir.config_parameter"].sudo()
if ICP.get_param("sale_financial_risk.include_risk_sale_order_done"):
risk_states.append("done")
return risk_states
class SaleOrderLine(models.Model):
_inherit = "sale.order.line"
company_currency_id = fields.Many2one(
comodel_name="res.currency",
related="company_id.currency_id",
string="Company Currency",
readonly=True,
)
risk_amount = fields.Monetary(
string="Risk amount",
compute="_compute_risk_amount",
compute_sudo=True,
currency_field="company_currency_id",
store=True,
)
risk_partner_id = fields.Many2one(
related="order_id.partner_invoice_id.commercial_partner_id",
string="Commercial Entity",
store=True,
index=True,
)
@api.depends(
"state",
"price_reduce_taxinc",
"qty_delivered",
"product_uom_qty",
"qty_invoiced",
)
def _compute_risk_amount(self):
risk_states = self.env["sale.order"]._get_risk_states()
for line in self:
if line.state not in risk_states or line.display_type:
line.risk_amount = 0.0
continue
qty = line.product_uom_qty
if line.product_id.invoice_policy == "delivery":
qty = max(qty, line.qty_delivered)
risk_qty = float_round(
qty - line.qty_invoiced, precision_rounding=line.product_uom.rounding
)
# There is no risk if the line hasn't stock moves to deliver
# Added hasattr condition because fails in post-migration compute
if (
risk_qty
and line.qty_delivered_method == "stock_move"
and (hasattr(line, "move_ids"))
):
if not line.move_ids.filtered(
lambda move: move.state not in ("done", "cancel")
):
risk_qty = line.qty_to_invoice
if risk_qty == 0.0:
line.risk_amount = 0.0
continue
if line.product_uom_qty:
# This method has more precision that using price_reduce_taxinc
risk_amount = line.price_total * (risk_qty / line.product_uom_qty)
else:
risk_amount = line.price_reduce_taxinc * risk_qty
line.risk_amount = line.order_id.currency_id._convert(
risk_amount,
line.company_id.currency_id,
line.company_id,
line.order_id.date_order
and line.order_id.date_order.date()
or fields.Date.context_today(self),
round=False,
)