1012 lines
60 KiB
Python
1012 lines
60 KiB
Python
# pylint: disable=C0326
|
|
from .common import TestAccountReportsCommon
|
|
|
|
from odoo import Command, fields
|
|
from odoo.tests import tagged
|
|
|
|
import json
|
|
|
|
|
|
@tagged('post_install', '-at_install')
|
|
class TestPartnerLedgerReport(TestAccountReportsCommon):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
|
|
cls.partner_category_a = cls.env['res.partner.category'].create({'name': 'partner_categ_a'})
|
|
cls.partner_category_b = cls.env['res.partner.category'].create({'name': 'partner_categ_b'})
|
|
|
|
cls.partner_a.write({'category_id': [Command.set([cls.partner_category_a.id, cls.partner_category_b.id])]})
|
|
cls.partner_b.write({'category_id': [Command.set([cls.partner_category_a.id])]})
|
|
cls.partner_c = cls._create_partner(name='partner_c', category_id=[Command.set([cls.partner_category_b.id])])
|
|
|
|
# Entries in 2016 for company_1 to test the initial balance.
|
|
cls.move_2016_1 = cls.env['account.move'].create({
|
|
'move_type': 'entry',
|
|
'date': fields.Date.from_string('2016-01-01'),
|
|
'journal_id': cls.company_data['default_journal_misc'].id,
|
|
'line_ids': [
|
|
(0, 0, {'debit': 100.0, 'credit': 0.0, 'name': '2016_1_1', 'account_id': cls.company_data['default_account_payable'].id, 'partner_id': cls.partner_a.id}),
|
|
(0, 0, {'debit': 200.0, 'credit': 0.0, 'name': '2016_1_1', 'account_id': cls.company_data['default_account_payable'].id, 'partner_id': cls.partner_b.id}),
|
|
(0, 0, {'debit': 0.0, 'credit': 300.0, 'name': '2016_1_2', 'account_id': cls.company_data['default_account_receivable'].id, 'partner_id': cls.partner_c.id}),
|
|
],
|
|
})
|
|
cls.move_2016_1.action_post()
|
|
|
|
# Entries in 2016 for company_2 to test the initial balance in multi-companies/multi-currencies.
|
|
cls.move_2016_2 = cls.env['account.move'].create({
|
|
'move_type': 'entry',
|
|
'date': fields.Date.from_string('2016-06-01'),
|
|
'journal_id': cls.company_data_2['default_journal_misc'].id,
|
|
'line_ids': [
|
|
(0, 0, {'debit': 100.0, 'credit': 0.0, 'name': '2016_2_1', 'account_id': cls.company_data_2['default_account_payable'].id, 'partner_id': cls.partner_a.id}),
|
|
(0, 0, {'debit': 0.0, 'credit': 100.0, 'name': '2016_2_2', 'account_id': cls.company_data_2['default_account_receivable'].id, 'partner_id': cls.partner_c.id}),
|
|
],
|
|
})
|
|
cls.move_2016_2.action_post()
|
|
|
|
# Entry in 2017 for company_1 to test the report at current date.
|
|
cls.move_2017_1 = cls.env['account.move'].create({
|
|
'move_type': 'entry',
|
|
'date': fields.Date.from_string('2017-01-01'),
|
|
'journal_id': cls.company_data['default_journal_misc'].id,
|
|
'line_ids': [
|
|
(0, 0, {'debit': 1000.0, 'credit': 0.0, 'name': '2017_1_1', 'account_id': cls.company_data['default_account_payable'].id, 'partner_id': cls.partner_b.id}),
|
|
(0, 0, {'debit': 2000.0, 'credit': 0.0, 'name': '2017_1_2', 'account_id': cls.company_data['default_account_payable'].id, 'partner_id': cls.partner_a.id}),
|
|
(0, 0, {'debit': 3000.0, 'credit': 0.0, 'name': '2017_1_3', 'account_id': cls.company_data['default_account_payable'].id, 'partner_id': cls.partner_a.id}),
|
|
(0, 0, {'debit': 4000.0, 'credit': 0.0, 'name': '2017_1_4', 'account_id': cls.company_data['default_account_receivable'].id, 'partner_id': cls.partner_a.id}),
|
|
(0, 0, {'debit': 5000.0, 'credit': 0.0, 'name': '2017_1_5', 'account_id': cls.company_data['default_account_receivable'].id, 'partner_id': cls.partner_a.id}),
|
|
(0, 0, {'debit': 6000.0, 'credit': 0.0, 'name': '2017_1_6', 'account_id': cls.company_data['default_account_receivable'].id, 'partner_id': cls.partner_a.id}),
|
|
(0, 0, {'debit': 0.0, 'credit': 6000.0, 'name': '2017_1_7', 'account_id': cls.company_data['default_account_receivable'].id, 'partner_id': cls.partner_c.id}),
|
|
(0, 0, {'debit': 0.0, 'credit': 7000.0, 'name': '2017_1_8', 'account_id': cls.company_data['default_account_receivable'].id, 'partner_id': cls.partner_c.id}),
|
|
(0, 0, {'debit': 0.0, 'credit': 8000.0, 'name': '2017_1_9', 'account_id': cls.company_data['default_account_receivable'].id, 'partner_id': cls.partner_c.id}),
|
|
],
|
|
})
|
|
cls.move_2017_1.action_post()
|
|
|
|
# Entry in 2017 for company_2 to test the current period in multi-companies/multi-currencies.
|
|
cls.move_2017_2 = cls.env['account.move'].create({
|
|
'move_type': 'entry',
|
|
'date': fields.Date.from_string('2017-06-01'),
|
|
'journal_id': cls.company_data_2['default_journal_misc'].id,
|
|
'line_ids': [
|
|
(0, 0, {'debit': 400.0, 'credit': 0.0, 'name': '2017_2_1', 'account_id': cls.company_data_2['default_account_receivable'].id}),
|
|
(0, 0, {'debit': 0.0, 'credit': 400.0, 'name': '2017_2_2', 'account_id': cls.company_data_2['default_account_receivable'].id}),
|
|
],
|
|
})
|
|
cls.move_2017_2.action_post()
|
|
|
|
cls.report = cls.env.ref('account_reports.partner_ledger_report')
|
|
|
|
def test_partner_ledger_send_recipients_multi_currency(self):
|
|
''' Computing the recipients when sending the report by email runs the sums
|
|
query, which joins the currency table. In a multi-currency setup that table
|
|
is a temporary table; make sure it is created first so the query does not
|
|
crash with a missing "account_currency_table" relation. '''
|
|
report = self.report.with_context(
|
|
allowed_company_ids=(self.company_data['company'] + self.company_data_2['company']).ids
|
|
)
|
|
options = self._generate_options(report, fields.Date.from_string('2017-01-01'), fields.Date.from_string('2017-12-31'))
|
|
|
|
# Two companies with different currencies must use the (temporary) currency table.
|
|
self.assertNotEqual(options['currency_table']['type'], 'monocurrency')
|
|
|
|
# Without initializing the currency table this raises psycopg2.errors.UndefinedTable.
|
|
recipients = report._get_report_send_recipients(options)
|
|
self.assertEqual(
|
|
sorted(recipients.mapped('name')),
|
|
['partner_a', 'partner_b', 'partner_c'],
|
|
)
|
|
|
|
def test_partner_ledger_unfold(self):
|
|
''' Test unfolding a line when rendering the whole report. '''
|
|
options = self._generate_options(self.report, fields.Date.from_string('2017-01-01'), fields.Date.from_string('2017-12-31'))
|
|
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('partner_a', 20000.0, 0.0, 20150.0),
|
|
('partner_b', 1000.0, 0.0, 1200.0),
|
|
('partner_c', 0.0, 21000.0, -21350.0),
|
|
('Unknown Partner', 200.0, 200.0, 0.0),
|
|
('Total', 21200.0, 21200.0, 0.0),
|
|
],
|
|
options,
|
|
)
|
|
|
|
options['unfolded_lines'] = [self.report._get_generic_line_id('res.partner', self.partner_a.id)]
|
|
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('partner_a', 20000.0, 0.0, 20150.0),
|
|
('Initial Balance', '', '', 150.0),
|
|
('MISC/2017/01/0001 2017_1_2', 2000.0, 0.0, 2150.0),
|
|
('MISC/2017/01/0001 2017_1_3', 3000.0, 0.0, 5150.0),
|
|
('MISC/2017/01/0001 2017_1_4', 4000.0, 0.0, 9150.0),
|
|
('MISC/2017/01/0001 2017_1_5', 5000.0, 0.0, 14150.0),
|
|
('MISC/2017/01/0001 2017_1_6', 6000.0, 0.0, 20150.0),
|
|
('Total partner_a', 20000.0, 0.0, 20150.0),
|
|
('partner_b', 1000.0, 0.0, 1200.0),
|
|
('partner_c', 0.0, 21000.0, -21350.0),
|
|
('Unknown Partner', 200.0, 200.0, 0.0),
|
|
('Total', 21200.0, 21200.0, 0.0),
|
|
],
|
|
options,
|
|
)
|
|
|
|
def test_partner_ledger_batch_data_generator(self):
|
|
""" Test the custom_unfold_all_batch_data_generator """
|
|
options = self._generate_options(
|
|
self.report,
|
|
fields.Date.from_string('2017-01-01'),
|
|
fields.Date.from_string('2017-12-31'),
|
|
default_options={'unfold_all': True}
|
|
)
|
|
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('partner_a', 20000.0, 0.0, 20150.0),
|
|
('Initial Balance', '', '', 150.0),
|
|
('MISC/2017/01/0001 2017_1_2', 2000.0, 0.0, 2150.0),
|
|
('MISC/2017/01/0001 2017_1_3', 3000.0, 0.0, 5150.0),
|
|
('MISC/2017/01/0001 2017_1_4', 4000.0, 0.0, 9150.0),
|
|
('MISC/2017/01/0001 2017_1_5', 5000.0, 0.0, 14150.0),
|
|
('MISC/2017/01/0001 2017_1_6', 6000.0, 0.0, 20150.0),
|
|
('Total partner_a', 20000.0, 0.0, 20150.0),
|
|
('partner_b', 1000.0, 0.0, 1200.0),
|
|
('Initial Balance', '', '', 200.0),
|
|
('MISC/2017/01/0001 2017_1_1', 1000.0, 0.0, 1200.0),
|
|
('Total partner_b', 1000.0, 0.0, 1200.0),
|
|
('partner_c', 0.0, 21000.0, -21350.0),
|
|
('Initial Balance', '', '', -350.0),
|
|
('MISC/2017/01/0001 2017_1_7', 0.0, 6000.0, -6350.0),
|
|
('MISC/2017/01/0001 2017_1_8', 0.0, 7000.0, -13350.0),
|
|
('MISC/2017/01/0001 2017_1_9', 0.0, 8000.0, -21350.0),
|
|
('Total partner_c', 0.0, 21000.0, -21350.0),
|
|
('Unknown Partner', 200.0, 200.0, 0.0),
|
|
('MISC/2017/06/0001 2017_2_1', 200.0, 0.0, 200.0),
|
|
('MISC/2017/06/0001 2017_2_2', 0.0, 200.0, 0.0),
|
|
('Total Unknown Partner', 200.0, 200.0, 0.0),
|
|
('Total', 21200.0, 21200.0, 0.0),
|
|
],
|
|
options,
|
|
)
|
|
|
|
def test_partner_ledger_load_more(self):
|
|
''' Test unfolding a line to use the load more. '''
|
|
self.report.load_more_limit = 2
|
|
|
|
options = self._generate_options(self.report, fields.Date.from_string('2017-01-01'), fields.Date.from_string('2017-12-31'))
|
|
options['unfolded_lines'] = [self.report._get_generic_line_id('res.partner', self.partner_a.id)]
|
|
|
|
report_lines = self.report._get_lines(options)
|
|
|
|
self.assertLinesValues(
|
|
report_lines,
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('partner_a', 20000.0, 0.0, 20150.0),
|
|
('Initial Balance', '', '', 150.0),
|
|
('MISC/2017/01/0001 2017_1_2', 2000.0, 0.0, 2150.0),
|
|
('MISC/2017/01/0001 2017_1_3', 3000.0, 0.0, 5150.0),
|
|
('Load more...', '', '', ''),
|
|
('Total partner_a', 20000.0, 0.0, 20150.0),
|
|
('partner_b', 1000.0, 0.0, 1200.0),
|
|
('partner_c', 0.0, 21000.0, -21350.0),
|
|
('Unknown Partner', 200.0, 200.0, 0.0),
|
|
('Total', 21200.0, 21200.0, 0.0),
|
|
],
|
|
options,
|
|
)
|
|
|
|
load_more_1 = self.report.get_expanded_lines(
|
|
options,
|
|
report_lines[0]['id'],
|
|
report_lines[4]['groupby'],
|
|
'_report_expand_unfoldable_line_partner_ledger',
|
|
report_lines[4]['progress'],
|
|
report_lines[4]['offset'],
|
|
None,
|
|
)
|
|
|
|
self.assertLinesValues(
|
|
load_more_1,
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('MISC/2017/01/0001 2017_1_4', 4000.0, 0.0, 9150.0),
|
|
('MISC/2017/01/0001 2017_1_5', 5000.0, 0.0, 14150.0),
|
|
('Load more...', '', '', ''),
|
|
],
|
|
options,
|
|
)
|
|
|
|
load_more_2 = self.report.get_expanded_lines(
|
|
options,
|
|
report_lines[0]['id'],
|
|
load_more_1[2]['groupby'],
|
|
'_report_expand_unfoldable_line_partner_ledger',
|
|
load_more_1[2]['progress'],
|
|
load_more_1[2]['offset'],
|
|
None,
|
|
)
|
|
|
|
self.assertLinesValues(
|
|
load_more_2,
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('MISC/2017/01/0001 2017_1_6', 6000.0, 0.0, 20150.0),
|
|
],
|
|
options,
|
|
)
|
|
|
|
def test_partner_ledger_filter_account_types(self):
|
|
''' Test building the report with a filter on account types.
|
|
When filtering on receivable accounts (i.e. trade_receivable and/or non_trade_receivable), partner_b should disappear from the report.
|
|
'''
|
|
options = self._generate_options(self.report, fields.Date.from_string('2017-01-01'), fields.Date.from_string('2017-12-31'))
|
|
options['unfolded_lines'] = [self.report._get_generic_line_id('res.partner', self.partner_a.id)]
|
|
options = self._update_multi_selector_filter(options, 'account_type', ['non_trade_receivable', 'trade_receivable'])
|
|
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('partner_a', 15000.0, 0.0, 15000.0),
|
|
('MISC/2017/01/0001 2017_1_4', 4000.0, 0.0, 4000.0),
|
|
('MISC/2017/01/0001 2017_1_5', 5000.0, 0.0, 9000.0),
|
|
('MISC/2017/01/0001 2017_1_6', 6000.0, 0.0, 15000.0),
|
|
('Total partner_a', 15000.0, 0.0, 15000.0),
|
|
('partner_c', 0.0, 21000.0, -21350.0),
|
|
('Unknown Partner', 200.0, 200.0, 0.0),
|
|
('Total', 15200.0, 21200.0, -6350.0),
|
|
],
|
|
options,
|
|
)
|
|
|
|
def test_partner_ledger_filter_partners(self):
|
|
''' Test the filter on top allowing to filter on res.partner.'''
|
|
options = self._generate_options(self.report, fields.Date.from_string('2017-01-01'), fields.Date.from_string('2017-12-31'))
|
|
options['partner_ids'] = (self.partner_a + self.partner_c).ids
|
|
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('partner_a', 20000.0, 0.00, 20150.0),
|
|
('partner_c', 0.00, 21000.0, -21350.0),
|
|
('Total', 20000.0, 21000.0, -1200.00),
|
|
],
|
|
options,
|
|
)
|
|
|
|
def test_partner_ledger_filter_partner_categories(self):
|
|
''' Test the filter on top allowing to filter on res.partner.category.'''
|
|
options = self._generate_options(self.report, fields.Date.from_string('2017-01-01'), fields.Date.from_string('2017-12-31'))
|
|
options['partner_categories'] = self.partner_category_a.ids
|
|
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('partner_a', 20000.0, 0.0, 20150.0),
|
|
('partner_b', 1000.0, 0.0, 1200.0),
|
|
('Total', 21000.0, 0.0, 21350.0),
|
|
],
|
|
options,
|
|
)
|
|
|
|
def test_partner_ledger_unknown_partner(self):
|
|
''' Test the partner ledger for whenever a line appearing in it has no partner assigned.
|
|
Check that reconciling this line with an invoice/bill of a partner does affect his balance.
|
|
'''
|
|
options = self._generate_options(self.report, fields.Date.from_string('2017-01-01'), fields.Date.from_string('2017-12-31'))
|
|
|
|
misc_move = self.env['account.move'].create({
|
|
'date': '2017-03-31',
|
|
'line_ids': [
|
|
(0, 0, {'debit': 1000.0, 'credit': 0.0, 'account_id': self.company_data['default_account_revenue'].id}),
|
|
(0, 0, {'debit': 0.0, 'credit': 1000.0, 'account_id': self.company_data['default_account_receivable'].id}),
|
|
],
|
|
})
|
|
misc_move.action_post()
|
|
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('partner_a', 20000.0, 0.00, 20150.0),
|
|
('partner_b', 1000.00, 0.00, 1200.00),
|
|
('partner_c', 0.00, 21000.0, -21350.0),
|
|
('Unknown Partner', 200.00, 1200.00, -1000.00),
|
|
('Total', 21200.0, 22200.0, -1000.00),
|
|
],
|
|
options,
|
|
)
|
|
|
|
debit_line = self.move_2017_1.line_ids.filtered(lambda line: line.debit == 4000.0)
|
|
credit_line = misc_move.line_ids.filtered(lambda line: line.credit == 1000.0)
|
|
(debit_line + credit_line).reconcile()
|
|
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('partner_a', 20000.0, 1000.00, 19150.0),
|
|
('partner_b', 1000.00, 0.00, 1200.00),
|
|
('partner_c', 0.00, 21000.0, -21350.0),
|
|
('Unknown Partner', 1200.00, 1200.00, 0.00),
|
|
('Total', 22200.0, 23200.0, -1000.00),
|
|
],
|
|
options,
|
|
)
|
|
|
|
# Unfold 'partner_a'
|
|
options['unfolded_lines'] = [self.report._get_generic_line_id('res.partner', self.partner_a.id)]
|
|
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('partner_a', 20000.0, 1000.00, 19150.0),
|
|
('Initial Balance', '', '', 150.0),
|
|
('MISC/2017/01/0001 2017_1_2', 2000.00, 0.00, 2150.0),
|
|
('MISC/2017/01/0001 2017_1_3', 3000.00, 0.00, 5150.0),
|
|
('MISC/2017/01/0001 2017_1_4', 4000.00, 0.00, 9150.0),
|
|
('MISC/2017/01/0001 2017_1_5', 5000.00, 0.00, 14150.0),
|
|
('MISC/2017/01/0001 2017_1_6', 6000.00, 0.00, 20150.0),
|
|
('MISC/2017/03/0001', 0.00, 1000.00, 19150.0),
|
|
('Total partner_a', 20000.0, 1000.00, 19150.0),
|
|
('partner_b', 1000.00, 0.00, 1200.00),
|
|
('partner_c', 0.00, 21000.0, -21350.0),
|
|
('Unknown Partner', 1200.00, 1200.00, 0.00),
|
|
('Total', 22200.0, 23200.0, -1000.00),
|
|
],
|
|
options,
|
|
)
|
|
|
|
# Unfold 'Unknown Partner'
|
|
options['unfolded_lines'] = [self.report._get_generic_line_id('res.partner', None, markup='no_partner')]
|
|
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('partner_a', 20000.0, 1000.00, 19150.0),
|
|
('partner_b', 1000.00, 0.00, 1200.00),
|
|
('partner_c', 0.00, 21000.0, -21350.0),
|
|
('Unknown Partner', 1200.00, 1200.00, 0.00),
|
|
('MISC/2017/03/0001', 0.00, 1000.00, -1000.00),
|
|
('MISC/2017/06/0001 2017_2_1', 200.00, 0.00, -800.00),
|
|
('MISC/2017/06/0001 2017_2_2', 0.00, 200.00, -1000.00),
|
|
('MISC/2017/03/0001', 1000.00, 0.00, 0.00),
|
|
('Total Unknown Partner', 1200.00, 1200.00, 0.00),
|
|
('Total', 22200.0, 23200.0, -1000.00),
|
|
],
|
|
options,
|
|
)
|
|
|
|
# Change the dates to exclude the reconciliation max date: situation is back to the beginning
|
|
options = self._generate_options(self.report, fields.Date.from_string('2017-01-01'), fields.Date.from_string('2017-03-30'))
|
|
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('partner_a', 20000.0, 0.00, 20150.0),
|
|
('partner_b', 1000.00, 0.00, 1200.00),
|
|
('partner_c', 0.00, 21000.0, -21350.0),
|
|
('Total', 21000.0, 21000.0, 0.00),
|
|
],
|
|
options,
|
|
)
|
|
|
|
# Change the dates to have a date_from > to the reconciliation max date and check the initial balances are correct
|
|
options = self._generate_options(self.report, fields.Date.from_string('2017-04-01'), fields.Date.from_string('2017-04-01'))
|
|
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('partner_a', 0.0, 1000.0, 19150.0),
|
|
('partner_b', 0.0, 0.0, 1200.00),
|
|
('partner_c', 0.0, 0.0, -21350.0),
|
|
('Unknown Partner', 1000.0, 0.0, 0.0),
|
|
('Total', 1000.0, 1000.0, -1000.0),
|
|
],
|
|
options,
|
|
)
|
|
|
|
# Unfold 'partner_a' to check the initial balance line is correct
|
|
options['unfolded_lines'] = [self.report._get_generic_line_id('res.partner', self.partner_a.id)]
|
|
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('partner_a', 0.0, 1000.0, 19150.0),
|
|
('Initial Balance', '', 1000.0, 19150.0),
|
|
('Total partner_a', 0.0, 1000.0, 19150.0),
|
|
('partner_b', 0.0, 0.0, 1200.0),
|
|
('partner_c', 0.0, 0.0, -21350.0),
|
|
('Unknown Partner', 1000.0, 0.0, 0.0),
|
|
('Total', 1000.0, 1000.0, -1000.0),
|
|
],
|
|
options,
|
|
)
|
|
|
|
def test_partner_ledger_prefix_groups(self):
|
|
partner_names = [
|
|
'A',
|
|
'A partner',
|
|
'A nice partner',
|
|
'A new partner',
|
|
'An original partner',
|
|
'Another partner',
|
|
'Anonymous partner',
|
|
'Annoyed partner',
|
|
'Brave partner',
|
|
]
|
|
|
|
test_date = '2010-12-13'
|
|
test_partners = self.env['res.partner']
|
|
for name in partner_names:
|
|
partner = self.env['res.partner'].create({'name': name})
|
|
test_partners += partner
|
|
invoice = self.init_invoice('out_invoice', partner=partner, invoice_date=test_date, amounts=[42.0], taxes=[], post=True)
|
|
|
|
# Without prefix groups
|
|
options = self._generate_options(self.report, test_date, test_date)
|
|
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Journal Debit Credit Balance
|
|
[ 0, 1, 6, 7, 9],
|
|
[
|
|
('A', '', 42.0, 0.0, 42.0),
|
|
('A new partner', '', 42.0, 0.0, 42.0),
|
|
('A nice partner', '', 42.0, 0.0, 42.0),
|
|
('A partner', '', 42.0, 0.0, 42.0),
|
|
('An original partner', '', 42.0, 0.0, 42.0),
|
|
('Annoyed partner', '', 42.0, 0.0, 42.0),
|
|
('Anonymous partner', '', 42.0, 0.0, 42.0),
|
|
('Another partner', '', 42.0, 0.0, 42.0),
|
|
('Brave partner', '', 42.0, 0.0, 42.0),
|
|
('Total', '', 378.0, 0.0, 378.0),
|
|
],
|
|
options,
|
|
)
|
|
|
|
# With prefix groups
|
|
self.report.prefix_groups_threshold = 3
|
|
options = self._generate_options(self.report, test_date, test_date, default_options={'unfold_all': True})
|
|
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Journal Debit Credit Balance
|
|
[ 0, 1, 6, 7, 9],
|
|
[
|
|
('A (8 lines)', '', 336.0, 0.0, 336.0),
|
|
('A', '', 42.0, 0.0, 42.0),
|
|
('INV/2010/00001', 'INV', 42.0, 0.0, 42.0),
|
|
('Total A', '', 42.0, 0.0, 42.0),
|
|
('A[ ] (3 lines)', '', 126.0, 0.0, 126.0),
|
|
('A N (2 lines)', '', 84.0, 0.0, 84.0),
|
|
('A new partner', '', 42.0, 0.0, 42.0),
|
|
('INV/2010/00004', 'INV', 42.0, 0.0, 42.0),
|
|
('Total A new partner', '', 42.0, 0.0, 42.0),
|
|
('A nice partner', '', 42.0, 0.0, 42.0),
|
|
('INV/2010/00003', 'INV', 42.0, 0.0, 42.0),
|
|
('Total A nice partner', '', 42.0, 0.0, 42.0),
|
|
('Total A N (2 lines)', '', 84.0, 0.0, 84.0),
|
|
('A P (1 line)', '', 42.0, 0.0, 42.0),
|
|
('A partner', '', 42.0, 0.0, 42.0),
|
|
('INV/2010/00002', 'INV', 42.0, 0.0, 42.0),
|
|
('Total A partner', '', 42.0, 0.0, 42.0),
|
|
('Total A P (1 line)', '', 42.0, 0.0, 42.0),
|
|
('Total A[ ] (3 lines)', '', 126.0, 0.0, 126.0),
|
|
('AN (4 lines)', '', 168.0, 0.0, 168.0),
|
|
('AN[ ] (1 line)', '', 42.0, 0.0, 42.0),
|
|
('An original partner', '', 42.0, 0.0, 42.0),
|
|
('INV/2010/00005', 'INV', 42.0, 0.0, 42.0),
|
|
('Total An original partner', '', 42.0, 0.0, 42.0),
|
|
('Total AN[ ] (1 line)', '', 42.0, 0.0, 42.0),
|
|
('ANN (1 line)', '', 42.0, 0.0, 42.0),
|
|
('Annoyed partner', '', 42.0, 0.0, 42.0),
|
|
('INV/2010/00008', 'INV', 42.0, 0.0, 42.0),
|
|
('Total Annoyed partner', '', 42.0, 0.0, 42.0),
|
|
('Total ANN (1 line)', '', 42.0, 0.0, 42.0),
|
|
('ANO (2 lines)', '', 84.0, 0.0, 84.0),
|
|
('Anonymous partner', '', 42.0, 0.0, 42.0),
|
|
('INV/2010/00007', 'INV', 42.0, 0.0, 42.0),
|
|
('Total Anonymous partner', '', 42.0, 0.0, 42.0),
|
|
('Another partner', '', 42.0, 0.0, 42.0),
|
|
('INV/2010/00006', 'INV', 42.0, 0.0, 42.0),
|
|
('Total Another partner', '', 42.0, 0.0, 42.0),
|
|
('Total ANO (2 lines)', '', 84.0, 0.0, 84.0),
|
|
('Total AN (4 lines)', '', 168.0, 0.0, 168.0),
|
|
('Total A (8 lines)', '', 336.0, 0.0, 336.0),
|
|
('B (1 line)', '', 42.0, 0.0, 42.0),
|
|
('Brave partner', '', 42.0, 0.0, 42.0),
|
|
('INV/2010/00009', 'INV', 42.0, 0.0, 42.0),
|
|
('Total Brave partner', '', 42.0, 0.0, 42.0),
|
|
('Total B (1 line)', '', 42.0, 0.0, 42.0),
|
|
('Total', '', 378.0, 0.0, 378.0),
|
|
],
|
|
options,
|
|
)
|
|
|
|
def test_filter_unreconciled_entries_only(self):
|
|
new_partner = self.env['res.partner'].create({'name': 'Obiwan Kenobi'})
|
|
move_1 = self.init_invoice('out_invoice', partner=new_partner, invoice_date='2019-01-01', amounts=[1000.0], taxes=[], post=True)
|
|
move_2 = self.init_invoice('out_invoice', partner=new_partner, invoice_date='2019-01-01', amounts=[5000.0], taxes=[], post=True)
|
|
|
|
self.env['account.payment.register'].create({
|
|
'payment_date': '2019-01-01',
|
|
'line_ids': move_1.line_ids.filtered(lambda l: l.display_type == 'payment_term'),
|
|
'amount': 700.0,
|
|
})._create_payments()
|
|
self.env['account.payment.register'].create({
|
|
'payment_date': '2019-01-01',
|
|
'line_ids': move_2.line_ids.filtered(lambda l: l.display_type == 'payment_term'),
|
|
})._create_payments()
|
|
|
|
self.assertEqual(move_1.payment_state, 'partial')
|
|
self.assertEqual(move_2.payment_state, move_2._get_invoice_in_payment_state())
|
|
|
|
options = self._generate_options(self.report, '2019-01-01', '2019-12-31', default_options={'partner_ids': new_partner.ids})
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('Obiwan Kenobi', 6000.0, 5700.0, 300.0),
|
|
('Total', 6000.0, 5700.0, 300.0),
|
|
],
|
|
options
|
|
)
|
|
|
|
options['unreconciled'] = True
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('Obiwan Kenobi', 1000.0, 700.0, 300.0),
|
|
('Total', 1000.0, 700.0, 300.0),
|
|
],
|
|
options
|
|
)
|
|
|
|
def test_print_pdf_exclude_partner_with_name_similar_to_another_partner_email(self):
|
|
"""
|
|
This test verifies that when printing a PDF report, the report accurately reflects the data displayed on the view
|
|
by excluding partners whose email addresses are similar to other partners' names if the search bar is used to filter out partners.
|
|
"""
|
|
partner = self.env['res.partner'].create({'name': 'Great Customer', 'email': 'partner_a@test.com'})
|
|
self.init_invoice('out_invoice', partner=partner, invoice_date='2019-02-14', amounts=[1000.0], taxes=[], post=True)
|
|
options = self._generate_options(self.report, '2019-02-01', '2019-02-28', default_options={
|
|
'filter_search_bar': 'partner_a',
|
|
'export_mode': 'print',
|
|
})
|
|
lines = self.report._get_lines(options)
|
|
self.assertFalse(partner.name in [line['name'] for line in lines])
|
|
|
|
def test_partner_ledger_search_with_unknown_partner(self):
|
|
''' Test that the lines with no partners are included in the report when searching for "Unknown Partner" '''
|
|
options = self._generate_options(self.report, fields.Date.from_string('2017-01-01'), fields.Date.from_string('2017-12-31'), default_options={
|
|
'filter_search_bar': 'un',
|
|
'export_mode': 'print',
|
|
})
|
|
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('Unknown Partner', 200.0, 200.0, 0.0),
|
|
('Total', 200.0, 200.0, 0.0),
|
|
],
|
|
options,
|
|
)
|
|
|
|
partner = self.env['res.partner'].create({'name': 'Unexpected Customer'})
|
|
self.init_invoice('out_invoice', partner=partner, invoice_date='2017-02-14', amounts=[1000.0], taxes=[], post=True)
|
|
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('Unexpected Customer', 1000.0, 0.0, 1000.0),
|
|
('Unknown Partner', 200.0, 200.0, 0.0),
|
|
('Total', 1200.0, 200.0, 1000.0),
|
|
],
|
|
options,
|
|
)
|
|
|
|
def test_no_amount_currency_col_in_single_currency(self):
|
|
# In multi-currency, we get the amount_currency column
|
|
self.assertGreater(len(self.env['res.currency'].search([])), 1)
|
|
options = self._generate_options(self.report, fields.Date.from_string('2023-01-01'), fields.Date.from_string('2023-12-31'))
|
|
self.assertTrue(any(col['expression_label'] == 'amount_currency' for col in options['columns']))
|
|
|
|
# Not in single-currency
|
|
self.env['res.currency'].search([('name', '!=', 'USD')]).with_context(force_deactivate=True).active = False
|
|
self.assertEqual(len(self.env['res.currency'].search([])), 1)
|
|
options = self._generate_options(self.report, fields.Date.from_string('2023-01-01'), fields.Date.from_string('2023-12-31'))
|
|
self.assertFalse(any(col['expression_label'] == 'amount_currency' for col in options['columns']))
|
|
|
|
def test_partner_ledger_fully_reconcile_previous_year(self):
|
|
"""
|
|
Verify the report's behavior when a partner is fully reconciled and has a zero balance.
|
|
If the partner's balance is zero:
|
|
If the partner has any unreconciled items, display the partner's information in the report.
|
|
If the partner has no unreconciled items but has an initial balance > 0, show the partner.
|
|
If the partner has no unreconciled items and has an initial balance = 0, hide the partner.
|
|
"""
|
|
new_partner = self.env['res.partner'].create({'name': 'Anakin Skywalker'})
|
|
move = self.env['account.move'].create({
|
|
'move_type': 'out_invoice',
|
|
'invoice_date': '2019-01-01',
|
|
'partner_id': new_partner.id,
|
|
'invoice_line_ids': [Command.create({
|
|
'quantity': 1,
|
|
'price_unit': 500.0,
|
|
'tax_ids': [],
|
|
})]
|
|
})
|
|
move.action_post()
|
|
|
|
payment_1 = self.env['account.move'].create({
|
|
'move_type': 'entry',
|
|
'date': '2019-01-01',
|
|
'journal_id': self.company_data['default_journal_misc'].id,
|
|
'partner_id': new_partner.id,
|
|
'line_ids': [
|
|
Command.create({'debit': 0.0, 'credit': 500.0, 'account_id': self.company_data['default_account_receivable'].id}),
|
|
Command.create({'debit': 500.0, 'credit': 0.0, 'account_id': self.company_data['default_journal_bank'].default_account_id.id}),
|
|
],
|
|
})
|
|
payment_1.action_post()
|
|
|
|
options = self._generate_options(self.report, '2020-01-01', '2020-12-31', default_options={'partner_ids': new_partner.ids})
|
|
# Balance is 0 but there are unreconciled entries, so we show the line
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('Total', 0.0, 0.0, 0.0),
|
|
],
|
|
options,
|
|
)
|
|
|
|
(payment_1 + move).line_ids.filtered(
|
|
lambda line: line.account_id == self.company_data['default_account_receivable']
|
|
).reconcile()
|
|
|
|
# Balance is still 0 and there is no more unreconciled entries, the partner is hide from the report
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('Total', 0.0, 0.0, 0.0),
|
|
],
|
|
options,
|
|
)
|
|
|
|
def test_partner_ledger_fully_reconcile_current_year(self):
|
|
new_partner = self.env['res.partner'].create({'name': 'Darth Vader'})
|
|
move = self.env['account.move'].create({
|
|
'move_type': 'out_invoice',
|
|
'invoice_date': '2019-01-01',
|
|
'partner_id': new_partner.id,
|
|
'invoice_line_ids': [Command.create({
|
|
'quantity': 1,
|
|
'price_unit': 500.0,
|
|
'tax_ids': [],
|
|
})]
|
|
})
|
|
move.action_post()
|
|
|
|
payment_1 = self.env['account.move'].create({
|
|
'move_type': 'entry',
|
|
'date': '2019-01-01',
|
|
'journal_id': self.company_data['default_journal_misc'].id,
|
|
'partner_id': new_partner.id,
|
|
'line_ids': [
|
|
Command.create({'debit': 0.0, 'credit': 500.0, 'account_id': self.company_data['default_account_receivable'].id}),
|
|
Command.create({'debit': 500.0, 'credit': 0.0, 'account_id': self.company_data['default_journal_bank'].default_account_id.id}),
|
|
],
|
|
})
|
|
payment_1.action_post()
|
|
|
|
options = self._generate_options(self.report, '2019-01-01', '2019-12-31', default_options={'partner_ids': new_partner.ids})
|
|
# Balance is 0 but there are unreconciled entries, so we show the line
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('Darth Vader', 500.0, 500.0, 0.0),
|
|
('Total', 500.0, 500.0, 0.0),
|
|
],
|
|
options,
|
|
)
|
|
|
|
(payment_1 + move).line_ids.filtered(
|
|
lambda line: line.account_id == self.company_data['default_account_receivable']
|
|
).reconcile()
|
|
|
|
# Balance is still 0 and there is no more unreconciled entries, but the moves is in the current report period,
|
|
# so we still show the partner in the report
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('Darth Vader', 500.0, 500.0, 0.0),
|
|
('Total', 500.0, 500.0, 0.0),
|
|
],
|
|
options,
|
|
)
|
|
|
|
def test_partner_ledger_toggle_followup(self):
|
|
"""Make sure that toggling the followup also (and only) toggles other lines of the same invoice."""
|
|
installments_payment_term = self.env['account.payment.term'].create({
|
|
'name': "3 installments",
|
|
'line_ids': [
|
|
Command.create({'value_amount': 40, 'value': 'percent', 'nb_days': 0}),
|
|
Command.create({'value_amount': 30, 'value': 'percent', 'nb_days': 30}),
|
|
Command.create({'value_amount': 30, 'value': 'percent', 'nb_days': 60}),
|
|
],
|
|
})
|
|
invoices = self.env['account.move'].create([
|
|
{
|
|
'move_type': 'out_invoice',
|
|
'invoice_date': fields.Date.from_string('2024-08-01'),
|
|
'partner_id': self.partner_a.id,
|
|
'invoice_line_ids': [Command.create({'quantity': 1, 'price_unit': 1000})],
|
|
'invoice_payment_term_id': installments_payment_term.id,
|
|
},
|
|
{
|
|
'move_type': 'out_invoice',
|
|
'invoice_date': fields.Date.from_string('2024-08-10'),
|
|
'partner_id': self.partner_a.id,
|
|
'invoice_line_ids': [Command.create({'quantity': 1, 'price_unit': 500})],
|
|
'invoice_payment_term_id': installments_payment_term.id,
|
|
},
|
|
])
|
|
invoices.action_post()
|
|
invoice_name = invoices[0].name
|
|
options = self._generate_options(self.report, '2024-01-01', '2024-12-31', default_options={'unfold_all': True})
|
|
lines = self.report._get_lines(options)
|
|
line_ids = [line['id'] for line in lines]
|
|
invoice_1_line_ids = [line['id'] for line in lines if invoice_name in line['name']]
|
|
self.assertEqual(
|
|
self.env['account.partner.ledger.report.handler'].action_toggle_no_followup(invoice_1_line_ids[0], line_ids)['updated_line_ids'],
|
|
invoice_1_line_ids,
|
|
)
|
|
|
|
def test_reconciled_misc_without_partner_shows_with_partner_filter(self):
|
|
"""A misc move without a partner reconciled with a partner invoice must still appear
|
|
when filtering the Partner Ledger by that partner."""
|
|
bernard = self.env['res.partner'].create({'name': 'Bernard Gagnant'})
|
|
invoice = self.init_invoice('out_invoice', partner=bernard, invoice_date='2019-03-01', amounts=[1000.0], taxes=[], post=True)
|
|
|
|
misc_move = self.env['account.move'].create({
|
|
'date': '2019-03-02',
|
|
'journal_id': self.company_data['default_journal_misc'].id,
|
|
'line_ids': [
|
|
(0, 0, {'debit': 1000.0, 'credit': 0.0, 'account_id': self.company_data['default_account_revenue'].id}),
|
|
(0, 0, {'debit': 0.0, 'credit': 1000.0, 'account_id': self.company_data['default_account_receivable'].id}),
|
|
],
|
|
})
|
|
misc_move.action_post()
|
|
|
|
invoice_receivable = invoice.line_ids.filtered(lambda l: l.account_id == self.company_data['default_account_receivable'])
|
|
misc_receivable = misc_move.line_ids.filtered(lambda l: l.account_id == self.company_data['default_account_receivable'] and not l.partner_id)
|
|
(invoice_receivable + misc_receivable).reconcile()
|
|
|
|
# Ensure both the invoice and the misc move appear when the report is fully unfolded.
|
|
options = self._generate_options(self.report, '2019-03-01', '2019-03-31', default_options={'unfold_all': True})
|
|
lines = self.report._get_lines(options)
|
|
self.assertLinesValues(
|
|
lines,
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
(bernard.name, 1000.0, 1000.0, 0.0),
|
|
(invoice.name, 1000.0, 0.0, 1000.0),
|
|
(misc_move.name, 0.0, 1000.0, 0.0),
|
|
('Total ' + bernard.name, 1000.0, 1000.0, 0.0),
|
|
('partner_a', 0.0, 0.0, 20150.0),
|
|
('Initial Balance', '', '', 20150.0),
|
|
('Total partner_a', 0.0, 0.0, 20150.0),
|
|
('partner_b', 0.0, 0.0, 1200.0),
|
|
('Initial Balance', '', '', 1200.0),
|
|
('Total partner_b', 0.0, 0.0, 1200.0),
|
|
('partner_c', 0.0, 0.0, -21350.0),
|
|
('Initial Balance', '', '', -21350.0),
|
|
('Total partner_c', 0.0, 0.0, -21350.0),
|
|
('Unknown Partner', 1000.0, 1000.0, 0.0),
|
|
('Initial Balance', '', '', 0.0),
|
|
('MISC/2019/03/0001', 0.0, 1000.0, -1000.0),
|
|
('MISC/2019/03/0001', 1000.0, 0.0, 0.0),
|
|
('Total Unknown Partner', 1000.0, 1000.0, 0.0),
|
|
('Total', 2000.0, 2000.0, 0.0),
|
|
],
|
|
options,
|
|
)
|
|
|
|
# When filtering the report by the partner, the misc move (despite having no partner)
|
|
# must still appear because it is reconciled with the partner's invoice.
|
|
options_partner = self._generate_options(self.report, '2019-03-01', '2019-03-31', default_options={'unfold_all': True, 'partner_ids': bernard.ids})
|
|
lines_filtered = self.report._get_lines(options_partner)
|
|
self.assertLinesValues(
|
|
lines_filtered,
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
(bernard.name, 1000.0, 1000.0, 0.0),
|
|
(invoice.name, 1000.0, 0.0, 1000.0),
|
|
(misc_move.name, 0.0, 1000.0, 0.0),
|
|
('Total ' + bernard.name, 1000.0, 1000.0, 0.0),
|
|
('Total', 1000.0, 1000.0, 0.0),
|
|
],
|
|
options_partner,
|
|
)
|
|
|
|
def test_partner_ledger_without_filter_partner(self):
|
|
""""Test opening the partner ledger report when filter_partner is disabled."""
|
|
self.report.filter_partner = False
|
|
options = self._generate_options(
|
|
self.report, '2019-03-01', '2019-03-31',
|
|
default_options={'unfold_all': True}
|
|
)
|
|
self.assertNotIn('partner_ids', options)
|
|
|
|
report_lines = self.report._get_lines(options)
|
|
self.assertLinesValues(
|
|
report_lines,
|
|
# Name Debit Credit Balance
|
|
[ 0, 6, 7, 9],
|
|
[
|
|
('partner_a', 0.0, 0.0, 20150.0),
|
|
('Initial Balance', '', '', 20150.0),
|
|
('Total partner_a', 0.0, 0.0, 20150.0),
|
|
('partner_b', 0.0, 0.0, 1200.0),
|
|
('Initial Balance', '', '', 1200.0),
|
|
('Total partner_b', 0.0, 0.0, 1200.0),
|
|
('partner_c', 0.0, 0.0, -21350.0),
|
|
('Initial Balance', '', '', -21350.0),
|
|
('Total partner_c', 0.0, 0.0, -21350.0),
|
|
('Total', 0.0, 0.0, 0.0),
|
|
],
|
|
options,
|
|
)
|
|
|
|
def test_partner_ledger_amount_currency(self):
|
|
"""
|
|
Ensure the partner ledger (and its variants) correctly display the amount currency for the partner line
|
|
in the case where all journal items of this partner share the same foreign currency per column group.
|
|
Also ensure that initial balance moves aren't taken into consideration in the calculation of the amount currency.
|
|
"""
|
|
bernard = self.env['res.partner'].create({'name': 'Bernard Gagnant'})
|
|
|
|
eur_currency = self.env.ref('base.EUR')
|
|
eur_currency.active = True
|
|
|
|
self.env['res.currency.rate'].create({
|
|
'name': '2026-12-01',
|
|
'rate': 1.0 / 2.0,
|
|
'currency_id': eur_currency.id,
|
|
'company_id': self.env.company.id,
|
|
})
|
|
|
|
usd_invoice = self.init_invoice('out_invoice', partner=bernard, invoice_date='2025-12-31', amounts=[1000.0], taxes=[])
|
|
eur_invoice = self.init_invoice('out_invoice', partner=bernard, invoice_date='2026-01-01', amounts=[1000.0], taxes=[], currency=eur_currency)
|
|
|
|
(usd_invoice + eur_invoice).action_post()
|
|
|
|
# USD invoice from previous period; shouldn't affect amount_currency (displayed since it's the only foreign currency in this period).
|
|
options = self._generate_options(self.report, '2026-01-01', '2026-01-31', default_options={'partner_ids': bernard.ids})
|
|
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Debit Credit Amount Currency Balance
|
|
[ 0, 6, 7, 8, 9],
|
|
[
|
|
('Bernard Gagnant', 2000.0, 0.0, 1000.0, 3000.0),
|
|
('Total', 2000.0, 0.0, '', 3000.0),
|
|
],
|
|
options,
|
|
currency_map={8: {'currency': eur_currency}},
|
|
)
|
|
|
|
# Test that if multiple currencies are used during the evaluated period, the amount currency shouldn't be displayed
|
|
gbp_currency = self.env.ref('base.GBP')
|
|
gbp_currency.active = True
|
|
|
|
self.env['res.currency.rate'].create({
|
|
'name': '2026-12-01',
|
|
'rate': 1.0 / 2.0,
|
|
'currency_id': gbp_currency.id,
|
|
'company_id': self.env.company.id,
|
|
})
|
|
|
|
self.init_invoice('out_invoice', partner=bernard, invoice_date='2026-01-01', amounts=[1000.0], taxes=[], currency=gbp_currency, post=True)
|
|
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# Name Debit Credit Amount Currency Balance
|
|
[ 0, 6, 7, 8, 9],
|
|
[
|
|
('Bernard Gagnant', 4000.0, 0.0, '', 5000.0),
|
|
('Total', 4000.0, 0.0, '', 5000.0),
|
|
],
|
|
options,
|
|
)
|
|
|
|
# Test that if multiple currencies are used, but a horizontal groupby is applied so that only a single foreign
|
|
# currency is used per column group, then the report should display the amount currency correctly
|
|
|
|
horizontal_group = self.env['account.report.horizontal.group'].create({
|
|
'name': 'Horizontal Group Currencies',
|
|
'report_ids': [self.report.id],
|
|
'rule_ids': [
|
|
Command.create({
|
|
'field_name': 'currency_id',
|
|
'domain': f"[('id', 'in', {(eur_currency + gbp_currency + self.env.company.currency_id).ids})]",
|
|
}),
|
|
],
|
|
})
|
|
|
|
self.init_invoice('out_invoice', partner=bernard, invoice_date='2026-01-01', amounts=[1000.0], taxes=[], post=True)
|
|
|
|
options = self._generate_options(
|
|
self.report, '2026-01-01', '2026-01-31',
|
|
default_options={
|
|
'partner_ids': bernard.ids,
|
|
'selected_horizontal_group_id': horizontal_group.id,
|
|
}
|
|
)
|
|
|
|
self.assertLinesValues(
|
|
self.report._get_lines(options),
|
|
# [ EUR ] [ GBP ] [ USD ]
|
|
# Name Amount Currency Balance Amount Currency Balance Amount Currency Balance
|
|
[ 0, 8, 9, 17, 18, 26, 27],
|
|
[
|
|
('Bernard Gagnant', 1000.0, 2000.0, 1000.0, 2000.0, '', 2000.0),
|
|
('Total', '', 2000.0, '', 2000.0, '', 2000.0),
|
|
],
|
|
options,
|
|
currency_map={
|
|
8: {'currency': eur_currency},
|
|
17: {'currency': gbp_currency},
|
|
},
|
|
)
|