Revert "#047268 (#5)"

This reverts commit 13a65d8beb.
This commit is contained in:
Bernat Brunet 2023-12-13 15:28:54 +01:00
parent b22c6adfcf
commit c1a4cca122
8 changed files with 114 additions and 197 deletions

View File

@ -5,14 +5,12 @@ from trytond.pool import Pool
from . import invoice
from . import commission
from . import payment
from . import move
def register():
Pool.register(
invoice.Invoice,
move.Move,
move.Line,
invoice.Move,
module='account_invoice_posted2draft', type_='model')
Pool.register(
payment.Invoice,

View File

@ -4,43 +4,27 @@
from trytond.pool import Pool, PoolMeta
from trytond.tools import grouped_slice
__all__ = ['Invoice']
class Invoice(metaclass=PoolMeta):
__name__ = 'account.invoice'
def get_allow_draft(self, name):
pool = Pool()
Commission = pool.get('commission')
result = super().get_allow_draft(name)
invoiced = Commission.search([
('origin.invoice', '=', self.id, 'account.invoice.line'),
('invoice_line', '!=', None),
])
if invoiced:
result = False
return result
@classmethod
def draft(cls, invoices):
pool = Pool()
Commission = pool.get('commission')
Commission = Pool().get('commission')
to_delete = []
for sub_invoices in grouped_slice(invoices):
ids = [i.id for i in sub_invoices]
to_delete = Commission.search([
commissions = Commission.search([
('origin.invoice', 'in', ids, 'account.invoice.line'),
('invoice_line', '=', None),
])
if to_delete:
to_delete_origin = Commission.search([
('origin.id', 'in',
[x.id for x in to_delete], 'commission'),
('invoice_line', '=', None),
if commissions:
commissions_origin = Commission.search([
('origin.id', 'in', [c.id for c in commissions], 'commission'),
])
if to_delete_origin:
to_delete += to_delete_origin
Commission.delete(to_delete)
if commissions_origin:
commissions += commissions_origin
Commission.delete(commissions)
return super(Invoice, cls).draft(invoices)

View File

@ -1,9 +1,8 @@
# This file is part account_invoice_posted2draft module for Tryton.
# The COPYRIGHT file at the top level of this repository contains
# the full copyright notices and license terms.
from trytond.pool import Pool, PoolMeta
from trytond.model import fields
from trytond.pyson import Eval
from trytond.pool import Pool, PoolMeta
from trytond.transaction import Transaction
from trytond.i18n import gettext
from trytond.exceptions import UserError
@ -12,35 +11,14 @@ from trytond.exceptions import UserError
class Invoice(metaclass=PoolMeta):
__name__ = 'account.invoice'
allow_draft = fields.Function(
fields.Boolean("Allow Draft Invoice"), 'get_allow_draft')
@classmethod
def __setup__(cls):
super(Invoice, cls).__setup__()
cls._check_modify_exclude.add('move')
cls._transitions |= set((('posted', 'draft'),))
cls._buttons['draft']['invisible'] = ~Eval('allow_draft', False)
cls._buttons['draft']['depends'] += tuple(['allow_draft'])
def get_allow_draft(self, name):
# when IN invoice is validate from scratch, the move is in 'draft'
# state, so in this case could be draft in a "normal" way
if (self.state == 'validated' and self.move
and self.move.state != 'draft'):
return False
elif self.state == 'cancelled' and self.number is not None:
return False
elif self.state in {'paid', 'draft'}:
return False
elif self.state == 'posted':
lines_to_pay = [l for l in self.lines_to_pay
if not l.reconciliation]
# Invoice already paid or partial paid, should not be possible
# to change state to draft.
if (not lines_to_pay
or self.amount_to_pay != self.total_amount):
return False
return True
cls._buttons['draft']['invisible'] = (
Eval('state').in_(['draft', 'paid']) | (
(Eval('state') == 'cancelled') & Eval('cancel_move')))
@classmethod
def draft(cls, invoices):
@ -48,54 +26,64 @@ class Invoice(metaclass=PoolMeta):
Move = pool.get('account.move')
MoveLine = pool.get('account.move.line')
JournalPeriod = pool.get('account.journal.period')
Warning = pool.get('res.user.warning')
moves = []
move_lines = []
to_draft = []
to_save = []
payment_lines = []
for invoice in invoices:
if not invoice.allow_draft:
continue
if invoice.move:
# check period is closed
if invoice.move.period.state == 'close':
raise UserError(gettext(
'account_invoice_posted2draft.msg_draft_closed_period',
invoice=invoice.rec_name,
period=invoice.move.period.rec_name,
))
# check period and journal is closed
journal_periods = JournalPeriod.search([
('journal', '=', invoice.move.journal.id),
('period', '=', invoice.move.period.id),
], limit=1)
if journal_periods:
journal_period, = journal_periods
if journal_period.state == 'close':
raise UserError(gettext(
'account_invoice_posted2draft.'
'msg_modify_closed_journal_period',
invoice=invoice.rec_name,
journal_period=journal_period.rec_name))
moves.append(invoice.move)
if invoice.payment_lines:
for payment_line in invoice.payment_lines:
if payment_line.move and payment_line.move.lines:
for lines in payment_line.move.lines:
payment_lines.append(lines)
move = invoice.move
if move:
if move.state == 'draft':
to_draft.append(invoice)
else:
to_save.append(invoice)
cancel_move = move.cancel()
Move.post([cancel_move])
moves.extend((invoice.move, cancel_move))
invoice.move = None
else:
to_draft.append(invoice)
if invoice.cancel_move:
moves.append(invoice.cancel_move)
invoice.cancel_move = None
invoice.additional_moves += tuple(moves)
if moves:
with Transaction().set_context(draft_invoices=True):
Move.write(moves, {'state': 'draft'})
# If the payment lines dont have a reconciliation, then the field
# invoice_payment will be fill up, and when we try to draft an
# invoice it will give us an error
if payment_lines:
MoveLine.write(payment_lines, {'invoice_payment':None})
cls.write(invoices, {
'invoice_report_format': None,
'invoice_report_cache': None,
})
with Transaction().set_context(draft_invoices=True):
return super(Invoice, cls).draft(invoices)
# Only make the special steps for the invoices that came from 'posted'
# state or 'validated', 'cancelled' with number, so the invoice have one
# or more move associated.
# The other possible invoices follow the standard workflow.
if to_draft:
super().draft(to_draft)
if to_save:
cls.save(to_save)
with Transaction().set_context(invoice_posted2draft=True):
super().draft(to_save)
@classmethod
def credit(cls, invoices, refund=False, **values):
with Transaction().set_context(cancel_from_credit=True):
return super().credit(invoices, refund, **values)
for invoice in to_save:
to_reconcile = []
for move in invoice.additional_moves:
for line in move.lines:
if (not line.reconciliation
and line.account == invoice.account):
to_reconcile.append(line)
if to_reconcile:
MoveLine.reconcile(to_reconcile)
# Remove links to lines which actually do not pay the invoice
if to_save:
cls._clean_payments(to_save)
class Move(metaclass=PoolMeta):
__name__ = 'account.move'
@classmethod
def check_modify(cls, *args, **kwargs):
if Transaction().context.get('draft_invoices', False):
return
return super(Move, cls).check_modify(*args, **kwargs)

View File

@ -2,26 +2,22 @@
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,allow_draft:"
msgid "Allow Draft Invoice"
msgstr "Permet factura esborrany"
msgctxt "model:ir.message,text:msg_cancel_invoice_with_number"
msgid "You cannot cancel invoice \"%(invoice)s\" because it already has a number."
msgstr "No podeu cancel·lar la factura \"%(invoice)s\" amb un número assignat."
msgctxt "model:ir.message,text:msg_draft_closed_period"
msgid ""
"You cannot create an account compesantion move in the period %(period)s "
"because is closed."
"You can not set to draft invoice \"%(invoice)s\" because period "
"\"%(period)s\" is closed."
msgstr ""
"No podeu crear un assentamet de compensació en el període %(period)s perquè "
"està tancat."
"No es pot passar a esborrany la factura \"%(invoice)s\" perquè el període "
"\"%(period)s\" està tancat."
msgctxt "model:ir.message,text:msg_invoice_in_payment"
msgctxt "model:ir.message,text:msg_modify_closed_journal_period"
msgid ""
"The invoice %(invoice)s could not be possible to draft, becasue it have one "
"or more move lines in payments [IDs: %(payments)s]. This means that is "
"possible that this payment will be in a payment group and this group upload "
"on a Bank."
"You can not set to draft invoice \"%(invoice)s\" on closed journal-period "
"\"%(journal_period)s\"."
msgstr ""
"La factura %(invoice)s no es pot passar a esborrany, perquè té un o més "
"apunts relacionats a pagaments [ID: %(payments)s]. Això vol dir que és "
"possible que aquest pagament estigui en una remesa bancària i aquesta estigui "
"pujada ja al Banc."
"No es pot passar a esborrany la factura \"%(invoice)s\" perquè el diari-"
"període \"%(journal_period)s\". està tancat."

View File

@ -2,26 +2,22 @@
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,allow_draft:"
msgid "Allow Draft Invoice"
msgstr "Permitir factura borrador"
msgctxt "model:ir.message,text:msg_cancel_invoice_with_number"
msgid "You cannot cancel invoice \"%(invoice)s\" because it already has a number."
msgstr "No puede cancelar la factura \"%(invoice)s\" con un número asignado."
msgctxt "model:ir.message,text:msg_draft_closed_period"
msgid ""
"You cannot create an account compesantion move in the period %(period)s "
"because is closed."
"You can not set to draft invoice \"%(invoice)s\" because period "
"\"%(period)s\" is closed."
msgstr ""
"No puedes crear un asiento de compensación en el periodo %(period)s porque "
"está cerrado."
"No se puede pasar a borrador la factura \"%(invoice)s\" porqué el período "
"\"%(period)s\" está cerrado."
msgctxt "model:ir.message,text:msg_invoice_in_payment"
msgctxt "model:ir.message,text:msg_modify_closed_journal_period"
msgid ""
"The invoice %(invoice)s could not be possible to draft, becasue it have one "
"or more move lines in payments [IDs: %(payments)s]. This means that is "
"possible that this payment will be in a payment group and this group upload "
"on a Bank."
"You can not set to draft invoice \"%(invoice)s\" on closed journal-period "
"\"%(journal_period)s\"."
msgstr ""
"La factura %(invoice)s no se puede pasar a borrador, porque tiene uno o más "
"apuntes relacionados a pagos [ID: %(payments)s]. Esto quiere decir que és "
"posible que estos pagos esten ya en una remesa bancárea y ésta esté subida "
"al Banco."
"No se puede pasar a borrador la factura \"%(invoice)s\" porqué el diario-"
"período \"%(journal_period)s\" está cerrado."

View File

@ -4,10 +4,13 @@ this repository contains the full copyright notices and license terms. -->
<tryton>
<data grouped="1">
<record model="ir.message" id="msg_draft_closed_period">
<field name="text">You cannot create an account compesantion move in the period %(period)s because is closed.</field>
<field name="text">You can not set to draft invoice "%(invoice)s" because period "%(period)s" is closed.</field>
</record>
<record model="ir.message" id="msg_invoice_in_payment">
<field name="text">The invoice %(invoice)s could not be possible to draft, becasue it have one or more move lines in payments [IDs: %(payments)s]. This means that is possible that this payment will be in a payment group and this group upload on a Bank.</field>
<record model="ir.message" id="msg_cancel_invoice_with_number">
<field name="text">You cannot cancel invoice "%(invoice)s" because it already has a number.</field>
</record>
<record model="ir.message" id="msg_modify_closed_journal_period">
<field name="text">You can not set to draft invoice "%(invoice)s" on closed journal-period "%(journal_period)s".</field>
</record>
</data>
</tryton>

40
move.py
View File

@ -1,40 +0,0 @@
# This file is part account_invoice_posted2draft module for Tryton.
# The COPYRIGHT file at the top level of this repository contains
# the full copyright notices and license terms.
from trytond.pool import Pool, PoolMeta
from trytond.transaction import Transaction
class Move(metaclass=PoolMeta):
__name__ = 'account.move'
@classmethod
def check_modify(cls, *args, **kwargs):
# As now the moves related to an invoice are not delete when 'draft'
# the invoice, is needed to modify some restricted fields when the
# move is in post state
if Transaction().context.get('invoice_posted2draft', False):
return
return super().check_modify(*args, **kwargs)
@classmethod
def delete(cls, moves):
# When invoice is set to 'draft', try to delete the move's associated
# in 'move' and 'additional_move' fields. If these moves are posted
# they cannot be deleted but keep them as history
if Transaction().context.get('invoice_posted2draft', False):
return
super().delete(moves)
class Line(metaclass=PoolMeta):
__name__ = 'account.move.line'
@classmethod
def check_modify(cls, lines, modified_fields=None):
# As now the moves related to an invoice are not delete when 'draft'
# the invoice, is needed to modify some restricted fields when the
# move is in post state
if Transaction().context.get('invoice_posted2draft', False):
return
return super().check_modify(lines, modified_fields)

View File

@ -2,8 +2,8 @@
# The COPYRIGHT file at the top level of this repository contains
# the full copyright notices and license terms.
from trytond.pool import Pool, PoolMeta
from trytond.i18n import gettext
from trytond.exceptions import UserError
__all__ = ['Invoice']
class Invoice(metaclass=PoolMeta):
@ -11,26 +11,18 @@ class Invoice(metaclass=PoolMeta):
@classmethod
def draft(cls, invoices):
pool = Pool()
Payment = pool.get('account.payment')
Payment = Pool().get('account.payment')
lines = []
for invoice in invoices:
moves = []
if invoice.move:
moves.append(invoice.move)
if invoice.additional_moves:
moves.extend(invoice.additional_moves)
lines.extend([l.id for l in invoice.move.lines])
if lines:
payments = Payment.search([
('line', 'in', lines),
('state', '=', 'failed'),
])
if payments:
Payment.write(payments, {'line': None})
if moves:
lines = [l.id for m in moves for l in m.lines]
if lines:
payments = Payment.search([
('line', 'in', lines),
('state', '!=', 'failed'),
])
if payments:
raise UserError(gettext('account_invoice_posted2draft'
'.msg_invoice_in_payment',
invoice=invoice.rec_name,
payments=", ".join([p.id for p in payments])))
return super().draft(invoices)
return super(Invoice, cls).draft(invoices)