Public release from ruodoo-project: 19.0 - 2026-11-01 22:52:25 UTC

This commit is contained in:
CI Publish Bot
2026-11-01 22:54:30 +00:00
commit 26250aa580
2492 changed files with 664277 additions and 0 deletions

View File

@@ -0,0 +1,111 @@
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()