[IMP] account: clean entry/move reversal
Task 2085023 * Add a field that replaces the context to get the ids of the entries/invoices * Remove move_id, we can use move_ids instead * Add text to explain invioces/bills will create refunds closes odoo/odoo#38857 Related: odoo/enterprise#6263 Signed-off-by: Quentin De Paoli (qdp) <qdp@openerp.com>
This commit is contained in:
@@ -1626,7 +1626,7 @@ class TestReconciliationExec(TestAccountReconciliationCommon):
|
||||
|
||||
reverse_date = fields.Date.today() + timedelta(days=+7)
|
||||
revertWidget = self.env['account.move.reversal'].create({
|
||||
'move_id': purchase_move.id,
|
||||
'move_ids': [(6, 0, [purchase_move.id])],
|
||||
'date': reverse_date,
|
||||
'reason': ['cancel'],
|
||||
})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from odoo import models, fields, api
|
||||
from odoo.tools.translate import _
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class AccountMoveReversal(models.TransientModel):
|
||||
@@ -10,9 +11,8 @@ class AccountMoveReversal(models.TransientModel):
|
||||
_name = 'account.move.reversal'
|
||||
_description = 'Account Move Reversal'
|
||||
|
||||
move_id = fields.Many2one('account.move', string='Journal Entry',
|
||||
domain=[('state', '=', 'posted'), ('type', 'not in', ('out_refund', 'in_refund'))])
|
||||
new_move_ids = fields.Many2many('account.move')
|
||||
move_ids = fields.Many2many('account.move', 'account_move_reversal_move', 'reversal_id', 'move_id', domain=[('state', '=', 'posted')])
|
||||
new_move_ids = fields.Many2many('account.move', 'account_move_reversal_new_move', 'reversal_id', 'new_move_id')
|
||||
date = fields.Date(string='Reversal date', default=fields.Date.context_today, required=True)
|
||||
reason = fields.Char(string='Reason')
|
||||
refund_method = fields.Selection(selection=[
|
||||
@@ -32,22 +32,23 @@ class AccountMoveReversal(models.TransientModel):
|
||||
def default_get(self, fields):
|
||||
res = super(AccountMoveReversal, self).default_get(fields)
|
||||
move_ids = self.env['account.move'].browse(self.env.context['active_ids']) if self.env.context.get('active_model') == 'account.move' else self.env['account.move']
|
||||
if any(move.state != "posted" for move in move_ids):
|
||||
raise UserError(_('You can only reverse posted moves.'))
|
||||
res['move_ids'] = [(6, 0, move_ids.ids)]
|
||||
res['refund_method'] = (len(move_ids) > 1 or move_ids.type == 'entry') and 'cancel' or 'refund'
|
||||
res['residual'] = len(move_ids) == 1 and move_ids.amount_residual or 0
|
||||
res['currency_id'] = len(move_ids.currency_id) == 1 and move_ids.currency_id.id or False
|
||||
res['move_type'] = len(move_ids) == 1 and move_ids.type or False
|
||||
return res
|
||||
|
||||
@api.depends('move_id')
|
||||
@api.depends('move_ids')
|
||||
def _compute_from_moves(self):
|
||||
move_ids = self.env['account.move'].browse(self.env.context['active_ids']) if self.env.context.get('active_model') == 'account.move' else self.move_id
|
||||
for record in self:
|
||||
move_ids = record.move_ids
|
||||
record.residual = len(move_ids) == 1 and move_ids.amount_residual or 0
|
||||
record.currency_id = len(move_ids.currency_id) == 1 and move_ids.currency_id or False
|
||||
record.move_type = len(move_ids) == 1 and move_ids.type or False
|
||||
record.move_type = move_ids.type if len(move_ids) == 1 else (any(move.type in ('in_invoice', 'out_invoice') for move in move_ids) and 'some_invoice' or False)
|
||||
|
||||
def reverse_moves(self):
|
||||
moves = self.env['account.move'].browse(self.env.context['active_ids']) if self.env.context.get('active_model') == 'account.move' else self.move_id
|
||||
self.ensure_one()
|
||||
moves = self.move_ids
|
||||
|
||||
# Create default values.
|
||||
default_values_list = []
|
||||
|
||||
@@ -7,12 +7,14 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Reverse Journal Entry">
|
||||
<field name="residual" invisible="1"/>
|
||||
<field name="move_ids" invisible="1"/>
|
||||
<field name="move_type" invisible="1"/>
|
||||
<span class="text-muted" attrs="{'invisible': [('move_type', 'not in', ('out_invoice', 'in_invoice', 'some_invoice'))]}">Invoices/>Bills won't be reversed but credit notes will be created instead: the tax tags will be adapted accordingly.</span>
|
||||
<group>
|
||||
<group attrs="{'invisible': [('move_type', 'not in', ('out_invoice', 'in_invoice'))]}">
|
||||
<field name="refund_method" widget="radio" attrs="{'readonly': [('residual', '=', 0)]}"/>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('move_type', 'not in', ('out_invoice', 'in_invoice'))]}">
|
||||
<group attrs="{'invisible': [('move_type', 'not in', ('out_invoice', 'in_invoice', 'some_invoice'))]}">
|
||||
<div attrs="{'invisible':[('refund_method', '!=', 'refund')]}" class="oe_grey" colspan="4">
|
||||
The credit note is created in draft and can be edited before being issued.
|
||||
</div>
|
||||
|
||||
@@ -8,8 +8,7 @@ class AccountMoveReversal(models.TransientModel):
|
||||
|
||||
_inherit = "account.move.reversal"
|
||||
|
||||
l10n_latam_use_documents = fields.Boolean(
|
||||
related='move_id.journal_id.l10n_latam_use_documents', readonly=True)
|
||||
l10n_latam_use_documents = fields.Boolean(readonly=True)
|
||||
l10n_latam_document_type_id = fields.Many2one('l10n_latam.document.type', 'Document Type', ondelete='cascade')
|
||||
l10n_latam_sequence_id = fields.Many2one('ir.sequence', compute='_compute_l10n_latam_sequence')
|
||||
l10n_latam_document_number = fields.Char(string='Document Number')
|
||||
@@ -22,6 +21,8 @@ class AccountMoveReversal(models.TransientModel):
|
||||
move_ids_use_document = move_ids.filtered(lambda move: move.l10n_latam_use_documents)
|
||||
if move_ids_use_document:
|
||||
raise UserError(_('You can only reverse documents with legal invoicing documents from Latin America one at a time.\nProblematic documents: %s') % ", ".join(move_ids_use_document.mapped('name')))
|
||||
else:
|
||||
res['l10n_latam_use_documents'] = move_ids.journal_id.l10n_latam_use_documents
|
||||
|
||||
return res
|
||||
|
||||
@@ -36,14 +37,14 @@ class AccountMoveReversal(models.TransientModel):
|
||||
'in_receipt': 'out_receipt'}
|
||||
return match.get(move_type)
|
||||
|
||||
@api.onchange('move_id')
|
||||
@api.onchange('move_ids')
|
||||
def _onchange_move_id(self):
|
||||
if self.move_id.l10n_latam_use_documents:
|
||||
refund = self.move_id.new({
|
||||
'type': self._reverse_type_map(self.move_id.type),
|
||||
'journal_id': self.move_id.journal_id.id,
|
||||
'partner_id': self.move_id.partner_id.id,
|
||||
'company_id': self.move_id.company_id.id,
|
||||
if self.l10n_latam_use_documents:
|
||||
refund = self.env['account.move'].new({
|
||||
'type': self._reverse_type_map(self.move_ids.type),
|
||||
'journal_id': self.move_ids.journal_id.id,
|
||||
'partner_id': self.move_ids.partner_id.id,
|
||||
'company_id': self.move_ids.company_id.id,
|
||||
})
|
||||
self.l10n_latam_document_type_id = refund.l10n_latam_document_type_id
|
||||
return {'domain': {
|
||||
@@ -57,14 +58,16 @@ class AccountMoveReversal(models.TransientModel):
|
||||
@api.depends('l10n_latam_document_type_id')
|
||||
def _compute_l10n_latam_sequence(self):
|
||||
for rec in self:
|
||||
refund = rec.move_id.new({
|
||||
'type': self._reverse_type_map(rec.move_id.type),
|
||||
'journal_id': rec.move_id.journal_id.id,
|
||||
'partner_id': rec.move_id.partner_id.id,
|
||||
'company_id': rec.move_id.company_id.id,
|
||||
'l10n_latam_document_type_id': rec.l10n_latam_document_type_id.id,
|
||||
})
|
||||
rec.l10n_latam_sequence_id = refund._get_document_type_sequence()
|
||||
rec.l10n_latam_sequence_id = False
|
||||
if len(rec.move_ids) <= 1:
|
||||
refund = rec.env['account.move'].new({
|
||||
'type': self._reverse_type_map(rec.move_ids.type),
|
||||
'journal_id': rec.move_ids.journal_id.id,
|
||||
'partner_id': rec.move_ids.partner_id.id,
|
||||
'company_id': rec.move_ids.company_id.id,
|
||||
'l10n_latam_document_type_id': rec.l10n_latam_document_type_id.id,
|
||||
})
|
||||
rec.l10n_latam_sequence_id = refund._get_document_type_sequence()
|
||||
|
||||
@api.onchange('l10n_latam_document_number', 'l10n_latam_document_type_id')
|
||||
def _onchange_l10n_latam_document_number(self):
|
||||
|
||||
Reference in New Issue
Block a user