Files
public/ruodoo_sale_control/models/sale_order.py

112 lines
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from datetime import date
from odoo import api, fields, models
class SaleOrder(models.Model):
_inherit = 'sale.order'
price_alarm = fields.Boolean(
string='Цены требуют проверки',
compute='_compute_price_alarm', store=True,
)
type_validation = fields.Selection(
[
('balance', 'По балансу'),
('overdraft', 'По балансу + овердрафт'),
('normal', 'По подтверждению'),
],
string='Тип контроля отгрузки', default='normal',
)
state = fields.Selection(
selection_add=[('wait', 'Ожидание оплаты')],
ondelete={'wait': 'set default'},
)
@api.depends('partner_id', 'order_line', 'order_line.price_unit', 'state')
def _compute_price_alarm(self):
SaleLine = self.env['sale.order.line']
for order in self:
if order.state != 'draft':
order.price_alarm = False
continue
alarm = False
partner = order.partner_id.parent_id or order.partner_id
for line in order.order_line:
if not line.product_id:
continue
previous_prices = SaleLine.search([
('order_id.partner_id', '=', partner.id),
('order_id.state', '=', 'sale'),
('product_id', '=', line.product_id.id),
]).sorted(
key=lambda ln: ln.order_id.date_order or fields.Datetime.now(),
reverse=True,
).mapped('price_unit')
# Сравниваем только с последней отгрузкой этому клиенту.
if previous_prices and line.price_unit < previous_prices[0]:
alarm = True
order.price_alarm = alarm
def _get_shipment_credit(self):
"""Долг и лимит кредита партнёра (с учётом головного контрагента)."""
self.ensure_one()
partner = self.partner_id.parent_id or self.partner_id
return partner.credit, partner.credit_limit
def _is_shipment_allowed(self):
"""Проверка финансовых условий отгрузки по выбранному типу контроля."""
self.ensure_one()
# Расчёт долга ведём в контексте компании заказа (без мутации env).
order = self.with_company(self.company_id)
credit, credit_limit = order._get_shipment_credit()
if self.type_validation == 'normal':
return True
if self.type_validation == 'balance':
return credit * (-1) >= self.amount_total
if self.type_validation == 'overdraft':
return credit * (-1) + credit_limit >= self.amount_total
return False
def action_confirm(self):
confirmable = self.env['sale.order']
for order in self:
if order._is_shipment_allowed():
order._log_shipment_activity()
# Заказ в ожидании оплаты вернём в черновик, чтобы штатный
# action_confirm принял его к подтверждению.
if order.state == 'wait':
order.state = 'draft'
confirmable |= order
elif order.state != 'wait':
order.message_post(
body='Проверка фин. условий оставила заказ в ожидании оплаты.'
)
order.state = 'wait'
if confirmable:
return super(SaleOrder, confirmable).action_confirm()
return True
def _log_shipment_activity(self):
self.ensure_one()
activity_type = self.env.ref(
'ruodoo_sale_control.mail_activity_shipment_allowed',
raise_if_not_found=False,
)
if not activity_type:
return
self.env['mail.activity'].create({
'res_model_id': self.env.ref('sale.model_sale_order').id,
'res_id': self.id,
'user_id': self.user_id.id,
'activity_type_id': activity_type.id,
'date_deadline': date.today(),
})
@api.model
def validate_all(self):
"""Повторно проверить все заказы в ожидании оплаты (cron/действие)."""
for order in self.search([('state', '=', 'wait')]):
order.action_confirm()