[FIX] account: manage multi-company for accrual wizard
Before, it was possible to select lines from different companies and create a line from a yet different company. This is now forbidden. Also, add tests to ensure only the account is changed when creating an accrual entry. closes odoo/odoo#36751 Signed-off-by: Laurent Smet <smetl@users.noreply.github.com>
This commit is contained in:
@@ -1193,3 +1193,47 @@ class TestAccountMoveInInvoiceOnchanges(InvoiceTestCommon):
|
||||
'amount_total' : self.move_vals['amount_total'],
|
||||
'amount_untaxed' : self.move_vals['amount_untaxed'],
|
||||
})
|
||||
|
||||
def test_in_invoice_accrual(self):
|
||||
self.env.company.accrual_default_journal_id = self.company_data['default_journal_misc']
|
||||
self.env.company.expense_accrual_account_id = self.env['account.account'].create({
|
||||
'name': 'Accrual Expense Account',
|
||||
'code': '234567',
|
||||
'user_type_id': self.env.ref('account.data_account_type_expenses').id,
|
||||
'reconcile': True,
|
||||
})
|
||||
self.env.company.revenue_accrual_account_id = self.env['account.account'].create({
|
||||
'name': 'Accrual Revenue Account',
|
||||
'code': '765432',
|
||||
'user_type_id': self.env.ref('account.data_account_type_expenses').id,
|
||||
'reconcile': True,
|
||||
})
|
||||
|
||||
invoice_line = self.invoice.line_ids.filtered(lambda l: l.account_id == self.product_a.property_account_expense_id)
|
||||
self.env['account.accrual.accounting.wizard'].with_context(
|
||||
active_model='account.move.line',
|
||||
active_ids=invoice_line.ids
|
||||
).create({
|
||||
'date': '2016-01-01',
|
||||
'percentage': 60,
|
||||
}).amend_entries()
|
||||
|
||||
# Nothing changed except the account
|
||||
self.assertInvoiceValues(self.invoice, [
|
||||
{
|
||||
**self.product_line_vals_1,
|
||||
'account_id': self.env.company.expense_accrual_account_id.id,
|
||||
},
|
||||
self.product_line_vals_2,
|
||||
self.tax_line_vals_1,
|
||||
self.tax_line_vals_2,
|
||||
self.term_line_vals_1,
|
||||
], self.move_vals)
|
||||
|
||||
accrual_moves = self.env['account.move'].search([('journal_id', '=', self.env.company.accrual_default_journal_id.id)])
|
||||
accrual_other_date = accrual_moves.filtered(lambda m: m.date == fields.Date.to_date('2016-01-01'))
|
||||
accrual_same_date = accrual_moves.filtered(lambda m: m.date == invoice_line.date)
|
||||
|
||||
self.assertEqual(accrual_same_date.amount_total, 0.4 * invoice_line.balance)
|
||||
self.assertEqual(accrual_other_date.amount_total, 0.6 * invoice_line.balance)
|
||||
self.assertTrue(accrual_other_date.line_ids.full_reconcile_id)
|
||||
|
||||
@@ -1267,4 +1267,48 @@ class TestAccountMoveOutInvoiceOnchanges(InvoiceTestCommon):
|
||||
'amount_tax' : self.move_vals['amount_tax'],
|
||||
'amount_total' : self.move_vals['amount_total'],
|
||||
'amount_untaxed' : self.move_vals['amount_untaxed'],
|
||||
})
|
||||
})
|
||||
|
||||
def test_out_invoice_accrual(self):
|
||||
self.env.company.accrual_default_journal_id = self.company_data['default_journal_misc']
|
||||
self.env.company.expense_accrual_account_id = self.env['account.account'].create({
|
||||
'name': 'Accrual Expense Account',
|
||||
'code': '234567',
|
||||
'user_type_id': self.env.ref('account.data_account_type_expenses').id,
|
||||
'reconcile': True,
|
||||
})
|
||||
self.env.company.revenue_accrual_account_id = self.env['account.account'].create({
|
||||
'name': 'Accrual Revenue Account',
|
||||
'code': '765432',
|
||||
'user_type_id': self.env.ref('account.data_account_type_expenses').id,
|
||||
'reconcile': True,
|
||||
})
|
||||
|
||||
invoice_line = self.invoice.line_ids.filtered(lambda l: l.account_id == self.product_a.property_account_income_id)
|
||||
self.env['account.accrual.accounting.wizard'].with_context(
|
||||
active_model='account.move.line',
|
||||
active_ids=invoice_line.ids
|
||||
).create({
|
||||
'date': '2016-01-01',
|
||||
'percentage': 60,
|
||||
}).amend_entries()
|
||||
|
||||
# Nothing changed except the account
|
||||
self.assertInvoiceValues(self.invoice, [
|
||||
{
|
||||
**self.product_line_vals_1,
|
||||
'account_id': self.env.company.revenue_accrual_account_id.id,
|
||||
},
|
||||
self.product_line_vals_2,
|
||||
self.tax_line_vals_1,
|
||||
self.tax_line_vals_2,
|
||||
self.term_line_vals_1,
|
||||
], self.move_vals)
|
||||
|
||||
accrual_moves = self.env['account.move'].search([('journal_id', '=', self.env.company.accrual_default_journal_id.id)])
|
||||
accrual_other_date = accrual_moves.filtered(lambda m: m.date == fields.Date.to_date('2016-01-01'))
|
||||
accrual_same_date = accrual_moves.filtered(lambda m: m.date == invoice_line.date)
|
||||
|
||||
self.assertEqual(accrual_same_date.amount_total, 0.4 * -invoice_line.balance)
|
||||
self.assertEqual(accrual_other_date.amount_total, 0.6 * -invoice_line.balance)
|
||||
self.assertTrue(accrual_other_date.line_ids.full_reconcile_id)
|
||||
|
||||
@@ -8,7 +8,7 @@ class AccrualAccountingWizard(models.TransientModel):
|
||||
_description = 'Create accrual entry.'
|
||||
|
||||
date = fields.Date(required=True)
|
||||
company_id = fields.Many2one('res.company', required=True, default=lambda self: self.env.company)
|
||||
company_id = fields.Many2one('res.company', required=True)
|
||||
account_type = fields.Selection([('income', 'Revenue'), ('expense', 'Expense')])
|
||||
active_move_line_ids = fields.Many2many('account.move.line')
|
||||
journal_id = fields.Many2one('account.journal', required=True, related="company_id.accrual_default_journal_id", readonly=False)
|
||||
@@ -41,6 +41,9 @@ class AccrualAccountingWizard(models.TransientModel):
|
||||
raise UserError(_('You can only change the period for items that are not yet reconciled.'))
|
||||
if any(line.account_id.user_type_id != active_move_line_ids[0].account_id.user_type_id for line in active_move_line_ids):
|
||||
raise UserError(_('All accounts on the lines must be from the same type.'))
|
||||
if any(line.company_id != active_move_line_ids[0].company_id for line in active_move_line_ids):
|
||||
raise UserError(_('All lines must be from the same company.'))
|
||||
rec['company_id'] = active_move_line_ids[0].company_id.id
|
||||
account_types_allowed = self.env.ref('account.data_account_type_expenses') + self.env.ref('account.data_account_type_revenue') + self.env.ref('account.data_account_type_other_income')
|
||||
if active_move_line_ids[0].account_id.user_type_id not in account_types_allowed:
|
||||
raise UserError(_('You can only change the period for items in these types of accounts: ') + ", ".join(account_types_allowed.mapped('name')))
|
||||
@@ -48,19 +51,15 @@ class AccrualAccountingWizard(models.TransientModel):
|
||||
return rec
|
||||
|
||||
def amend_entries(self):
|
||||
move_data = []
|
||||
to_reconcile = []
|
||||
message_data = []
|
||||
|
||||
#gather the origin account on seleced journal items
|
||||
# gather the origin account on seleced journal items
|
||||
origin_accounts = {}
|
||||
for aml in self.active_move_line_ids:
|
||||
origin_accounts[aml.id] = aml.account_id.id
|
||||
|
||||
#set the accrual account on the selected journal items
|
||||
# set the accrual account on the selected journal items
|
||||
self.active_move_line_ids.write({'account_id': (self.revenue_accrual_account if self.account_type == 'income' else self.expense_accrual_account).id})
|
||||
|
||||
#create the accrual move(s) and reconcile accrual items together
|
||||
# create the accrual move(s) and reconcile accrual items together
|
||||
for aml in self.active_move_line_ids:
|
||||
reported_debit = aml.company_id.currency_id.round((self.percentage / 100) * aml.debit)
|
||||
reported_credit = aml.company_id.currency_id.round((self.percentage / 100) * aml.credit)
|
||||
@@ -91,7 +90,7 @@ class AccrualAccountingWizard(models.TransientModel):
|
||||
id=aml.move_id.id,
|
||||
name=aml.move_id.name,
|
||||
)]
|
||||
#in case the percentage to recognize is not 100%, another entry is created to keep the remaining balance in the same account at the original date
|
||||
# in case the percentage to recognize is not 100%, another entry is created to keep the remaining balance in the same account at the original date
|
||||
if self.percentage < 100:
|
||||
ref = _('Accrual Adjusting Entry ({percent}% recognized) for invoice: {name}').format(percent=100 - self.percentage, name=aml.move_id.name)
|
||||
move_data.append({
|
||||
@@ -126,11 +125,11 @@ class AccrualAccountingWizard(models.TransientModel):
|
||||
for move, msg in zip(created_ids, message_data):
|
||||
move.message_post(body=msg)
|
||||
|
||||
#reconcile journal items on the accrual account
|
||||
# reconcile journal items on the accrual account
|
||||
to_reconcile = created_ids.line_ids.filtered(lambda line: line.account_id in (self.revenue_accrual_account + self.expense_accrual_account)) + aml
|
||||
to_reconcile.reconcile()
|
||||
|
||||
#open the generated entries
|
||||
# open the generated entries
|
||||
action = {
|
||||
'name': _('Generated Entries'),
|
||||
'domain': [('id', 'in', created_ids.ids)],
|
||||
|
||||
Reference in New Issue
Block a user