Files
public/rsbu_fns_reporting/models/rsbu_upd_generation.py

133 lines
7.3 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.
"""Ручное формирование документа реализации (и УПД) из инвойса Odoo.
Пользователь оформляет и проводит инвойс (account.move, out_invoice) —
РСБУ-слой формирует проводку реализации с зачётом авансов (резолвер
shipment_upd). Документ реализации (rsbu.realization), из которого затем
выгружается/печатается УПД, создаётся НЕ автоматически, а по кнопке
«Создать документ реализации» на форме инвойса.
Документ реализации создаётся для ЛЮБОЙ отгрузки — облагаемой НДС и
«Без НДС». При наличии НДС хотя бы в одной строке он порождает подчинённый
отгрузочный счёт-фактуру (rsbu.invoice, тип «shipment»).
Жизненный цикл закрывающего документа отражает поле closing_document на
инвойсе:
not_done — закрывающий документ не сформирован;
issued — документ реализации оформлен, ждём подпись клиента;
signed — клиент подписал (проставляется вручную).
При создании документа реализации статус переходит в «issued». При
удалении/отмене реализации — возвращается в «not_done» (хук на
rsbu.realization). В «signed» статус переводит только человек. Исходная
РСБУ-проводка инвойса при формировании УПД не меняется: реализация и СФ —
документы-надстройки, собственных проводок отгрузки не создают (их уже
сформировал резолвер при проведении).
"""
from odoo import _, fields, models
from odoo.exceptions import UserError
class AccountMove(models.Model):
_inherit = 'account.move'
closing_document = fields.Selection(
selection=[
('not_done', 'Не сделан'),
('issued', 'Оформлен'),
('signed', 'Подписан'),
],
string='Закрывающий документ', default='not_done', copy=False,
tracking=True,
help='Состояние закрывающего документа (УПД) по реализации: '
'«Не сделан» — документ реализации не сформирован; '
'«Оформлен» — создан, ждём подпись клиента; «Подписан» — '
'клиент подписал (ставится вручную).')
# Связанный документ реализации РСБУ (источник УПД).
rsbu_realization_id = fields.Many2one(
'rsbu.realization', string='Документ реализации (УПД)', copy=False,
compute='_compute_rsbu_realization_id', store=False,
help='Документ реализации РСБУ-слоя, сформированный по этому инвойсу '
'для выгрузки/печати УПД.')
def _compute_rsbu_realization_id(self):
Realization = self.env['rsbu.realization'].sudo()
for move in self:
move.rsbu_realization_id = Realization.search([
('source_model', '=', 'account.move'),
('source_res_id', '=', move.id),
('state', '!=', 'cancelled'),
('company_id', '=', move.company_id.id),
], limit=1)
# ------------------------------------------------------------------
def _upd_can_create(self):
"""Можно ли сформировать документ реализации по этому инвойсу.
Документ реализации формируется по любой проведённой реализации
(out_invoice, с НДС и без), если он ещё не создан.
"""
self.ensure_one()
return bool(
self.move_type == 'out_invoice'
and self.state == 'posted'
and not self.rsbu_realization_id
)
def action_create_realization(self):
"""Сформировать документ реализации (и УПД) по инвойсу.
Всегда создаётся rsbu.realization; при наличии НДS хотя бы в одной
строке — дополнительно порождается подчинённый отгрузочный СФ.
"""
self.ensure_one()
if self.move_type != 'out_invoice':
raise UserError(_(
'Документ реализации формируется только по счёту покупателю '
'(реализация).'))
if self.state != 'posted':
raise UserError(_(
'Проведите инвойс перед формированием документа реализации.'))
if self.rsbu_realization_id:
raise UserError(_(
'По этому инвойсу уже сформирован документ реализации: %s.')
% self.rsbu_realization_id.name)
Realization = self.env['rsbu.realization'].sudo()
realization = Realization.create({
'partner_id': self.partner_id.id,
'company_id': self.company_id.id,
'date': self.invoice_date or self.date or fields.Date.today(),
'source_model': 'account.move',
'source_res_id': self.id,
'amount_untaxed': abs(self.amount_untaxed),
'amount_tax': abs(self.amount_tax),
'state': 'confirmed',
})
if realization._has_vat(self):
realization._create_shipment_invoice()
self.closing_document = 'issued'
# Связь rsbu_realization_id — non-stored computed; сбрасываем кэш,
# чтобы кнопки/статус сразу отразили созданную реализацию.
self.invalidate_recordset(['rsbu_realization_id'])
return self._upd_open_realization(realization)
def action_open_realization(self):
"""Открыть сформированный документ реализации (УПД)."""
self.ensure_one()
realization = self.rsbu_realization_id
if not realization:
raise UserError(_(
'По этому инвойсу документ реализации ещё не сформирован.'))
return self._upd_open_realization(realization)
def _upd_open_realization(self, realization):
return {
'type': 'ir.actions.act_window',
'name': _('Документ реализации (УПД)'),
'res_model': 'rsbu.realization',
'view_mode': 'form',
'res_id': realization.id,
'target': 'current',
}