Files
odoo_source/addons/account/tests/test_payment.py
T
qdp-odoo ee2c76a431 [IMP] account: define the m2m relation between bank statement lines and account.move.line instead of account.move
This is needed in order to support use cases where we have several account.move.line on an account_id of internal_type 'bank' inside a single account.move. Indeed, each journal item should be linked to a bank statement line in order to disappear from the bank reconciliation widget and, previously, setting the reference to the second bank statement line was removing the first as both info had to be filled in a single m2o. OPW: 696842
2016-12-20 14:43:03 +01:00

182 lines
10 KiB
Python

from odoo.addons.account.tests.account_test_classes import AccountingTestCase
import time
class TestPayment(AccountingTestCase):
def setUp(self):
super(TestPayment, self).setUp()
self.register_payments_model = self.env['account.register.payments']
self.payment_model = self.env['account.payment']
self.invoice_model = self.env['account.invoice']
self.invoice_line_model = self.env['account.invoice.line']
self.acc_bank_stmt_model = self.env['account.bank.statement']
self.acc_bank_stmt_line_model = self.env['account.bank.statement.line']
self.partner_agrolait = self.env.ref("base.res_partner_2")
self.partner_axelor = self.env.ref("base.res_partner_2")
self.currency_chf_id = self.env.ref("base.CHF").id
self.currency_usd_id = self.env.ref("base.USD").id
self.currency_eur_id = self.env.ref("base.EUR").id
self.env.ref('base.main_company').write({'currency_id': self.currency_eur_id})
self.product = self.env.ref("product.product_product_4")
self.payment_method_manual_in = self.env.ref("account.account_payment_method_manual_in")
self.payment_method_manual_out = self.env.ref("account.account_payment_method_manual_out")
self.account_receivable = self.env['account.account'].search([('user_type_id', '=', self.env.ref('account.data_account_type_receivable').id)], limit=1)
self.account_payable = self.env['account.account'].search([('user_type_id', '=', self.env.ref('account.data_account_type_payable').id)], limit=1)
self.account_revenue = self.env['account.account'].search([('user_type_id', '=', self.env.ref('account.data_account_type_revenue').id)], limit=1)
self.bank_journal_euro = self.env['account.journal'].create({'name': 'Bank', 'type': 'bank', 'code': 'BNK67'})
self.account_eur = self.bank_journal_euro.default_debit_account_id
self.bank_journal_usd = self.env['account.journal'].create({'name': 'Bank US', 'type': 'bank', 'code': 'BNK68', 'currency_id': self.currency_usd_id})
self.account_usd = self.bank_journal_usd.default_debit_account_id
self.transfer_account = self.env['res.users'].browse(self.env.uid).company_id.transfer_account_id
self.diff_income_account = self.env['res.users'].browse(self.env.uid).company_id.income_currency_exchange_account_id
self.diff_expense_account = self.env['res.users'].browse(self.env.uid).company_id.expense_currency_exchange_account_id
def create_invoice(self, amount=100, type='out_invoice', currency_id=None):
""" Returns an open invoice """
invoice = self.invoice_model.create({
'partner_id': self.partner_agrolait.id,
'reference_type': 'none',
'currency_id': currency_id,
'name': type == 'out_invoice' and 'invoice to client' or 'invoice to supplier',
'account_id': self.account_receivable.id,
'type': type,
'date_invoice': time.strftime('%Y') + '-06-26',
})
self.invoice_line_model.create({
'product_id': self.product.id,
'quantity': 1,
'price_unit': amount,
'invoice_id': invoice.id,
'name': 'something',
'account_id': self.account_revenue.id,
})
invoice.action_invoice_open()
return invoice
def reconcile(self, liquidity_aml, amount=0.0, amount_currency=0.0, currency_id=None):
""" Reconcile a journal entry corresponding to a payment with its bank statement line """
bank_stmt = self.acc_bank_stmt_model.create({
'journal_id': liquidity_aml.journal_id.id,
'date': time.strftime('%Y') + '-07-15',
})
bank_stmt_line = self.acc_bank_stmt_line_model.create({
'name': 'payment',
'statement_id': bank_stmt.id,
'partner_id': self.partner_agrolait.id,
'amount': amount,
'amount_currency': amount_currency,
'currency_id': currency_id,
'date': time.strftime('%Y') + '-07-15'
})
amount_in_widget = currency_id and amount_currency or amount
bank_stmt_line.process_reconciliation(payment_aml_rec=liquidity_aml)
return bank_stmt
def check_journal_items(self, aml_recs, aml_dicts):
def compare_rec_dict(aml_rec, aml_dict):
return aml_rec.account_id.id == aml_dict['account_id'] \
and round(aml_rec.debit, 2) == aml_dict['debit'] \
and round(aml_rec.credit, 2) == aml_dict['credit'] \
and round(aml_rec.amount_currency, 2) == aml_dict['amount_currency'] \
and aml_rec.currency_id.id == aml_dict['currency_id']
for aml_dict in aml_dicts:
# There is no unique key to identify journal items (an account_payment may create several lines
# in the same account), so to check the expected entries are created, we check there is a line
# matching for each dict of expected values
aml_rec = aml_recs.filtered(lambda r: compare_rec_dict(r, aml_dict))
self.assertEqual(len(aml_rec), 1, "Expected a move line with values : %s" % str(aml_dict))
if aml_dict.get('currency_diff'):
if aml_rec.credit:
currency_diff_move = aml_rec.matched_debit_ids.full_reconcile_id.exchange_move_id
else:
currency_diff_move = aml_rec.matched_credit_ids.full_reconcile_id.exchange_move_id
for currency_diff_line in currency_diff_move.line_ids:
if aml_dict.get('currency_diff') > 0:
if currency_diff_line.account_id.id == aml_rec.account_id.id:
self.assertAlmostEquals(currency_diff_line.debit, aml_dict.get('currency_diff'))
else:
self.assertAlmostEquals(currency_diff_line.credit, aml_dict.get('currency_diff'))
self.assertIn(currency_diff_line.account_id.id, [self.diff_expense_account.id, self.diff_income_account.id])
else:
if currency_diff_line.account_id.id == aml_rec.account_id.id:
self.assertAlmostEquals(currency_diff_line.credit, abs(aml_dict.get('currency_diff')))
else:
self.assertAlmostEquals(currency_diff_line.debit, abs(aml_dict.get('currency_diff')))
self.assertIn(currency_diff_line.account_id.id, [self.diff_expense_account.id, self.diff_income_account.id])
def test_full_payment_process(self):
""" Create a payment for two invoices, post it and reconcile it with a bank statement """
inv_1 = self.create_invoice(amount=100, currency_id=self.currency_eur_id)
inv_2 = self.create_invoice(amount=200, currency_id=self.currency_eur_id)
ctx = { 'active_model': 'account.invoice', 'active_ids': [inv_1.id, inv_2.id] }
register_payments = self.register_payments_model.with_context(ctx).create({
'payment_date': time.strftime('%Y') + '-07-15',
'journal_id': self.bank_journal_euro.id,
'payment_method_id': self.payment_method_manual_in.id,
})
register_payments.create_payment()
payment = self.payment_model.search([], order="id desc", limit=1)
self.assertAlmostEquals(payment.amount, 300)
self.assertEqual(payment.state, 'posted')
self.assertEqual(inv_1.state, 'paid')
self.assertEqual(inv_2.state, 'paid')
self.check_journal_items(payment.move_line_ids, [
{'account_id': self.account_eur.id, 'debit': 300.0, 'credit': 0.0, 'amount_currency': 0, 'currency_id': False},
{'account_id': inv_1.account_id.id, 'debit': 0.0, 'credit': 300.0, 'amount_currency': 00, 'currency_id': False},
])
liquidity_aml = payment.move_line_ids.filtered(lambda r: r.account_id == self.account_eur)
bank_statement = self.reconcile(liquidity_aml, 200, 0, False)
self.assertEqual(liquidity_aml.statement_id, bank_statement)
self.assertEqual(liquidity_aml.statement_line_id, bank_statement.line_ids[0])
self.assertEqual(payment.state, 'reconciled')
def test_internal_transfer_journal_usd_journal_eur(self):
""" Create a transfer from a EUR journal to a USD journal """
payment = self.payment_model.create({
'payment_date': time.strftime('%Y') + '-07-15',
'payment_type': 'transfer',
'amount': 50,
'currency_id': self.currency_usd_id,
'journal_id': self.bank_journal_usd.id,
'destination_journal_id': self.bank_journal_euro.id,
'payment_method_id': self.payment_method_manual_out.id,
})
payment.post()
self.check_journal_items(payment.move_line_ids, [
{'account_id': self.transfer_account.id, 'debit': 32.70, 'credit': 0.0, 'amount_currency': 50, 'currency_id': self.currency_usd_id},
{'account_id': self.transfer_account.id, 'debit': 0.0, 'credit': 32.70, 'amount_currency': -50, 'currency_id': self.currency_usd_id},
{'account_id': self.account_eur.id, 'debit': 32.70, 'credit': 0.0, 'amount_currency': 0, 'currency_id': False},
{'account_id': self.account_usd.id, 'debit': 0.0, 'credit': 32.70, 'amount_currency': -50, 'currency_id': self.currency_usd_id},
])
def test_payment_chf_journal_usd(self):
payment = self.payment_model.create({
'payment_date': time.strftime('%Y') + '-07-15',
'payment_type': 'outbound',
'amount': 50,
'currency_id': self.currency_chf_id,
'journal_id': self.bank_journal_usd.id,
'partner_type': 'supplier',
'partner_id': self.partner_axelor.id,
'payment_method_id': self.payment_method_manual_out.id,
})
payment.post()
self.check_journal_items(payment.move_line_ids, [
{'account_id': self.account_usd.id, 'debit': 0.0, 'credit': 38.21, 'amount_currency': -58.42, 'currency_id': self.currency_usd_id},
{'account_id': self.partner_axelor.property_account_payable_id.id, 'debit': 38.21, 'credit': 0.0, 'amount_currency': 50, 'currency_id': self.currency_chf_id},
])