diff --git a/addons/account/account.py b/addons/account/account.py
index 46e7b3457ec..c3ead387fba 100644
--- a/addons/account/account.py
+++ b/addons/account/account.py
@@ -1563,11 +1563,15 @@ class account_move_reconcile(osv.osv):
_defaults = {
'name': lambda self,cr,uid,ctx={}: self.pool.get('ir.sequence').get(cr, uid, 'account.reconcile') or '/',
}
+
def reconcile_partial_check(self, cr, uid, ids, type='auto', context=None):
total = 0.0
for rec in self.browse(cr, uid, ids, context=context):
for line in rec.line_partial_ids:
- total += (line.debit or 0.0) - (line.credit or 0.0)
+ if line.account_id.currency_id:
+ total += line.amount_currency
+ else:
+ total += (line.debit or 0.0) - (line.credit or 0.0)
if not total:
self.pool.get('account.move.line').write(cr, uid,
map(lambda x: x.id, rec.line_partial_ids),
diff --git a/addons/account/account_invoice_view.xml b/addons/account/account_invoice_view.xml
index 11ec7d8360a..a84eb5f5a32 100644
--- a/addons/account/account_invoice_view.xml
+++ b/addons/account/account_invoice_view.xml
@@ -305,8 +305,8 @@
+
-
diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py
index 5de7fed2428..2af05c3c82e 100644
--- a/addons/account/account_move_line.py
+++ b/addons/account/account_move_line.py
@@ -741,7 +741,10 @@ class account_move_line(osv.osv):
company_list.append(line.company_id.id)
for line in self.browse(cr, uid, ids, context=context):
- company_currency_id = line.company_id.currency_id
+ if line.account_id.currency_id:
+ currency_id = line.account_id.currency_id
+ else:
+ currency_id = line.company_id.currency_id
if line.reconcile_id:
raise osv.except_osv(_('Warning'), _('Already Reconciled!'))
if line.reconcile_partial_id:
@@ -749,12 +752,18 @@ class account_move_line(osv.osv):
if not line2.reconcile_id:
if line2.id not in merges:
merges.append(line2.id)
- total += (line2.debit or 0.0) - (line2.credit or 0.0)
+ if line2.account_id.currency_id:
+ total += line2.amount_currency
+ else:
+ total += (line2.debit or 0.0) - (line2.credit or 0.0)
merges_rec.append(line.reconcile_partial_id.id)
else:
unmerge.append(line.id)
- total += (line.debit or 0.0) - (line.credit or 0.0)
- if self.pool.get('res.currency').is_zero(cr, uid, company_currency_id, total):
+ if line.account_id.currency_id:
+ total += line.amount_currency
+ else:
+ total += (line.debit or 0.0) - (line.credit or 0.0)
+ if self.pool.get('res.currency').is_zero(cr, uid, currency_id, total):
res = self.reconcile(cr, uid, merges+unmerge, context=context, writeoff_acc_id=writeoff_acc_id, writeoff_period_id=writeoff_period_id, writeoff_journal_id=writeoff_journal_id)
return res
r_id = move_rec_obj.create(cr, uid, {
diff --git a/addons/account_voucher/__openerp__.py b/addons/account_voucher/__openerp__.py
index 97ac9950efb..5e6e6ab0513 100644
--- a/addons/account_voucher/__openerp__.py
+++ b/addons/account_voucher/__openerp__.py
@@ -59,7 +59,12 @@ Account Voucher module includes all the basic requirements of Voucher Entries fo
"test/account_voucher.yml",
"test/sales_receipt.yml",
"test/sales_payment.yml",
- "test/account_voucher_report.yml"
+ "test/account_voucher_report.yml",
+ "test/case1_usd_usd.yml",
+ "test/case2_usd_eur_debtor_in_eur.yml",
+ "test/case2_usd_eur_debtor_in_usd.yml",
+ "test/case3_eur_eur.yml",
+ "test/case4_cad_chf.yml",
],
'certificate': '0037580727101',
"active": False,
diff --git a/addons/account_voucher/account_voucher.py b/addons/account_voucher/account_voucher.py
index a5ae75cefa9..38af59009d8 100644
--- a/addons/account_voucher/account_voucher.py
+++ b/addons/account_voucher/account_voucher.py
@@ -651,13 +651,302 @@ class account_voucher(osv.osv):
res['account_id'] = account_id
return {'value':res}
+ def _sel_context(self, cr, uid, voucher_id,context=None):
+ """
+ Select the context to use accordingly if it needs to be multicurrency or not.
+
+ :param voucher_id: Id of the actual voucher
+ :return: The returned context will be the same as given in parameter if the voucher currency is the same
+ than the company currency, otherwise it's a copy of the parameter with an extra key 'date' containing
+ the date of the voucher.
+ :rtype: dict
+ """
+ company_currency = self._get_company_currency(cr, uid, voucher_id, context)
+ current_currency = self._get_current_currency(cr, uid, voucher_id, context)
+ if current_currency <> company_currency:
+ context_multi_currency = context.copy()
+ voucher_brw = self.pool.get('account.voucher').browse(cr, uid, voucher_id, context)
+ context_multi_currency.update({'date': voucher_brw.date})
+ return context_multi_currency
+ return context
+
+ def first_move_line_get(self, cr, uid, voucher_id, move_id, company_currency, current_currency, context=None):
+ '''
+ Return a dict to be use to create the first account move line of given voucher.
+
+ :param voucher_id: Id of voucher what we are creating account_move.
+ :param move_id: Id of account move where this line will be added.
+ :param company_currency: id of currency of the company to which the voucher belong
+ :param current_currency: id of currency of the voucher
+ :return: mapping between fieldname and value of account move line to create
+ :rtype: dict
+ '''
+ move_line_obj = self.pool.get('account.move.line')
+ currency_obj = self.pool.get('res.currency')
+ voucher_brw = self.pool.get('account.voucher').browse(cr,uid,voucher_id,context)
+ debit = credit = 0.0
+ # TODO: is there any other alternative then the voucher type ??
+ # ANSWER: We can have payment and receipt "In Advance".
+ # TODO: Make this logic available.
+ # -for sale, purchase we have but for the payment and receipt we do not have as based on the bank/cash journal we can not know its payment or receipt
+ if voucher_brw.type in ('purchase', 'payment'):
+ credit = currency_obj.compute(cr, uid, current_currency, company_currency, voucher_brw.amount, context=context)
+ elif voucher_brw.type in ('sale', 'receipt'):
+ debit = currency_obj.compute(cr, uid, current_currency, company_currency, voucher_brw.amount, context=context)
+ if debit < 0: credit = -debit; debit = 0.0
+ if credit < 0: debit = -credit; credit = 0.0
+ sign = debit - credit < 0 and -1 or 1
+ #set the first line of the voucher
+ move_line = {
+ 'name': voucher_brw.name or '/',
+ 'debit': debit,
+ 'credit': credit,
+ 'account_id': voucher_brw.account_id.id,
+ 'move_id': move_id,
+ 'journal_id': voucher_brw.journal_id.id,
+ 'period_id': voucher_brw.period_id.id,
+ 'partner_id': voucher_brw.partner_id.id,
+ 'currency_id': company_currency <> current_currency and current_currency or False,
+ 'amount_currency': company_currency <> current_currency and sign * voucher_brw.amount or 0.0,
+ 'date': voucher_brw.date,
+ 'date_maturity': voucher_brw.date_due
+ }
+ return move_line
+
+ def account_move_get(self, cr, uid, voucher_id, context=None):
+ '''
+ This method prepare the creation of the account move related to the given voucher.
+
+ :param voucher_id: Id of voucher for which we are creating account_move.
+ :return: mapping between fieldname and value of account move to create
+ :rtype: dict
+ '''
+ move_obj = self.pool.get('account.move')
+ seq_obj = self.pool.get('ir.sequence')
+ voucher_brw = self.pool.get('account.voucher').browse(cr,uid,voucher_id,context)
+ if voucher_brw.number:
+ name = voucher_brw.number
+ elif voucher_brw.journal_id.sequence_id:
+ name = seq_obj.next_by_id(cr, uid, voucher_brw.journal_id.sequence_id.id)
+ else:
+ raise osv.except_osv(_('Error !'),
+ _('Please define a sequence on the journal !'))
+ if not voucher_brw.reference:
+ ref = name.replace('/','')
+ else:
+ ref = voucher_brw.reference
+
+ move = {
+ 'name': name,
+ 'journal_id': voucher_brw.journal_id.id,
+ 'narration': voucher_brw.narration,
+ 'date': voucher_brw.date,
+ 'ref': ref,
+ 'period_id': voucher_brw.period_id and voucher_brw.period_id.id or False
+ }
+ return move
+
+ def _get_exchange_lines(self, cr, uid, line, move_id, amount_residual, company_currency, current_currency, context=None):
+ '''
+ Prepare the two lines due to currency rate difference.
+
+ :param line: browse record of the voucher.line for which we want to create currency rate difference accounting entries
+ :param move_id: Account move wher the move lines will be.
+ :param amount_residual: Amount to be posted.
+ :param company_currency: id of currency of the company to which the voucher belong
+ :param current_currency: id of currency of the voucher
+ :return: the account move line and its counterpart to create, depicted as mapping between fieldname and value
+ :rtype: tuple of dict
+ '''
+ if not line.voucher_id.exchange_acc_id.id:
+ raise osv.except_osv(_('Error!'), _('You must provide an account for the exchange difference.'))
+
+ move_line = {
+ 'journal_id': line.voucher_id.journal_id.id,
+ 'period_id': line.voucher_id.period_id.id,
+ 'name': _('change')+': '+(line.name or '/'),
+ 'account_id': line.account_id.id,
+ 'move_id': move_id,
+ 'partner_id': line.voucher_id.partner_id.id,
+ 'currency_id': company_currency <> current_currency and current_currency or False,
+ 'amount_currency': 0.0,
+ 'quantity': 1,
+ 'credit': amount_residual > 0 and amount_residual or 0.0,
+ 'debit': amount_residual < 0 and -amount_residual or 0.0,
+ 'date': line.voucher_id.date,
+ }
+ move_line_counterpart = {
+ 'journal_id': line.voucher_id.journal_id.id,
+ 'period_id': line.voucher_id.period_id.id,
+ 'name': _('change')+': '+(line.name or '/'),
+ 'account_id': line.voucher_id.exchange_acc_id.id,
+ 'move_id': move_id,
+ 'amount_currency': 0.0,
+ 'partner_id': line.voucher_id.partner_id.id,
+ 'currency_id': company_currency <> current_currency and current_currency or False,
+ 'quantity': 1,
+ 'debit': amount_residual > 0 and amount_residual or 0.0,
+ 'credit': amount_residual < 0 and -amount_residual or 0.0,
+ 'date': line.voucher_id.date,
+ }
+ return (move_line, move_line_counterpart)
+
+ def voucher_move_line_create(self, cr, uid, voucher_id, line_total, move_id, company_currency, current_currency, context=None):
+ '''
+ Create one account move line, on the given account move, per voucher line where amount is not 0.0.
+ It returns Tuple with tot_line what is total of difference between debit and credit and
+ a list of lists with ids to be reconciled with this format (total_deb_cred,list_of_lists).
+
+ :param voucher_id: Voucher id what we are working with
+ :param line_total: Amount of the first line, which correspond to the amount we should totally split among all voucher lines.
+ :param move_id: Account move wher those lines will be joined.
+ :param company_currency: id of currency of the company to which the voucher belong
+ :param current_currency: id of currency of the voucher
+ :return: Tuple build as (remaining amount not allocated on voucher lines, list of account_move_line created in this method)
+ :rtype: tuple(int, list of int)
+ '''
+ move_line_obj = self.pool.get('account.move.line')
+ currency_obj = self.pool.get('res.currency')
+ tot_line = line_total
+ rec_lst_ids = []
+
+ voucher_brw = self.pool.get('account.voucher').browse(cr,uid,voucher_id,context)
+ for line in voucher_brw.line_ids:
+ #create one move line per voucher line where amount is not 0.0
+ if not line.amount:
+ continue
+ #we check if the voucher line is fully paid or not and create a move line to balance the payment and initial invoice if needed
+ if line.amount == line.amount_unreconciled:
+ amount = currency_obj.compute(cr, uid, current_currency, company_currency, line.untax_amount or line.amount, context=context)
+ amount_residual = line.move_line_id.amount_residual - amount #residual amount in company currency
+ else:
+ amount = currency_obj.compute(cr, uid, current_currency, company_currency, line.untax_amount or line.amount, context=context)
+ amount_residual = 0.0
+ move_line = {
+ 'journal_id': voucher_brw.journal_id.id,
+ 'period_id': voucher_brw.period_id.id,
+ 'name': line.name or '/',
+ 'account_id': line.account_id.id,
+ 'move_id': move_id,
+ 'partner_id': voucher_brw.partner_id.id,
+ 'currency_id': company_currency <> current_currency and current_currency or False,
+ 'analytic_account_id': line.account_analytic_id and line.account_analytic_id.id or False,
+ 'quantity': 1,
+ 'credit': 0.0,
+ 'debit': 0.0,
+ 'date': voucher_brw.date
+ }
+ if amount < 0:
+ amount = -amount
+ if line.type == 'dr':
+ line.type = 'cr'
+ else:
+ line.type = 'dr'
+
+ if (line.type=='dr'):
+ tot_line += amount
+ move_line['debit'] = amount
+ else:
+ tot_line -= amount
+ move_line['credit'] = amount
+
+ if voucher_brw.tax_id and voucher_brw.type in ('sale', 'purchase'):
+ move_line.update({
+ 'account_tax_id': voucher_brw.tax_id.id,
+ })
+
+ if move_line.get('account_tax_id', False):
+ tax_data = tax_obj.browse(cr, uid, [move_line['account_tax_id']], context=context)[0]
+ if not (tax_data.base_code_id and tax_data.tax_code_id):
+ raise osv.except_osv(_('No Account Base Code and Account Tax Code!'),_("You have to configure account base code and account tax code on the '%s' tax!") % (tax_data.name))
+
+ sign = (move_line['debit'] - move_line['credit']) < 0 and -1 or 1
+ move_line['amount_currency'] = company_currency <> current_currency and sign * line.amount or False
+ voucher_line = move_line_obj.create(cr, uid, move_line)
+ rec_ids = [voucher_line, line.move_line_id.id]
+
+ if amount_residual:
+ # Change difference entry
+ exch_lines = self._get_exchange_lines(cr, uid, line, move_id, amount_residual, company_currency, current_currency, context=context)
+ new_id = move_line_obj.create(cr, uid, exch_lines[0],context)
+ move_line_obj.create(cr, uid, exch_lines[1], context)
+ rec_ids.append(new_id)
+
+ if line.move_line_id.id:
+ rec_lst_ids.append(rec_ids)
+
+ return (tot_line, rec_lst_ids)
+
+ def writeoff_move_line_get(self, cr, uid, voucher_id, line_total, move_id, name, company_currency, current_currency, context=None):
+ '''
+ Set a dict to be use to create the writeoff move line.
+
+ :param voucher_id: Id of voucher what we are creating account_move.
+ :param line_total: Amount remaining to be allocated on lines.
+ :param move_id: Id of account move where this line will be added.
+ :param name: Description of account move line.
+ :param company_currency: id of currency of the company to which the voucher belong
+ :param current_currency: id of currency of the voucher
+ :return: mapping between fieldname and value of account move line to create
+ :rtype: dict
+ '''
+ move_line_obj = self.pool.get('account.move.line')
+ currency_obj = self.pool.get('res.currency')
+ move_line = {}
+
+ voucher_brw = self.pool.get('account.voucher').browse(cr,uid,voucher_id,context)
+ current_currency_obj = voucher_brw.currency_id or voucher_brw.journal_id.company_id.currency_id
+
+ if not currency_obj.is_zero(cr, uid, current_currency_obj, line_total):
+ diff = line_total
+ account_id = False
+ write_off_name = ''
+ if voucher_brw.payment_option == 'with_writeoff':
+ account_id = voucher_brw.writeoff_acc_id.id
+ write_off_name = voucher_brw.comment
+ elif voucher_brw.type in ('sale', 'receipt'):
+ account_id = voucher_brw.partner_id.property_account_receivable.id
+ else:
+ account_id = voucher_brw.partner_id.property_account_payable.id
+ move_line = {
+ 'name': write_off_name or name,
+ 'account_id': account_id,
+ 'move_id': move_id,
+ 'partner_id': voucher_brw.partner_id.id,
+ 'date': voucher_brw.date,
+ 'credit': diff > 0 and diff or 0.0,
+ 'debit': diff < 0 and -diff or 0.0,
+ 'amount_currency': company_currency <> current_currency and voucher_brw.writeoff_amount or False,
+ 'currency_id': company_currency <> current_currency and current_currency or False,
+ }
+
+ return move_line
+
+ def _get_company_currency(self, cr, uid, voucher_id, context=None):
+ '''
+ Get the currency of the actual company.
+
+ :param voucher_id: Id of the voucher what i want to obtain company currency.
+ :return: currency id of the company of the voucher
+ :rtype: int
+ '''
+ return self.pool.get('account.voucher').browse(cr,uid,voucher_id,context).journal_id.company_id.currency_id.id
+
+ def _get_current_currency(self, cr, uid, voucher_id, context=None):
+ '''
+ Get the currency of the voucher.
+
+ :param voucher_id: Id of the voucher what i want to obtain current currency.
+ :return: currency id of the voucher
+ :rtype: int
+ '''
+ voucher = self.pool.get('account.voucher').browse(cr,uid,voucher_id,context)
+ return voucher.currency_id.id or self._get_company_currency(cr,uid,voucher.id,context)
+
def action_move_line_create(self, cr, uid, ids, context=None):
- def _get_payment_term_lines(term_id, amount):
- term_pool = self.pool.get('account.payment.term')
- if term_id and amount:
- terms = term_pool.compute(cr, uid, term_id, amount)
- return terms
- return False
+ '''
+ Confirm the vouchers given in ids and create the journal entries for each of them
+ '''
if context is None:
context = {}
move_pool = self.pool.get('account.move')
@@ -665,198 +954,44 @@ class account_voucher(osv.osv):
currency_pool = self.pool.get('res.currency')
tax_obj = self.pool.get('account.tax')
seq_obj = self.pool.get('ir.sequence')
- for inv in self.browse(cr, uid, ids, context=context):
- if inv.move_id:
+ for voucher in self.browse(cr, uid, ids, context=context):
+ if voucher.move_id:
continue
- context_multi_currency = context.copy()
- context_multi_currency.update({'date': inv.date})
-
- if inv.number:
- name = inv.number
- elif inv.journal_id.sequence_id:
- name = seq_obj.next_by_id(cr, uid, inv.journal_id.sequence_id.id)
- else:
- raise osv.except_osv(_('Error !'), _('Please define a sequence on the journal !'))
- if not inv.reference:
- ref = name.replace('/','')
- else:
- ref = inv.reference
-
- move = {
- 'name': name,
- 'journal_id': inv.journal_id.id,
- 'narration': inv.narration,
- 'date': inv.date,
- 'ref': ref,
- 'period_id': inv.period_id and inv.period_id.id or False
- }
- move_id = move_pool.create(cr, uid, move)
-
- #create the first line manually
- company_currency = inv.journal_id.company_id.currency_id.id
- current_currency = inv.currency_id.id or company_currency
- current_currency_obj = inv.currency_id or inv.journal_id.company_id.currency_id
- debit = 0.0
- credit = 0.0
- # TODO: is there any other alternative then the voucher type ??
- # -for sale, purchase we have but for the payment and receipt we do not have as based on the bank/cash journal we can not know its payment or receipt
- if inv.type in ('purchase', 'payment'):
- credit = currency_pool.compute(cr, uid, current_currency, company_currency, inv.amount, context=context_multi_currency)
- elif inv.type in ('sale', 'receipt'):
- debit = currency_pool.compute(cr, uid, current_currency, company_currency, inv.amount, context=context_multi_currency)
- if debit < 0:
- credit = -debit
- debit = 0.0
- if credit < 0:
- debit = -credit
- credit = 0.0
- sign = debit - credit < 0 and -1 or 1
- #create the first line of the voucher, the payment made
- move_line = {
- 'name': inv.name or '/',
- 'debit': debit,
- 'credit': credit,
- 'account_id': inv.account_id.id,
- 'move_id': move_id,
- 'journal_id': inv.journal_id.id,
- 'period_id': inv.period_id.id,
- 'partner_id': inv.partner_id.id,
- 'currency_id': company_currency <> current_currency and current_currency or False,
- 'amount_currency': company_currency <> current_currency and sign * inv.amount or 0.0,
- 'date': inv.date,
- 'date_maturity': inv.date_due
- }
- move_line_pool.create(cr, uid, move_line)
+ company_currency = self._get_company_currency(cr, uid, voucher.id, context)
+ current_currency = self._get_current_currency(cr, uid, voucher.id, context)
+ context = self._sel_context(cr, uid, voucher.id, context)
+ #Create the account move record.
+ move_id = move_pool.create(cr, uid, self.account_move_get(cr, uid, voucher.id, context=context), context=context)
+ # Get the name of the account_move just created
+ name = move_pool.browse(cr, uid, move_id, context=context).name
+ #Create the first line of the voucher
+ move_line_id = move_line_pool.create(cr, uid, self.first_move_line_get(cr,uid,voucher.id, move_id, company_currency, current_currency, context), context)
+ move_line_brw = move_line_pool.browse(cr, uid, move_line_id, context=context)
+ line_total = move_line_brw.debit - move_line_brw.credit
rec_list_ids = []
- line_total = debit - credit
- if inv.type == 'sale':
- line_total = line_total - currency_pool.compute(cr, uid, current_currency, company_currency, inv.tax_amount, context=context_multi_currency)
- elif inv.type == 'purchase':
- line_total = line_total + currency_pool.compute(cr, uid, current_currency, company_currency, inv.tax_amount, context=context_multi_currency)
+ if voucher.type == 'sale':
+ line_total = line_total - currency_pool.compute(cr, uid, current_currency, company_currency, voucher.tax_amount, context=context)
+ elif voucher.type == 'purchase':
+ line_total = line_total + currency_pool.compute(cr, uid, current_currency, company_currency, voucher.tax_amount, context=context)
+ #create one move line per voucher line where amount is not 0.0
+ line_total, rec_list_ids = self.voucher_move_line_create(cr, uid, voucher.id, line_total, move_id, company_currency, current_currency, context)
- for line in inv.line_ids:
- #create one move line per voucher line where amount is not 0.0
- if not line.amount:
- continue
- #we check if the voucher line is fully paid or not and create a move line to balance the payment and initial invoice if needed
- if line.amount == line.amount_unreconciled:
- amount = currency_pool.compute(cr, uid, current_currency, company_currency, line.untax_amount or line.amount, context=context_multi_currency)
- amount_residual = line.move_line_id.amount_residual - amount #residual amount in company currency
- else:
- amount = currency_pool.compute(cr, uid, current_currency, company_currency, line.untax_amount or line.amount, context=context_multi_currency)
- amount_residual = 0.0
- move_line = {
- 'journal_id': inv.journal_id.id,
- 'period_id': inv.period_id.id,
- 'name': line.name or '/',
- 'account_id': line.account_id.id,
- 'move_id': move_id,
- 'partner_id': inv.partner_id.id,
- 'currency_id': company_currency <> current_currency and current_currency or False,
- 'analytic_account_id': line.account_analytic_id and line.account_analytic_id.id or False,
- 'quantity': 1,
- 'credit': 0.0,
- 'debit': 0.0,
- 'date': inv.date
- }
- if amount < 0:
- amount = -amount
- if line.type == 'dr':
- line.type = 'cr'
- else:
- line.type = 'dr'
- if (line.type=='dr'):
- line_total += amount
- move_line['debit'] = amount
- else:
- line_total -= amount
- move_line['credit'] = amount
-
- if inv.tax_id and inv.type in ('sale', 'purchase'):
- move_line.update({
- 'account_tax_id': inv.tax_id.id,
- })
- if move_line.get('account_tax_id', False):
- tax_data = tax_obj.browse(cr, uid, [move_line['account_tax_id']], context=context)[0]
- if not (tax_data.base_code_id and tax_data.tax_code_id):
- raise osv.except_osv(_('No Account Base Code and Account Tax Code!'),_("You have to configure account base code and account tax code on the '%s' tax!") % (tax_data.name))
- sign = (move_line['debit'] - move_line['credit']) < 0 and -1 or 1
- move_line['amount_currency'] = company_currency <> current_currency and sign * line.amount or False
- voucher_line = move_line_pool.create(cr, uid, move_line)
- rec_ids = [voucher_line, line.move_line_id.id]
-
- # Change difference entry
- if amount_residual:
- if not inv.exchange_acc_id.id:
- raise osv.except_osv(_('Error!'), _('You must provide an account for the exchange difference.'))
- move_line = {
- 'journal_id': inv.journal_id.id,
- 'period_id': inv.period_id.id,
- 'name': _('change')+': '+(line.name or '/'),
- 'account_id': line.account_id.id,
- 'move_id': move_id,
- 'partner_id': inv.partner_id.id,
- 'currency_id': company_currency <> current_currency and current_currency or False,
- 'amount_currency': 0.0,
- 'quantity': 1,
- 'credit': amount_residual > 0 and amount_residual or 0.0,
- 'debit': amount_residual < 0 and -amount_residual or 0.0,
- 'date': inv.date
- }
- new_id = move_line_pool.create(cr, uid, move_line)
- move_line = {
- 'journal_id': inv.journal_id.id,
- 'period_id': inv.period_id.id,
- 'name': _('change')+': '+(line.name or '/'),
- 'account_id': inv.exchange_acc_id.id,
- 'move_id': move_id,
- 'amount_currency': 0.0,
- 'partner_id': inv.partner_id.id,
- 'currency_id': company_currency <> current_currency and current_currency or False,
- 'quantity': 1,
- 'debit': amount_residual > 0 and amount_residual or 0.0,
- 'credit': amount_residual < 0 and -amount_residual or 0.0,
- 'date': inv.date
- }
- move_line_pool.create(cr, uid, move_line)
- rec_ids.append(new_id)
-
- if line.move_line_id.id:
- rec_list_ids.append(rec_ids)
-
- if not currency_pool.is_zero(cr, uid, current_currency_obj, line_total):
- diff = line_total
- account_id = False
- write_off_name = ''
- if inv.payment_option == 'with_writeoff':
- account_id = inv.writeoff_acc_id.id
- write_off_name = inv.comment
- elif inv.type in ('sale', 'receipt'):
- account_id = inv.partner_id.property_account_receivable.id
- else:
- account_id = inv.partner_id.property_account_payable.id
- move_line = {
- 'name': write_off_name or name,
- 'account_id': account_id,
- 'move_id': move_id,
- 'partner_id': inv.partner_id.id,
- 'date': inv.date,
- 'credit': diff > 0 and diff or 0.0,
- 'debit': diff < 0 and -diff or 0.0,
- 'amount_currency': company_currency <> current_currency and inv.writeoff_amount or False,
- 'currency_id': company_currency <> current_currency and current_currency or False,
- }
- move_line_pool.create(cr, uid, move_line)
- self.write(cr, uid, [inv.id], {
+ #create the writeoff line if needed
+ ml_writeoff = self.writeoff_move_line_get(cr, uid, voucher.id, line_total, move_id, name, company_currency, current_currency, context)
+ if ml_writeoff:
+ ml_writeoff_id = move_line_pool.create(cr, uid, ml_writeoff, context)
+ #We post the voucher.
+ self.write(cr, uid, [voucher.id], {
'move_id': move_id,
'state': 'posted',
'number': name,
})
- if inv.journal_id.entry_posted:
+ if voucher.journal_id.entry_posted:
move_pool.post(cr, uid, [move_id], context={})
+ #We automatically reconcile the account move lines.
for rec_ids in rec_list_ids:
if len(rec_ids) >= 2:
- move_line_pool.reconcile_partial(cr, uid, rec_ids, writeoff_acc_id=inv.exchange_acc_id.id, writeoff_period_id=inv.period_id.id, writeoff_journal_id=inv.journal_id.id)
+ move_line_pool.reconcile_partial(cr, uid, rec_ids, writeoff_acc_id=voucher.exchange_acc_id.id, writeoff_period_id=voucher.period_id.id, writeoff_journal_id=voucher.journal_id.id)
return True
def copy(self, cr, uid, id, default={}, context=None):
diff --git a/addons/account_voucher/test/case1_usd_usd.yml b/addons/account_voucher/test/case1_usd_usd.yml
new file mode 100644
index 00000000000..eabcec2a08c
--- /dev/null
+++ b/addons/account_voucher/test/case1_usd_usd.yml
@@ -0,0 +1,344 @@
+-
+ In order to check the Account_voucher module with multi-currency in OpenERP,
+ I create 2 Invoices in USD and make 2 Payments in USD based on the currency rating on that particular date
+-
+ I create currency USD in OpenERP for January of 1.333333 Rate
+-
+ !python {model: res.currency.rate}: |
+ from datetime import datetime
+ curr_id = self.pool.get('res.currency').search(cr, uid, [('name', '=', 'USD')])[0]
+ date = '%s-01-01' %(datetime.now().year)
+ ids = self.search(cr, uid, [('currency_id','=',curr_id), ('name', '=', date)])
+ self.write(cr, uid, ids, {'rate': 1.333333})
+-
+ I create currency USD in OpenERP for February of 1.250000 Rate
+-
+ !record {model: res.currency.rate, id: feb_usd}:
+ currency_id: base.USD
+ name: !eval "'%s-02-01' %(datetime.now().year)"
+ rate: 1.250000
+
+-
+ I create currency USD in OpenERP for March of 1.111111 Rate
+-
+ !record {model: res.currency.rate, id: mar_usd}:
+ currency_id: base.USD
+ name: !eval "'%s-03-01' %(datetime.now().year)"
+ rate: 1.111111
+
+-
+ I create currency USD in OpenERP for April of 1.052632 Rate
+-
+ !record {model: res.currency.rate, id: apr_usd}:
+ currency_id: base.USD
+ name: !eval "'%s-04-01' %(datetime.now().year)"
+ rate: 1.052632
+
+-
+ I create a bank journal with USD as currency
+-
+ !record {model: account.journal, id: bank_journal_USD}:
+ name: Bank Journal(USD)
+ code: BUSD
+ type: bank
+ analytic_journal_id: account.sit
+ sequence_id: account.sequence_bank_journal
+ default_debit_account_id: account.cash
+ default_credit_account_id: account.cash
+ currency: base.USD
+ company_id: base.main_company
+ view_id: account.account_journal_bank_view
+
+-
+ I create new partner Mark Strauss.
+-
+ !record {model: res.partner, id: res_partner_strauss0}:
+ address:
+ - city: paris
+ country_id: base.fr
+ name: Mark Strauss
+ street: 1 rue Rockfeller
+ type: invoice
+ zip: '75016'
+ name: Mr. Mark Strauss
+-
+ I create the first invoice on 1st January for 200 USD
+-
+ !record {model: account.invoice, id: account_invoice_jan}:
+ account_id: account.a_recv
+ address_contact_id: base.res_partner_address_3000
+ address_invoice_id: base.res_partner_address_3000
+ company_id: base.main_company
+ currency_id: base.USD
+ date_invoice: !eval "'%s-01-01' %(datetime.now().year)"
+ period_id: account.period_1
+ invoice_line:
+ - account_id: account.a_sale
+ name: '[PC1] Basic PC'
+ price_unit: 200.0
+ quantity: 1.0
+ product_id: product.product_product_pc1
+ uos_id: product.product_uom_unit
+ journal_id: account.sales_journal
+ partner_id: res_partner_strauss0
+ reference_type: none
+-
+ I Validate invoice by clicking on Validate button
+-
+ !workflow {model: account.invoice, action: invoice_open, ref: account_invoice_jan}
+-
+ I check that first invoice move is correct for debtor account (debit - credit == 150.0)
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_invoice_jan"))
+ assert invoice_id.move_id, "Move not created for open invoice"
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.debit - move_line.credit == 150.0), "Invoice move is not correct for debtors account"
+-
+ I create the second invoice on 1st February for 100 USD
+-
+ !record {model: account.invoice, id: account_invoice_feb}:
+ account_id: account.a_recv
+ address_contact_id: base.res_partner_address_3000
+ address_invoice_id: base.res_partner_address_3000
+ company_id: base.main_company
+ currency_id: base.USD
+ date_invoice: !eval "'%s-02-01' %(datetime.now().year)"
+ period_id: account.period_2
+ invoice_line:
+ - account_id: account.a_sale
+ name: '[PC1] Basic PC'
+ price_unit: 100.0
+ quantity: 1.0
+ product_id: product.product_product_pc1
+ uos_id: product.product_uom_unit
+ journal_id: account.sales_journal
+ partner_id: res_partner_strauss0
+ reference_type: none
+-
+ I Validate invoice by clicking on Validate button
+-
+ !workflow {model: account.invoice, action: invoice_open, ref: account_invoice_feb}
+-
+ I check that second invoice move is correct for debtor account (debit - credit == 80)
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_invoice_feb"))
+ assert invoice_id.move_id, "Move not created for open invoice"
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.debit - move_line.credit == 80), "Invoice move is not correct for debtors account"
+
+-
+ I create the first voucher of payment
+
+-
+ !python {model: account.voucher}: |
+ import netsvc, time
+ vals = {}
+ res = self.onchange_partner_id(cr, uid, [], ref("res_partner_strauss0"), ref('bank_journal_USD'), 240.00, 2, ttype='receipt', date=False)
+ vals = {
+ 'account_id': ref('account.cash'),
+ 'amount': 240.00,
+ 'company_id': ref('base.main_company'),
+ 'currency_id': ref('base.USD'),
+ 'journal_id': ref('bank_journal_USD'),
+ 'partner_id': ref('res_partner_strauss0'),
+ 'period_id': ref('account.period_3'),
+ 'type': 'receipt',
+ 'date': time.strftime("%Y-03-01"),
+ 'payment_option': 'with_writeoff',
+ 'writeoff_acc_id': ref('account.a_expense'),
+ 'comment': 'Write Off',
+ 'name': 'First payment',
+ }
+ if not res['value']['line_cr_ids']:
+ res['value']['line_cr_ids'] = [{'type': 'cr', 'account_id': ref('account.a_recv'),}]
+ for item in res['value']['line_cr_ids']:
+ if item['amount_unreconciled'] == 200.00:
+ item['amount'] = 180.00
+ else:
+ item['amount'] = 70.00
+ vals['line_cr_ids'] = [(0,0,i) for i in res['value']['line_cr_ids']]
+ id = self.create(cr, uid, vals)
+ voucher_id = self.browse(cr, uid, id)
+ assert (voucher_id.state=='draft'), "Voucher is not in draft state"
+-
+ I check that writeoff amount computed is 10.0
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'First payment'), ('partner_id', '=', ref('res_partner_strauss0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ assert (voucher_id.writeoff_amount == 10.0), "Writeoff amount is not 10.0"
+-
+ I confirm the voucher
+-
+ !python {model: account.voucher}: |
+ import netsvc
+ voucher = self.search(cr, uid, [('name', '=', 'First payment'), ('partner_id', '=', ref('res_partner_strauss0'))])
+ wf_service = netsvc.LocalService("workflow")
+ wf_service.trg_validate(uid, 'account.voucher', voucher[0], 'proforma_voucher', cr)
+-
+ I check that the move of my first voucher is valid
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'First payment'), ('partner_id', '=', ref('res_partner_strauss0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', voucher_id.move_id.id)])
+ for move_line in move_line_obj.browse(cr, uid, move_lines):
+ assert move_line.state == 'valid', "Voucher move is not valid"
+-
+ I check that my debtor account is correct
+-
+ I check that the debtor account has 2 new lines with -180 and -70 as amount_currency columns and that their credit columns are respectively 162 and 63
+-
+ I check that my write-off is correct. 9 debit and 10 amount_currency
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'First payment'), ('partner_id', '=', ref('res_partner_strauss0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', voucher_id.move_id.id)])
+ for move_line in move_line_obj.browse(cr, uid, move_lines):
+ if move_line.amount_currency == -180.00:
+ assert move_line.credit == 162.00, "Debtor account has wrong entry."
+ elif move_line.amount_currency == -70.00:
+ assert move_line.credit == 63.00, "Debtor account has wrong entry."
+ elif move_line.amount_currency == 10.00:
+ assert move_line.debit == 9.00, "Writeoff amount is wrong."
+-
+ I check the residual amount of Invoice1, should be 20 in amount_currency
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_invoice_jan"))
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('invoice', '=', invoice_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.amount_residual_currency == 20.0) , "Residual amount is not correct for first Invoice"
+-
+ I check the residual amuont of Invoice2, should be 30 in residual currency and 24 in amount_residual
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_invoice_feb"))
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('invoice', '=', invoice_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.amount_residual_currency == 30.0) , "Residual amount is not correct for first Invoice"
+-
+ I create the second voucher of payment
+
+
+-
+ !python {model: account.voucher}: |
+ import netsvc, time
+ vals = {}
+ res = self.onchange_partner_id(cr, uid, [], ref("res_partner_strauss0"), ref('bank_journal_USD'), 45.00, 2, ttype='receipt', date=False)
+ vals = {
+ 'account_id': ref('account.cash'),
+ 'amount': 45.00,
+ 'exchange_acc_id': ref('account.o_expense'),
+ 'company_id': ref('base.main_company'),
+ 'currency_id': ref('base.USD'),
+ 'journal_id': ref('bank_journal_USD'),
+ 'partner_id': ref('res_partner_strauss0'),
+ 'period_id': ref('account.period_3'),
+ 'type': 'receipt',
+ 'date': time.strftime("%Y-04-01"),
+ 'payment_option': 'with_writeoff',
+ 'writeoff_acc_id': ref('account.a_expense'),
+ 'comment': 'Write Off',
+ 'name': 'Second payment',
+ }
+ if not res['value']['line_cr_ids']:
+ res['value']['line_cr_ids'] = [{'type': 'cr', 'account_id': ref('account.a_recv'),}]
+ for item in res['value']['line_cr_ids']:
+ if item['amount_unreconciled'] == 20.00:
+ item['amount'] = 20.00
+ else:
+ item['amount'] = 30.00
+ vals['line_cr_ids'] = [(0,0,i) for i in res['value']['line_cr_ids']]
+ id = self.create(cr, uid, vals)
+ voucher_id = self.browse(cr, uid, id)
+ assert (voucher_id.state=='draft'), "Voucher is not in draft state"
+-
+ I check that writeoff amount computed is 5.0
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'Second payment'), ('partner_id', '=', ref('res_partner_strauss0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ assert (voucher_id.writeoff_amount == 5.0), "Writeoff amount is not 5.0"
+-
+ I confirm the voucher
+-
+ !python {model: account.voucher}: |
+ import netsvc
+ voucher = self.search(cr, uid, [('name', '=', 'Second payment'), ('partner_id', '=', ref('res_partner_strauss0'))])
+ wf_service = netsvc.LocalService("workflow")
+ wf_service.trg_validate(uid, 'account.voucher', voucher[0], 'proforma_voucher', cr)
+-
+ I check that the move of my second voucher is valid
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'Second payment'), ('partner_id', '=', ref('res_partner_strauss0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', voucher_id.move_id.id)])
+ for move_line in move_line_obj.browse(cr, uid, move_lines):
+ assert move_line.state == 'valid', "Voucher move is not valid"
+-
+ I check that my debtor account is correct
+-
+ I check that the debtor account has 2 new lines with -20 and -30 as amount_currency columns and their credit columns are respectively 19 and 28.5
+-
+ I check that my currency rate difference is correct. 8.5 in credit with no amount_currency
+-
+ I check that the total reconcilation created entries as expected
+-
+ I check that my writeoff is correct. 4.75 debit and 5 amount_currency
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'Second payment'), ('partner_id', '=', ref('res_partner_strauss0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', voucher_id.move_id.id)])
+ reconcile_a = reconcile_b = False
+ for move_line in move_line_obj.browse(cr, uid, move_lines):
+ if move_line.amount_currency == -20.00:
+ assert move_line.reconcile_id.id, "The invoice of 200$ is not fully reconciled"
+ reconcile_b = move_line.reconcile_id.id
+ elif move_line.amount_currency == -30.00:
+ assert move_line.reconcile_id.id, "The invoice of 100$ is not fully reconciled"
+ reconcile_a = move_line.reconcile_id.id
+ for move_line in move_line_obj.browse(cr, uid, move_lines):
+ if move_line.amount_currency == -20.00:
+ assert move_line.credit == 19.00, "Debtor account has wrong entry."
+ elif move_line.amount_currency == -30.00:
+ assert move_line.credit == 28.50, "Debtor account has wrong entry."
+ elif move_line.amount_currency == 5.00:
+ assert move_line.debit == 4.75, "Writeoff amount is wrong."
+ elif move_line.debit == 11.5 and move_line.account_id.reconcile:
+ assert move_line.amount_currency == 0.0 and move_line.reconcile_id.id == reconcile_a, "Exchange difference entry for the invoice of 100$ is wrong"
+ elif move_line.debit == 31.0 and move_line.account_id.reconcile:
+ assert move_line.amount_currency == 0.0 and move_line.reconcile_id.id == reconcile_b, "Exchange difference entry for the invoice of 200$ is wrong"
+-
+ I check the residual amount of Invoice1, should be 0 in residual currency and 0 in amount_residual and paid
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_invoice_jan"))
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('invoice', '=', invoice_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.amount_residual_currency == 0.0 and move_line.amount_residual == 0.0 and invoice_id.state == 'paid') , "Residual amount is not correct for first Invoice"
+-
+ I check the residual amuont of Invoice2, should be 0 in residual currency and 0 in amount_residual and paid
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_invoice_feb"))
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('invoice', '=', invoice_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.amount_residual_currency == 0.0 and move_line.amount_residual == 0.0 and invoice_id.state == 'paid') , "Residual amount is not correct for second Invoice"
diff --git a/addons/account_voucher/test/case2_suppl_usd_eur.yml b/addons/account_voucher/test/case2_suppl_usd_eur.yml
new file mode 100644
index 00000000000..31e756d5355
--- /dev/null
+++ b/addons/account_voucher/test/case2_suppl_usd_eur.yml
@@ -0,0 +1,328 @@
+-
+ In order to check the Account_voucher module with multi-currency in OpenERP,
+ I create 2 Invoices in USD and make 2 Payments one in USD and another in EUR, based on the currency rating on that particular date
+-
+ I create a bank journal with EUR as currency
+-
+ !record {model: account.journal, id: bank_journal_EUR}:
+ name: Bank Journal(EUR)
+ code: BEUR
+ type: bank
+ analytic_journal_id: account.sit
+ sequence_id: account.sequence_bank_journal
+ default_debit_account_id: account.cash
+ default_credit_account_id: account.cash
+ currency: base.EUR
+ company_id: base.main_company
+ view_id: account.account_journal_bank_view
+-
+ I create a bank journal with USD as currency
+-
+ !record {model: account.journal, id: bank_journal_USD}:
+ name: Bank Journal(USD)
+ code: BUSD
+ type: bank
+ analytic_journal_id: account.sit
+ sequence_id: account.sequence_bank_journal
+ default_debit_account_id: account.cash
+ default_credit_account_id: account.cash
+ currency: base.USD
+ company_id: base.main_company
+ view_id: account.account_journal_bank_view
+-
+ I create a new partner Robert Clements
+-
+ !record {model: res.partner, id: res_partner_clements0}:
+ address:
+ - city: marseille
+ country_id: base.fr
+ name: Robert
+ street: 1 rue Rockfeller
+ type: invoice
+ zip: '13016'
+ name: Mr.Robert Clements
+-
+ I create the first invoice on 1st January for 200 USD
+-
+ !record {model: account.invoice, id: account_first_invoice_jan_suppl}:
+ account_id: account.a_pay
+ type : in_invoice
+ address_contact_id: base.res_partner_address_3000
+ address_invoice_id: base.res_partner_address_3000
+ company_id: base.main_company
+ currency_id: base.USD
+ date_invoice: !eval "'%s-01-01' %(datetime.now().year)"
+ period_id: account.period_1
+ invoice_line:
+ - account_id: account.a_expense
+ name: '[PC1] Basic PC'
+ price_unit: 200.0
+ quantity: 1.0
+ product_id: product.product_product_pc1
+ uos_id: product.product_uom_unit
+ journal_id: account.sales_journal
+ partner_id: res_partner_clements0
+ reference_type: none
+ check_total : 200
+-
+ I Validate invoice by clicking on Validate button
+-
+ !workflow {model: account.invoice, action: invoice_open, ref: account_first_invoice_jan_suppl}
+-
+ I check that first invoice move is correct for debtor account(debit - credit == -150)
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_first_invoice_jan_suppl"))
+ assert invoice_id.move_id, "Move not created for open invoice"
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.debit - move_line.credit == -150.00), "Invoice move is incorrect for debtors account"
+-
+ I create the second invoice on 1st February for 100 USD
+-
+ !record {model: account.invoice, id: account_second_invoice_feb_suppl}:
+ account_id: account.a_pay
+ address_contact_id: base.res_partner_address_3000
+ address_invoice_id: base.res_partner_address_3000
+ company_id: base.main_company
+ currency_id: base.USD
+ date_invoice: !eval "'%s-02-01' %(datetime.now().year)"
+ period_id: account.period_2
+ type : in_invoice
+ invoice_line:
+ - account_id: account.a_expense
+ name: '[PC1] Basic PC'
+ price_unit: 100.0
+ quantity: 1.0
+ product_id: product.product_product_pc1
+ uos_id: product.product_uom_unit
+ journal_id: account.sales_journal
+ partner_id: res_partner_clements0
+ reference_type: none
+ check_total : 100.0
+-
+ I Validate invoice by clicking on Validate button
+-
+ !workflow {model: account.invoice, action: invoice_open, ref: account_second_invoice_feb_suppl}
+-
+ I check that second invoice move is correct for debtor account (debit - credit == -80)
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_second_invoice_feb_suppl"))
+ assert invoice_id.move_id, "Move not created for open invoice"
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.debit - move_line.credit == -80), "Invoice move is incorrect for debtors account"
+-
+ I create the first voucher of payment
+
+-
+ !python {model: account.voucher}: |
+ import netsvc, time
+ vals = {}
+ res = self.onchange_partner_id(cr, uid, [], ref("res_partner_clements0"), ref('bank_journal_EUR'), 240.0, 2, ttype='payment', date=False)
+ vals = {
+ 'account_id': ref('account.cash'),
+ 'amount': 240.0,
+ 'company_id': ref('base.main_company'),
+ 'currency_id': ref('base.EUR'),
+ 'journal_id': ref('bank_journal_EUR'),
+ 'partner_id': ref('res_partner_clements0'),
+ 'period_id': ref('account.period_3'),
+ 'type': 'payment',
+ 'date': time.strftime("%Y-03-01"),
+ 'payment_option': 'with_writeoff',
+ 'writeoff_acc_id': ref('account.a_expense'),
+ 'comment': 'Write Off',
+ 'name': 'First payment',
+ }
+ if not res['value']['line_dr_ids']:
+ res['value']['line_dr_ids'] = [{'type': 'dr', 'account_id': ref('account.a_pay'),}]
+ for item in res['value']['line_dr_ids']:
+ if item['amount_unreconciled'] == 200.00:
+ item['amount'] = 180.00
+ else:
+ item['amount'] = 70.00
+ vals['line_dr_ids'] = [(0,0,i) for i in res['value']['line_dr_ids']]
+ id = self.create(cr, uid, vals)
+ voucher_id = self.browse(cr, uid, id)
+ assert (voucher_id.state=='draft'), "Voucher is not in draft state"
+-
+ I check that writeoff amount computed is -15.0
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'First payment'), ('partner_id', '=', ref('res_partner_clements0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ assert (voucher_id.writeoff_amount == -15.0), "Writeoff amount is not -15.0"
+-
+ I check that currency rate difference is 34.0
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'First payment'), ('partner_id', '=', ref('res_partner_clements0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ assert (voucher_id.currency_rate_difference == 34.0), "Currency rate difference is not 34.0"
+-
+ I confirm the voucher
+-
+ !python {model: account.voucher}: |
+ import netsvc
+ voucher = self.search(cr, uid, [('name', '=', 'First payment'), ('partner_id', '=', ref('res_partner_clements0'))])
+ wf_service = netsvc.LocalService("workflow")
+ wf_service.trg_validate(uid, 'account.voucher', voucher[0], 'proforma_voucher', cr)
+-
+ I check that the move of my voucher is valid
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'First payment'), ('partner_id', '=', ref('res_partner_clements0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', voucher_id.move_id.id)])
+ for move_line in move_line_obj.browse(cr, uid, move_lines):
+ assert move_line.state == 'valid', "Voucher move is not valid"
+-
+ I check that my creditor account is correct
+-
+ I check that the creditor account has 2 new lines with 180 and 70 in amount_currency columns and their debit columns are respectively 135 and 56 and currency is USD($).
+-
+ I check that my currency rate difference is correct. -34 in credit with no amount_currency
+-
+ I check that my writeoff is correct. -15 in credit with no amount_currency
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'First payment'), ('partner_id', '=', ref('res_partner_clements0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', voucher_id.move_id.id)])
+ for move_line in move_line_obj.browse(cr, uid, move_lines):
+ if move_line.amount_currency == 180.00:
+ assert move_line.debit == 135.00, "Creditor account has wrong entry."
+ elif move_line.amount_currency == 70.00:
+ assert move_line.debit == 56.00, "Debtor account has wrong entry."
+ elif move_line.debit == 34.00:
+ assert move_line.amount_currency == 0.00, "Incorrect Currency Difference."
+ elif move_line.debit == 15.00:
+ assert move_line.amount_currency == 0.00, "Writeoff amount is wrong."
+-
+ I check the residual amount of Invoice1, should be 20 in residual currency and 15 in amount_residual
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_first_invoice_jan_suppl"))
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('invoice', '=', invoice_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.amount_residual_currency == 20.0 and move_line.amount_residual == 15) , "Residual amount is not correct for first Invoice"
+-
+ I check the residual amuont of Invoice2, should be 30 in residual currency and 24 in amount_residual
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_second_invoice_feb_suppl"))
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('invoice', '=', invoice_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.amount_residual_currency == 30 and move_line.amount_residual == 24) , "Residual amount is not correct for second Invoice"
+-
+ I create the second voucher of payment
+
+-
+ !python {model: account.voucher}: |
+ import netsvc, time
+ vals = {}
+ res = self.onchange_partner_id(cr, uid, [], ref("res_partner_clements0"), ref('bank_journal_EUR'), 45.0, 2, ttype='payment', date=False)
+ vals = {
+ 'account_id': ref('account.cash'),
+ 'amount': 45.0,
+ 'company_id': ref('base.main_company'),
+ 'currency_id': ref('base.USD'),
+ 'journal_id': ref('bank_journal_USD'),
+ 'partner_id': ref('res_partner_clements0'),
+ 'period_id': ref('account.period_3'),
+ 'type': 'payment',
+ 'date': time.strftime("%Y-04-01"),
+ 'payment_option': 'with_writeoff',
+ 'writeoff_acc_id': ref('account.a_expense'),
+ 'comment': 'Write Off',
+ 'name': 'Second payment',
+ }
+ if not res['value']['line_dr_ids']:
+ res['value']['line_dr_ids'] = [{'type': 'dr', 'account_id': ref('account.a_pay'),}]
+ for item in res['value']['line_dr_ids']:
+ if item['amount_unreconciled'] == 20.00:
+ item['amount'] = 20.00
+ else:
+ item['amount'] = 30.00
+ vals['line_dr_ids'] = [(0,0,i) for i in res['value']['line_dr_ids']]
+ id = self.create(cr, uid, vals)
+ voucher_id = self.browse(cr, uid, id)
+ assert (voucher_id.state=='draft'), "Voucher is not in draft state"
+-
+ I check that writeoff amount computed is -5.0
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'Second payment'), ('partner_id', '=', ref('res_partner_clements0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ assert (voucher_id.writeoff_amount == 5.0), "Writeoff amount is not 5.0"
+-
+ I check that currency rate difference is 8.50
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'Second payment'), ('partner_id', '=', ref('res_partner_clements0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ assert (voucher_id.currency_rate_difference == 8.50), "Currency rate difference is not 8.50"
+-
+ I confirm the voucher
+-
+ !python {model: account.voucher}: |
+ import netsvc
+ voucher = self.search(cr, uid, [('name', '=', 'Second payment'), ('partner_id', '=', ref('res_partner_clements0'))])
+ wf_service = netsvc.LocalService("workflow")
+ wf_service.trg_validate(uid, 'account.voucher', voucher[0], 'proforma_voucher', cr)
+-
+ I check that my voucher state is posted
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'Second payment'), ('partner_id', '=', ref('res_partner_clements0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ assert voucher_id.state == 'posted', "Voucher state is not posted"
+-
+ I check that my creditor account is correct
+-
+ I check that the creditor account has 2 new lines with 20 and 30 in amount_currency columns and their debit columns are respectively 15 and 24 and currency is USD($).
+-
+ I check that my currency rate difference is correct. 8.50 in debit with no amount_currency
+-
+ I check that my writeoff is correct. 4.75 in credit and 5 in amount_currency
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'Second payment'), ('partner_id', '=', ref('res_partner_clements0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', voucher_id.move_id.id)])
+ for move_line in move_line_obj.browse(cr, uid, move_lines):
+ if move_line.amount_currency == 20.00:
+ assert move_line.debit == 15.00, "Debtor account has wrong entry."
+ elif move_line.amount_currency == 30.00:
+ assert move_line.debit == 24.00, "Debtor account has wrong entry."
+ elif move_line.debit == 8.50:
+ assert move_line.amount_currency == 0.00, "Incorrect Currency Difference."
+ elif move_line.amount_currency == -5.00:
+ assert move_line.credit == 4.75, "Writeoff amount is wrong."
+-
+ I check the residual amount of invoice 1, should be 0 in residual currency and 0 in amount_residual and paid
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_first_invoice_jan_suppl"))
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('invoice', '=', invoice_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.amount_residual_currency == 0.0 and move_line.amount_residual == 0.0 and invoice_id.state == 'paid') , "Residual amount is not correct for first Invoice"
+-
+ I check the residual amount of invoice 2, should be 0 in residual currency and 0 in amount_residual and paid
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_second_invoice_feb_suppl"))
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('invoice', '=', invoice_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.amount_residual_currency == 0.0 and move_line.amount_residual == 0.0 and invoice_id.state == 'paid') , "Residual amount is not correct for second Invoice"
diff --git a/addons/account_voucher/test/case2_usd_eur_debtor_in_eur.yml b/addons/account_voucher/test/case2_usd_eur_debtor_in_eur.yml
new file mode 100644
index 00000000000..b872a54561d
--- /dev/null
+++ b/addons/account_voucher/test/case2_usd_eur_debtor_in_eur.yml
@@ -0,0 +1,340 @@
+-
+ In order to check the Account_voucher module with multi-currency in OpenERP,
+ I create 2 Invoices in USD and make 2 Payments one in USD and another in EUR, based on the currency rating on that particular date
+-
+ I modify the debtor account in order to make sure there is no currency_id linked
+-
+ !python {model: account.account}: |
+ from datetime import datetime
+ ids = self.search(cr, uid, [('name', 'ilike', 'debtor')])
+ self.write(cr, uid, ids, {'currency_id': False})
+-
+ I create currency USD in OpenERP for January of 1.333333 Rate
+-
+ !python {model: res.currency.rate}: |
+ from datetime import datetime
+ curr_id = self.pool.get('res.currency').search(cr, uid, [('name', '=', 'USD')])[0]
+ date = '%s-01-01' %(datetime.now().year)
+ ids = self.search(cr, uid, [('currency_id', '=', curr_id), ('name', '=', date)])
+ self.write(cr, uid, ids, {'rate': 1.333333})
+-
+ I create currency USD in OpenERP for February of 1.250000 Rate
+-
+ !record {model: res.currency.rate, id: febr_usd}:
+ currency_id: base.USD
+ name: !eval "'%s-02-01' %(datetime.now().year)"
+ rate: 1.250000
+-
+ I create currency USD in OpenERP for March of 1.111111 Rate
+-
+ !record {model: res.currency.rate, id: marc_usd}:
+ currency_id: base.USD
+ name: !eval "'%s-03-01' %(datetime.now().year)"
+ rate: 1.111111
+-
+ I create currency USD in OpenERP for April of 1.052632 Rate
+-
+ !record {model: res.currency.rate, id: apri_usd}:
+ currency_id: base.USD
+ name: !eval "'%s-04-01' %(datetime.now().year)"
+ rate: 1.052632
+-
+ I create a bank journal with EUR as currency
+-
+ !record {model: account.journal, id: bank_journal_EUR}:
+ name: Bank Journal(EUR)
+ code: BEUR
+ type: bank
+ analytic_journal_id: account.sit
+ sequence_id: account.sequence_bank_journal
+ default_debit_account_id: account.cash
+ default_credit_account_id: account.cash
+ currency: base.EUR
+ company_id: base.main_company
+ view_id: account.account_journal_bank_view
+-
+ I create a bank journal with USD as currency
+-
+ !record {model: account.journal, id: bank_journal_USD}:
+ name: Bank Journal(USD)
+ code: BUSD
+ type: bank
+ analytic_journal_id: account.sit
+ sequence_id: account.sequence_bank_journal
+ default_debit_account_id: account.cash
+ default_credit_account_id: account.cash
+ currency: base.USD
+ company_id: base.main_company
+ view_id: account.account_journal_bank_view
+-
+ I create a new partner Michael Geller
+-
+ !record {model: res.partner, id: res_partner_michael0}:
+ address:
+ - city: paris
+ country_id: base.fr
+ name: Michael
+ street: 1 rue Rockfeller
+ type: invoice
+ zip: '75016'
+ name: Mr.Michael Geller
+-
+ I create the first invoice on 1st January for 200 USD
+-
+ !record {model: account.invoice, id: account_first_invoice_jan}:
+ account_id: account.a_recv
+ address_contact_id: base.res_partner_address_3000
+ address_invoice_id: base.res_partner_address_3000
+ company_id: base.main_company
+ currency_id: base.USD
+ date_invoice: !eval "'%s-01-01' %(datetime.now().year)"
+ period_id: account.period_1
+ invoice_line:
+ - account_id: account.a_sale
+ name: '[PC1] Basic PC'
+ price_unit: 200.0
+ quantity: 1.0
+ product_id: product.product_product_pc1
+ uos_id: product.product_uom_unit
+ journal_id: account.sales_journal
+ partner_id: res_partner_michael0
+ reference_type: none
+-
+ I Validate invoice by clicking on Validate button
+-
+ !workflow {model: account.invoice, action: invoice_open, ref: account_first_invoice_jan}
+-
+ I check that first invoice move is correct for debtor account(debit - credit == 150)
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_first_invoice_jan"))
+ assert invoice_id.move_id, "Move not created for open invoice"
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.debit - move_line.credit == 150.00), "Invoice move is incorrect for debtors account"
+-
+ I create the second invoice on 1st February for 100 USD
+-
+ !record {model: account.invoice, id: account_second_invoice_feb}:
+ account_id: account.a_recv
+ address_contact_id: base.res_partner_address_3000
+ address_invoice_id: base.res_partner_address_3000
+ company_id: base.main_company
+ currency_id: base.USD
+ date_invoice: !eval "'%s-02-01' %(datetime.now().year)"
+ period_id: account.period_2
+ invoice_line:
+ - account_id: account.a_sale
+ name: '[PC1] Basic PC'
+ price_unit: 100.0
+ quantity: 1.0
+ product_id: product.product_product_pc1
+ uos_id: product.product_uom_unit
+ journal_id: account.sales_journal
+ partner_id: res_partner_michael0
+ reference_type: none
+-
+ I Validate invoice by clicking on Validate button
+-
+ !workflow {model: account.invoice, action: invoice_open, ref: account_second_invoice_feb}
+-
+ I check that second invoice move is correct for debtor account (debit - credit == 80)
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_second_invoice_feb"))
+ assert invoice_id.move_id, "Move not created for open invoice"
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.debit - move_line.credit == 80), "Invoice move is incorrect for debtors account"
+-
+ I create the first voucher of payment
+
+-
+ !python {model: account.voucher}: |
+ import netsvc, time
+ vals = {}
+ res = self.onchange_partner_id(cr, uid, [], ref("res_partner_michael0"), ref('bank_journal_EUR'), 240.0, 2, ttype='receipt', date=False)
+ vals = {
+ 'account_id': ref('account.cash'),
+ 'amount': 200.0,
+ 'company_id': ref('base.main_company'),
+ 'currency_id': ref('base.EUR'),
+ 'journal_id': ref('bank_journal_EUR'),
+ 'partner_id': ref('res_partner_michael0'),
+ 'period_id': ref('account.period_3'),
+ 'type': 'receipt',
+ 'date': time.strftime("%Y-03-01"),
+ 'payment_option': 'with_writeoff',
+ 'writeoff_acc_id': ref('account.a_expense'),
+ 'comment': 'Write Off',
+ 'name': 'First payment',
+ }
+ if not res['value']['line_cr_ids']:
+ res['value']['line_cr_ids'] = [{'type': 'cr', 'account_id': ref('account.a_recv'),}]
+ for item in res['value']['line_cr_ids']:
+ if item['amount_unreconciled'] == 150.00:
+ item['amount'] = 130.00
+ else:
+ item['amount'] = 70.00
+ vals['line_cr_ids'] = [(0,0,i) for i in res['value']['line_cr_ids']]
+ id = self.create(cr, uid, vals)
+ voucher_id = self.browse(cr, uid, id)
+ assert (voucher_id.state=='draft'), "Voucher is not in draft state"
+-
+ I confirm the voucher
+-
+ !python {model: account.voucher}: |
+ import netsvc
+ voucher = self.search(cr, uid, [('name', '=', 'First payment'), ('partner_id', '=', ref('res_partner_michael0'))])
+ wf_service = netsvc.LocalService("workflow")
+ wf_service.trg_validate(uid, 'account.voucher', voucher[0], 'proforma_voucher', cr)
+-
+ I check that the move of my voucher is valid
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'First payment'), ('partner_id', '=', ref('res_partner_michael0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', voucher_id.move_id.id)])
+ for move_line in move_line_obj.browse(cr, uid, move_lines):
+ assert move_line.state == 'valid', "Voucher move is not valid"
+-
+ I check that my debtor account is correct
+-
+ I check that the debtor account has 2 new lines with 0 in amount_currency columns and their credit columns are 130 and 70
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'First payment'), ('partner_id', '=', ref('res_partner_michael0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', voucher_id.move_id.id)])
+ for move_line in move_line_obj.browse(cr, uid, move_lines):
+ assert move_line.amount_currency == 0.00, "A line has the 'amount_currency' column filled"
+-
+ I check the residual amount of Invoice1, should be 55.56 in residual currency and 20 in amount_residual
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_first_invoice_jan"))
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('invoice', '=', invoice_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.amount_residual_currency == 55.56 and move_line.amount_residual == 20) , "Residual amount is not correct for first Invoice"
+- toto
+ I check the residual amuont of Invoice2, should be 22.22 in residual currency and 10 in amount_residual
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_second_invoice_feb"))
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('invoice', '=', invoice_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.amount_residual_currency == 22.22 and move_line.amount_residual == 10) , "Residual amount is not correct for second Invoice"
+-
+ I create the second voucher of payment
+
+-
+ !python {model: account.voucher}: |
+ import netsvc, time
+ vals = {}
+ res = self.onchange_partner_id(cr, uid, [], ref("res_partner_michael0"), ref('bank_journal_USD'), 80.0, 2, ttype='receipt', date=False)
+ vals = {
+ 'account_id': ref('account.cash'),
+ 'amount': 80.0,
+ 'company_id': ref('base.main_company'),
+ 'currency_id': ref('base.USD'),
+ 'journal_id': ref('bank_journal_USD'),
+ 'partner_id': ref('res_partner_michael0'),
+ 'period_id': ref('account.period_3'),
+ 'type': 'receipt',
+ 'date': time.strftime("%Y-04-01"),
+ 'payment_option': 'with_writeoff',
+ 'writeoff_acc_id': ref('account.a_expense'),
+ 'exchange_acc_id': ref('account.o_expense'),
+ 'comment': 'Write Off',
+ 'name': 'Second payment',
+ }
+ if not res['value']['line_cr_ids']:
+ res['value']['line_cr_ids'] = [{'type': 'cr', 'account_id': ref('account.a_recv'),}]
+ for item in res['value']['line_cr_ids']:
+ if item['amount_unreconciled'] == 55.56:
+ item['amount'] = 55.56
+ else:
+ item['amount'] = 22.22
+ vals['line_cr_ids'] = [(0,0,i) for i in res['value']['line_cr_ids']]
+ id = self.create(cr, uid, vals)
+ voucher_id = self.browse(cr, uid, id)
+ assert (voucher_id.state=='draft'), "Voucher is not in draft state"
+-
+ I check that writeoff amount computed is 2.22
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'Second payment'), ('partner_id', '=', ref('res_partner_michael0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ assert (round(voucher_id.writeoff_amount, 2) == 2.22), "Writeoff amount is not 2.22$"
+-
+ I confirm the voucher
+-
+ !python {model: account.voucher}: |
+ import netsvc
+ voucher = self.search(cr, uid, [('name', '=', 'Second payment'), ('partner_id', '=', ref('res_partner_michael0'))])
+ wf_service = netsvc.LocalService("workflow")
+ wf_service.trg_validate(uid, 'account.voucher', voucher[0], 'proforma_voucher', cr)
+-
+ I check that my voucher state is posted
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'Second payment'), ('partner_id', '=', ref('res_partner_michael0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ assert voucher_id.state == 'posted', "Voucher state is not posted"
+-
+ I check that my debtor account is correct
+-
+ I check that the debtor account has 2 new lines with -55.56 and -22.22 in amount_currency columns and their credit columns are respectively 52.78 and 21.11 and currency is USD($).
+-
+ I check that my currency rate difference is correct.
+-
+ I check that my writeoff is correct. 2.11 in credit and 2.22 in amount_currency
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'Second payment'), ('partner_id', '=', ref('res_partner_michael0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', voucher_id.move_id.id)])
+ reconcile_a = reconcile_b = False
+ for move_line in move_line_obj.browse(cr, uid, move_lines):
+ if move_line.amount_currency == -22.22:
+ assert move_line.reconcile_id.id, "The invoice of 200$ is not fully reconciled"
+ reconcile_b = move_line.reconcile_id.id
+ elif move_line.amount_currency == -55.56:
+ assert move_line.reconcile_id.id, "The invoice of 100$ is not fully reconciled"
+ reconcile_a = move_line.reconcile_id.id
+ for move_line in move_line_obj.browse(cr, uid, move_lines):
+ if move_line.amount_currency == -55.56:
+ assert move_line.credit == 52.78, "Debtor account has wrong entry."
+ elif move_line.amount_currency == -22.22:
+ assert move_line.credit == 21.11, "Debtor account has wrong entry."
+ elif move_line.credit == 11.11 and move_line.account_id.reconcile:
+ assert move_line.amount_currency == 0.00 and move_line.reconcile_id.id == reconcile_b, "Incorrect Currency Difference."
+ elif move_line.credit == 32.78 and move_line.account_id.reconcile:
+ assert move_line.amount_currency == 0.00 and move_line.reconcile_id.id == reconcile_a, "Incorrect Currency Difference."
+ elif move_line.amount_currency == 2.22:
+ assert move_line.credit == 2.11, "Writeoff amount is wrong."
+-
+ I check the residual amount of invoice 1, should be 0 in residual currency and 0 in amount_residual and paid
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_first_invoice_jan"))
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('invoice', '=', invoice_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.amount_residual_currency == 0.0 and move_line.amount_residual == 0.0 and invoice_id.state == 'paid') , "Residual amount is not correct for first Invoice"
+-
+ I check the residual amuont of invoice 2, should be 0 in residual currency and 0 in amount_residual and paid
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_second_invoice_feb"))
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('invoice', '=', invoice_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.amount_residual_currency == 0.0 and move_line.amount_residual == 0.0 and invoice_id.state == 'paid') , "Residual amount is not correct for second Invoice"
diff --git a/addons/account_voucher/test/case2_usd_eur_debtor_in_usd.yml b/addons/account_voucher/test/case2_usd_eur_debtor_in_usd.yml
new file mode 100644
index 00000000000..8fc495d79c8
--- /dev/null
+++ b/addons/account_voucher/test/case2_usd_eur_debtor_in_usd.yml
@@ -0,0 +1,343 @@
+-
+ In order to check the Account_voucher module with multi-currency in OpenERP,
+ I create 2 Invoices in USD and make 2 Payments one in USD and another in EUR, based on the currency rating on that particular date
+-
+ I modify the debtor account in order to set the currency_id = USD
+-
+ !python {model: account.account}: |
+ from datetime import datetime
+ ids = self.search(cr, uid, [('name', 'ilike', 'debtor')])
+ self.write(cr, uid, ids, {'currency_id': ref('base.USD')})
+-
+ I create currency USD in OpenERP for January of 1.333333 Rate
+-
+ !python {model: res.currency.rate}: |
+ from datetime import datetime
+ curr_id = self.pool.get('res.currency').search(cr, uid, [('name', '=', 'USD')])[0]
+ date = '%s-01-01' %(datetime.now().year)
+ ids = self.search(cr, uid, [('currency_id', '=', curr_id), ('name', '=', date)])
+ self.write(cr, uid, ids, {'rate': 1.333333})
+-
+ I create currency USD in OpenERP for February of 1.250000 Rate
+-
+ !record {model: res.currency.rate, id: febr_usd}:
+ currency_id: base.USD
+ name: !eval "'%s-02-01' %(datetime.now().year)"
+ rate: 1.250000
+-
+ I create currency USD in OpenERP for March of 1.111111 Rate
+-
+ !record {model: res.currency.rate, id: marc_usd}:
+ currency_id: base.USD
+ name: !eval "'%s-03-01' %(datetime.now().year)"
+ rate: 1.111111
+-
+ I create currency USD in OpenERP for April of 1.052632 Rate
+-
+ !record {model: res.currency.rate, id: apri_usd}:
+ currency_id: base.USD
+ name: !eval "'%s-04-01' %(datetime.now().year)"
+ rate: 1.052632
+-
+ I create a bank journal with EUR as currency
+-
+ !record {model: account.journal, id: bank_journal_EUR}:
+ name: Bank Journal(EUR)
+ code: BEUR
+ type: bank
+ analytic_journal_id: account.sit
+ sequence_id: account.sequence_bank_journal
+ default_debit_account_id: account.cash
+ default_credit_account_id: account.cash
+ currency: base.EUR
+ company_id: base.main_company
+ view_id: account.account_journal_bank_view
+-
+ I create a bank journal with USD as currency
+-
+ !record {model: account.journal, id: bank_journal_USD}:
+ name: Bank Journal(USD)
+ code: BUSD
+ type: bank
+ analytic_journal_id: account.sit
+ sequence_id: account.sequence_bank_journal
+ default_debit_account_id: account.cash
+ default_credit_account_id: account.cash
+ currency: base.USD
+ company_id: base.main_company
+ view_id: account.account_journal_bank_view
+-
+ I create a new partner Michal Gallette
+-
+ !record {model: res.partner, id: res_partner_michal1}:
+ address:
+ - city: paris
+ country_id: base.fr
+ name: Michal
+ street: 1 rue Rockfeller
+ type: invoice
+ zip: '75016'
+ name: Mr.Michal Gallette
+-
+ I create the first invoice on 1st January for 200 USD
+-
+ !record {model: account.invoice, id: account_first_invoice_jan_michal}:
+ account_id: account.a_recv
+ address_contact_id: base.res_partner_address_3000
+ address_invoice_id: base.res_partner_address_3000
+ company_id: base.main_company
+ currency_id: base.USD
+ date_invoice: !eval "'%s-01-01' %(datetime.now().year)"
+ period_id: account.period_1
+ invoice_line:
+ - account_id: account.a_sale
+ name: '[PC1] Basic PC'
+ price_unit: 200.0
+ quantity: 1.0
+ product_id: product.product_product_pc1
+ uos_id: product.product_uom_unit
+ journal_id: account.sales_journal
+ partner_id: res_partner_michal1
+ reference_type: none
+-
+ I Validate invoice by clicking on Validate button
+-
+ !workflow {model: account.invoice, action: invoice_open, ref: account_first_invoice_jan_michal}
+-
+ I check that first invoice move is correct for debtor account(debit - credit == 150)
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_first_invoice_jan_michal"))
+ assert invoice_id.move_id, "Move not created for open invoice"
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.debit - move_line.credit == 150.00), "Invoice move is incorrect for debtors account"
+-
+ I create the second invoice on 1st February for 100 USD
+-
+ !record {model: account.invoice, id: account_second_invoice_feb_michal}:
+ account_id: account.a_recv
+ address_contact_id: base.res_partner_address_3000
+ address_invoice_id: base.res_partner_address_3000
+ company_id: base.main_company
+ currency_id: base.USD
+ date_invoice: !eval "'%s-02-01' %(datetime.now().year)"
+ period_id: account.period_2
+ invoice_line:
+ - account_id: account.a_sale
+ name: '[PC1] Basic PC'
+ price_unit: 100.0
+ quantity: 1.0
+ product_id: product.product_product_pc1
+ uos_id: product.product_uom_unit
+ journal_id: account.sales_journal
+ partner_id: res_partner_michal1
+ reference_type: none
+-
+ I Validate invoice by clicking on Validate button
+-
+ !workflow {model: account.invoice, action: invoice_open, ref: account_second_invoice_feb_michal}
+-
+ I check that second invoice move is correct for debtor account (debit - credit == 80)
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_second_invoice_feb_michal"))
+ assert invoice_id.move_id, "Move not created for open invoice"
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.debit - move_line.credit == 80), "Invoice move is incorrect for debtors account"
+-
+ I create the first voucher of payment
+
+-
+ !python {model: account.voucher}: |
+ import netsvc, time
+ vals = {}
+ res = self.onchange_partner_id(cr, uid, [], ref("res_partner_michal1"), ref('bank_journal_EUR'), 200.0, 2, ttype='receipt', date=False)
+ vals = {
+ 'account_id': ref('account.cash'),
+ 'amount': 200.0,
+ 'company_id': ref('base.main_company'),
+ 'currency_id': ref('base.EUR'),
+ 'journal_id': ref('bank_journal_EUR'),
+ 'partner_id': ref('res_partner_michal1'),
+ 'period_id': ref('account.period_3'),
+ 'type': 'receipt',
+ 'date': time.strftime("%Y-03-01"),
+ 'payment_option': 'with_writeoff',
+ 'writeoff_acc_id': ref('account.a_expense'),
+ 'comment': 'Write Off',
+ 'name': 'First payment',
+ }
+ if not res['value']['line_cr_ids']:
+ res['value']['line_cr_ids'] = [{'type': 'cr', 'account_id': ref('account.a_recv'),}]
+ for item in res['value']['line_cr_ids']:
+ if item['amount_unreconciled'] == 150.00:
+ item['amount'] = 130.00
+ else:
+ item['amount'] = 70.00
+ vals['line_cr_ids'] = [(0,0,i) for i in res['value']['line_cr_ids']]
+ id = self.create(cr, uid, vals)
+ voucher_id = self.browse(cr, uid, id)
+ assert (voucher_id.state=='draft'), "Voucher is not in draft state"
+-
+ I confirm the voucher
+-
+ !python {model: account.voucher}: |
+ import netsvc
+ voucher = self.search(cr, uid, [('name', '=', 'First payment'), ('partner_id', '=', ref('res_partner_michal1'))])
+ wf_service = netsvc.LocalService("workflow")
+ wf_service.trg_validate(uid, 'account.voucher', voucher[0], 'proforma_voucher', cr)
+-
+ I check that the move of my voucher is valid
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'First payment'), ('partner_id', '=', ref('res_partner_michal1'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', voucher_id.move_id.id)])
+ for move_line in move_line_obj.browse(cr, uid, move_lines):
+ assert move_line.state == 'valid', "Voucher move is not valid"
+-
+ I check that my debtor account is correct
+-
+ I check that the debtor account has 2 new lines with 144.44 and 77.78 in amount_currency columns and their credit columns are 130 and 70
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'First payment'), ('partner_id', '=', ref('res_partner_michal1'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', voucher_id.move_id.id)])
+ for move_line in move_line_obj.browse(cr, uid, move_lines):
+ if move_line.credit == 70.0:
+ assert move_line.amount_currency == -77.78, "Wrong debtor entry"
+ if move_line.credit == 130.0:
+ assert move_line.amount_currency == -144.44, "Wrong debtor entry"
+-
+ I check the residual amount of Invoice1, should be 55.56 in residual currency and 20 in amount_residual
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_first_invoice_jan_michal"))
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('invoice', '=', invoice_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.amount_residual_currency == 55.56 and move_line.amount_residual == 20) , "Residual amount is not correct for first Invoice"
+- toto
+ I check the residual amuont of Invoice2, should be 22.22 in residual currency and 10 in amount_residual
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_second_invoice_feb_michal"))
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('invoice', '=', invoice_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.amount_residual_currency == 22.22 and move_line.amount_residual == 10) , "Residual amount is not correct for second Invoice"
+-
+ I create the second voucher of payment
+
+-
+ !python {model: account.voucher}: |
+ import netsvc, time
+ vals = {}
+ res = self.onchange_partner_id(cr, uid, [], ref("res_partner_michal1"), ref('bank_journal_USD'), 80.0, 2, ttype='receipt', date=False)
+ vals = {
+ 'account_id': ref('account.cash'),
+ 'amount': 80.0,
+ 'company_id': ref('base.main_company'),
+ 'currency_id': ref('base.USD'),
+ 'journal_id': ref('bank_journal_USD'),
+ 'partner_id': ref('res_partner_michal1'),
+ 'period_id': ref('account.period_3'),
+ 'type': 'receipt',
+ 'date': time.strftime("%Y-04-01"),
+ 'payment_option': 'with_writeoff',
+ 'writeoff_acc_id': ref('account.a_expense'),
+ 'exchange_acc_id': ref('account.o_expense'),
+ 'comment': 'Write Off',
+ 'name': 'Second payment',
+ }
+ if not res['value']['line_cr_ids']:
+ res['value']['line_cr_ids'] = [{'type': 'cr', 'account_id': ref('account.a_recv'),}]
+ for item in res['value']['line_cr_ids']:
+ if item['amount_unreconciled'] == 55.56:
+ item['amount'] = 55.56
+ else:
+ item['amount'] = 22.22
+ vals['line_cr_ids'] = [(0,0,i) for i in res['value']['line_cr_ids']]
+ id = self.create(cr, uid, vals)
+ voucher_id = self.browse(cr, uid, id)
+ assert (voucher_id.state=='draft'), "Voucher is not in draft state"
+-
+ I check that writeoff amount computed is 2.22
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'Second payment'), ('partner_id', '=', ref('res_partner_michal1'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ assert (round(voucher_id.writeoff_amount, 2) == 2.22), "Writeoff amount is not 2.22$"
+-
+ I confirm the voucher
+-
+ !python {model: account.voucher}: |
+ import netsvc
+ voucher = self.search(cr, uid, [('name', '=', 'Second payment'), ('partner_id', '=', ref('res_partner_michal1'))])
+ wf_service = netsvc.LocalService("workflow")
+ wf_service.trg_validate(uid, 'account.voucher', voucher[0], 'proforma_voucher', cr)
+-
+ I check that my voucher state is posted
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'Second payment'), ('partner_id', '=', ref('res_partner_michal1'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ assert voucher_id.state == 'posted', "Voucher state is not posted"
+-
+ I check that my debtor account is correct
+-
+ I check that the debtor account has 2 new lines with -55.56 and -22.22 in amount_currency columns and their credit columns are respectively 52.78 and 21.11 and currency is USD($).
+-
+ I check that my currency rate difference is correct.
+-
+ I check that my writeoff is correct. 2.11 in credit and 2.22 in amount_currency
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'Second payment'), ('partner_id', '=', ref('res_partner_michal1'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', voucher_id.move_id.id)])
+ reconcile_a = reconcile_b = False
+ for move_line in move_line_obj.browse(cr, uid, move_lines):
+ if move_line.amount_currency == -22.22:
+ assert move_line.reconcile_id.id, "The invoice of 200$ is not fully reconciled"
+ reconcile_b = move_line.reconcile_id.id
+ elif move_line.amount_currency == -55.56:
+ assert move_line.reconcile_id.id, "The invoice of 100$ is not fully reconciled"
+ reconcile_a = move_line.reconcile_id.id
+ for move_line in move_line_obj.browse(cr, uid, move_lines):
+ if move_line.amount_currency == -55.56:
+ assert move_line.credit == 52.78, "Debtor account has wrong entry."
+ elif move_line.amount_currency == -22.22:
+ assert move_line.credit == 21.11, "Debtor account has wrong entry."
+ elif move_line.credit == 11.11 and move_line.account_id.reconcile:
+ assert move_line.amount_currency == 0.00 and move_line.reconcile_id.id == reconcile_b, "Incorrect Currency Difference."
+ elif move_line.credit == 32.78 and move_line.account_id.reconcile:
+ assert move_line.amount_currency == 0.00 and move_line.reconcile_id.id == reconcile_a, "Incorrect Currency Difference."
+ elif move_line.amount_currency == 2.22:
+ assert move_line.credit == 2.11, "Writeoff amount is wrong."
+-
+ I check the residual amount of invoice 1, should be 0 in residual currency and 0 in amount_residual and paid
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_first_invoice_jan_michal"))
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('invoice', '=', invoice_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.amount_residual_currency == 0.0 and move_line.amount_residual == 0.0 and invoice_id.state == 'paid') , "Residual amount is not correct for first Invoice"
+-
+ I check the residual amuont of invoice 2, should be 0 in residual currency and 0 in amount_residual and paid
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_second_invoice_feb_michal"))
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('invoice', '=', invoice_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.amount_residual_currency == 0.0 and move_line.amount_residual == 0.0 and invoice_id.state == 'paid') , "Residual amount is not correct for second Invoice"
diff --git a/addons/account_voucher/test/case3_eur_eur.yml b/addons/account_voucher/test/case3_eur_eur.yml
new file mode 100644
index 00000000000..374f40607bd
--- /dev/null
+++ b/addons/account_voucher/test/case3_eur_eur.yml
@@ -0,0 +1,297 @@
+-
+ In order to check the Account_voucher module with multi-currency in OpenERP,
+ I create 2 Invoices in EUR and make 2 Payments in EUR based on the currency rating on that particular date.
+-
+ I create currency EUR in OpenERP for January of 1.000000 Rate
+-
+ !record {model: res.currency.rate, id: jan_eur}:
+ currency_id: base.EUR
+ name: !eval "'%s-01-01' %(datetime.now().year)"
+ rate: 1.000000
+-
+ I modify the debtor account in order to make sure there is no currency_id linked
+-
+ !python {model: account.account}: |
+ from datetime import datetime
+ ids = self.search(cr, uid, [('name', 'ilike', 'debtor')])
+ self.write(cr, uid, ids, {'currency_id': False})
+-
+ I create a bank journal with EUR as currency
+-
+ !record {model: account.journal, id: bank_journal_EUR}:
+ name: Bank Journal(EUR)
+ code: BEUR
+ type: bank
+ analytic_journal_id: account.sit
+ sequence_id: account.sequence_bank_journal
+ default_debit_account_id: account.cash
+ default_credit_account_id: account.cash
+ currency: base.EUR
+ company_id: base.main_company
+ view_id: account.account_journal_bank_view
+-
+ I create a new partner Peter Lawson.
+-
+ !record {model: res.partner, id: res_partner_peter0}:
+ address:
+ - city: paris
+ country_id: base.fr
+ name: Peter
+ street: 1 rue Rockfeller
+ type: invoice
+ zip: '75016'
+ name: Mr.Peter Lawson
+-
+ I create the first invoice on 1st January for 150 EUR
+-
+ !record {model: account.invoice, id: account_first_invoice_jan_eur}:
+ account_id: account.a_recv
+ address_contact_id: base.res_partner_address_3000
+ address_invoice_id: base.res_partner_address_3000
+ company_id: base.main_company
+ currency_id: base.EUR
+ date_invoice: !eval "'%s-01-01' %(datetime.now().year)"
+ period_id: account.period_1
+ invoice_line:
+ - account_id: account.a_sale
+ name: '[PC1] Basic PC'
+ price_unit: 150.0
+ quantity: 1.0
+ product_id: product.product_product_pc1
+ uos_id: product.product_uom_unit
+ journal_id: account.sales_journal
+ partner_id: res_partner_peter0
+ reference_type: none
+-
+ I Validate invoice by clicking on Validate button
+-
+ !workflow {model: account.invoice, action: invoice_open, ref: account_first_invoice_jan_eur}
+-
+ I check that first invoice move is correct for debtor account(debit - credit == 150)
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_first_invoice_jan_eur"))
+ assert invoice_id.move_id, "Move not created for open invoice"
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.debit - move_line.credit == 150.00), "Invoice move is incorrect for debtors account"
+-
+ I create the second invoice on 1st February for 80 EUR
+-
+ !record {model: account.invoice, id: account_second_invoice_feb_eur}:
+ account_id: account.a_recv
+ address_contact_id: base.res_partner_address_3000
+ address_invoice_id: base.res_partner_address_3000
+ company_id: base.main_company
+ currency_id: base.EUR
+ date_invoice: !eval "'%s-02-01' %(datetime.now().year)"
+ period_id: account.period_1
+ invoice_line:
+ - account_id: account.a_sale
+ name: '[PC1] Basic PC'
+ price_unit: 80.0
+ quantity: 1.0
+ product_id: product.product_product_pc1
+ uos_id: product.product_uom_unit
+ journal_id: account.sales_journal
+ partner_id: res_partner_peter0
+ reference_type: none
+-
+ I Validate invoice by clicking on Validate button
+-
+ !workflow {model: account.invoice, action: invoice_open, ref: account_second_invoice_feb_eur}
+-
+ I check that second invoice move is correct for debtor account (debit - credit == 80)
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_second_invoice_feb_eur"))
+ assert invoice_id.move_id, "Move not created for open invoice"
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.debit - move_line.credit == 80.00), "Invoice move is incorrect for debtors account"
+-
+ I create the first voucher of payment
+
+-
+ !python {model: account.voucher}: |
+ import netsvc, time
+ vals = {}
+ res = self.onchange_partner_id(cr, uid, [], ref("res_partner_peter0"), ref('bank_journal_EUR'), 120.00, 2, ttype='receipt', date=False)
+ vals = {
+ 'account_id': ref('account.cash'),
+ 'amount': 120.00,
+ 'company_id': ref('base.main_company'),
+ 'currency_id': ref('base.EUR'),
+ 'journal_id': ref('bank_journal_EUR'),
+ 'partner_id': ref('res_partner_peter0'),
+ 'period_id': ref('account.period_3'),
+ 'type': 'receipt',
+ 'date': time.strftime("%Y-03-01"),
+ 'payment_option': 'with_writeoff',
+ 'writeoff_acc_id': ref('account.a_expense'),
+ 'comment': 'Write Off',
+ 'name': 'First payment',
+ }
+ if not res['value']['line_cr_ids']:
+ res['value']['line_cr_ids'] = [{'type': 'cr', 'account_id': ref('account.a_recv'),}]
+ for item in res['value']['line_cr_ids']:
+ if item['amount_unreconciled'] == 150.00:
+ item['amount'] = 100.00
+ else:
+ item['amount'] = 20.00
+ vals['line_cr_ids'] = [(0,0,i) for i in res['value']['line_cr_ids']]
+ id = self.create(cr, uid, vals)
+ voucher_id = self.browse(cr, uid, id)
+ assert (voucher_id.state=='draft'), "Voucher is not in draft state"
+-
+ I check that writeoff amount computed is 0.00
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'First payment'),('partner_id', '=', ref('res_partner_peter0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ assert (voucher_id.writeoff_amount == 0.00), "Writeoff amount is not 0.00"
+-
+ I confirm the voucher
+-
+ !python {model: account.voucher}: |
+ import netsvc
+ voucher = self.search(cr, uid, [('name', '=', 'First payment'),('partner_id', '=', ref('res_partner_peter0'))])
+ wf_service = netsvc.LocalService("workflow")
+ wf_service.trg_validate(uid, 'account.voucher', voucher[0], 'proforma_voucher', cr)
+-
+ I check that the move of my first voucher is valid
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'First payment'),('partner_id', '=', ref('res_partner_peter0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', voucher_id.move_id.id)])
+ for move_line in move_line_obj.browse(cr, uid, move_lines):
+ assert move_line.state == 'valid', "Voucher move is not valid"
+-
+ I check that my debtor account is correct
+-
+ I check that the debtor account has 2 new lines with 0.00 and 0.00 in amount_currency columns and their credit are 20 and 100 respectively
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'First payment'),('partner_id', '=', ref('res_partner_peter0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', voucher_id.move_id.id)])
+ for move_line in move_line_obj.browse(cr, uid, move_lines):
+ if move_line.credit == 20.00:
+ assert move_line.amount_currency == 0.00, "Debtor account has wrong entry."
+ elif move_line.credit == 100.00:
+ assert move_line.amount_currency == 0.00, "Debtor account has wrong entry."
+-
+ I check the residual amount of Invoice1 is 50
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_first_invoice_jan_eur"))
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('invoice', '=', invoice_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.amount_residual_currency == 50.0 and move_line.amount_residual == 50.0) , "Residual amount is not correct for first Invoice"
+-
+ I check the residual amuont of Invoice2 is 60
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_second_invoice_feb_eur"))
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('invoice', '=', invoice_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.amount_residual_currency == 60.0 and move_line.amount_residual == 60.0) , "Residual amount is not correct for second Invoice"
+-
+ I create the second voucher of payment and check to let open the debtor overpaid amount.
+
+-
+ !python {model: account.voucher}: |
+ import netsvc, time
+ vals = {}
+ res = self.onchange_partner_id(cr, uid, [], ref("res_partner_peter0"), ref('bank_journal_EUR'), 120.00, 2, ttype='receipt', date=False)
+ vals = {
+ 'account_id': ref('account.cash'),
+ 'amount': 120.00,
+ 'company_id': ref('base.main_company'),
+ 'currency_id': ref('base.EUR'),
+ 'journal_id': ref('bank_journal_EUR'),
+ 'partner_id': ref('res_partner_peter0'),
+ 'period_id': ref('account.period_3'),
+ 'type': 'receipt',
+ 'date': time.strftime("%Y-04-01"),
+ 'payment_option': 'with_writeoff',
+ 'writeoff_acc_id': ref('account.a_expense'),
+ 'comment': 'Write Off',
+ 'name': 'Second payment',
+ }
+ if not res['value']['line_cr_ids']:
+ res['value']['line_cr_ids'] = [{'type': 'cr', 'account_id': ref('account.a_recv'),}]
+ for item in res['value']['line_cr_ids']:
+ if item['amount_unreconciled'] == 50.00:
+ item['amount'] = 50.00
+ elif item['amount_unreconciled'] == 60.00:
+ item['amount'] = 70.00
+ vals['line_cr_ids'] = [(0,0,i) for i in res['value']['line_cr_ids']]
+ id = self.create(cr, uid, vals)
+ voucher_id = self.browse(cr, uid, id)
+ assert (voucher_id.state=='draft'), "Voucher is not in draft state"
+-
+ I check that writeoff amount computed is 0.00
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'Second payment'),('partner_id', '=', ref('res_partner_peter0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ assert (voucher_id.writeoff_amount == 0.00), "Writeoff amount is not 0"
+-
+ I confirm the voucher
+-
+ !python {model: account.voucher}: |
+ import netsvc
+ voucher = self.search(cr, uid, [('name', '=', 'Second payment'), ('partner_id', '=', ref('res_partner_peter0'))])
+ wf_service = netsvc.LocalService("workflow")
+ wf_service.trg_validate(uid, 'account.voucher', voucher[0], 'proforma_voucher', cr)
+-
+ I check that the move of my second voucher is valid
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'Second payment'), ('partner_id', '=', ref('res_partner_peter0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', voucher_id.move_id.id)])
+ for move_line in move_line_obj.browse(cr, uid, move_lines):
+ assert move_line.state == 'valid', "Voucher move is not valid"
+-
+ I check that my debtor account is correct
+-
+ I check that the debtor account has 2 new lines with 0.00 and 0.00 in amount_currency columns and their credit are 70 and 50
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'Second payment'), ('partner_id', '=', ref('res_partner_peter0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', voucher_id.move_id.id)])
+ for move_line in move_line_obj.browse(cr, uid, move_lines):
+ if move_line.credit == 70.00:
+ assert move_line.amount_currency == 0.00, "Debtor account has wrong entry."
+ elif move_line.credit == 50.00:
+ assert move_line.amount_currency == 0.00, "Debtor account has wrong entry."
+-
+ I check the residual amount of Invoice1 is 0
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_first_invoice_jan_eur"))
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('invoice', '=', invoice_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.amount_residual_currency == 0 and move_line.amount_residual == 0) , "Residual amount is not correct for first Invoice"
+-
+ I check the residual amuont of Invoice2 is -10
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_second_invoice_feb_eur"))
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('invoice', '=', invoice_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.amount_residual_currency == -10.0 and move_line.amount_residual == -10.0) , "Residual amount is not correct for second Invoice"
diff --git a/addons/account_voucher/test/case4_cad_chf.yml b/addons/account_voucher/test/case4_cad_chf.yml
new file mode 100644
index 00000000000..deaf341d1c0
--- /dev/null
+++ b/addons/account_voucher/test/case4_cad_chf.yml
@@ -0,0 +1,185 @@
+-
+ In order to check the Account_voucher module with multi-currency in OpenERP,
+ I create an invoice in CAD and make its Payment in CHF based on the currency rating on that particular date.
+-
+ I create currency CAD in OpenERP for January of 1.338800 Rate
+-
+ !record {model: res.currency.rate, id: jan_cad}:
+ currency_id: base.CAD
+ name: !eval "'%s-01-01' %(datetime.now().year)"
+ rate: 1.338800
+-
+ I create currency CAD in OpenERP for March of 2.000000 Rate
+-
+ !record {model: res.currency.rate, id: mar_cad}:
+ currency_id: base.CAD
+ name: !eval "'%s-03-01' %(datetime.now().year)"
+ rate: 2.000000
+-
+ I create currency CHF in OpenERP for January of 1.308600 Rate
+-
+ !record {model: res.currency.rate, id: jan_chf}:
+ currency_id: base.CHF
+ name: !eval "'%s-01-01' %(datetime.now().year)"
+ rate: 1.308600
+-
+ I create currency CHF in OpenERP for March of 1.250000 Rate
+-
+ !record {model: res.currency.rate, id: mar_chf}:
+ currency_id: base.CHF
+ name: !eval "'%s-03-01' %(datetime.now().year)"
+ rate: 1.25000
+-
+ I create a bank journal with CHF as currency
+-
+ !record {model: account.journal, id: bank_journal_CHF}:
+ name: Bank Journal(CHF)
+ code: BCHF
+ type: bank
+ analytic_journal_id: account.sit
+ sequence_id: account.sequence_bank_journal
+ default_debit_account_id: account.cash
+ default_credit_account_id: account.cash
+ currency: base.CHF
+ company_id: base.main_company
+ view_id: account.account_journal_bank_view
+-
+ I create a new partner John Armani.
+-
+ !record {model: res.partner, id: res_partner_john0}:
+ address:
+ - city: paris
+ country_id: base.fr
+ name: John
+ street: 1 rue Rockfeller
+ type: invoice
+ zip: '75016'
+ name: Mr.John Armani
+-
+ I create the first invoice on 1st January for 200 CAD
+-
+ !record {model: account.invoice, id: account_first_invoice_jan_cad}:
+ account_id: account.a_recv
+ address_contact_id: base.res_partner_address_3000
+ address_invoice_id: base.res_partner_address_3000
+ company_id: base.main_company
+ currency_id: base.CAD
+ date_invoice: !eval "'%s-01-01' %(datetime.now().year)"
+ period_id: account.period_1
+ invoice_line:
+ - account_id: account.a_sale
+ name: '[PC1] Basic PC'
+ price_unit: 200.0
+ quantity: 1.0
+ product_id: product.product_product_pc1
+ uos_id: product.product_uom_unit
+ journal_id: account.sales_journal
+ partner_id: res_partner_john0
+ reference_type: none
+-
+ I Validate invoice by clicking on Validate button
+-
+ !workflow {model: account.invoice, action: invoice_open, ref: account_first_invoice_jan_cad}
+-
+ I check that first invoice move is correct for debtor account (debit - credit == 149.39)
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_first_invoice_jan_cad"))
+ assert invoice_id.move_id, "Move not created for open invoice"
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.debit - move_line.credit == 149.39), "Invoice move is incorrect for debtors account"
+-
+ I create the first voucher of payment
+
+-
+ !python {model: account.voucher}: |
+ import netsvc, time
+ vals = {}
+ res = self.onchange_partner_id(cr, uid, [], ref("res_partner_john0"), ref('bank_journal_CHF'), 200.00, 2, ttype='receipt', date=False)
+ vals = {
+ 'account_id': ref('account.cash'),
+ 'amount': 200.00,
+ 'company_id': ref('base.main_company'),
+ 'currency_id': ref('base.CHF'),
+ 'journal_id': ref('bank_journal_CHF'),
+ 'partner_id': ref('res_partner_john0'),
+ 'period_id': ref('account.period_3'),
+ 'type': 'receipt',
+ 'date': time.strftime("%Y-03-01"),
+ 'payment_option': 'with_writeoff',
+ 'writeoff_acc_id': ref('account.a_expense'),
+ 'exchange_acc_id': ref('account.o_expense'),
+ 'comment': 'Write Off',
+ 'name': 'First payment',
+ }
+ if not res['value']['line_cr_ids']:
+ res['value']['line_cr_ids'] = [{'type': 'cr', 'account_id': ref('account.a_recv'),}]
+ for item in res['value']['line_cr_ids']:
+ if item['amount_unreconciled'] == 186.74:
+ item['amount'] = 186.74
+ vals['line_cr_ids'] = [(0,0,i) for i in res['value']['line_cr_ids']]
+ id = self.create(cr, uid, vals)
+ voucher_id = self.browse(cr, uid, id)
+ assert (voucher_id.state=='draft'), "Voucher is not in draft state"
+-
+ I check that writeoff amount computed is 13.26
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'First payment'), ('partner_id', '=', ref('res_partner_john0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ assert (round(voucher_id.writeoff_amount,2) == 13.26), "Writeoff amount is not 13.26 CHF"
+-
+ I confirm the voucher
+-
+ !python {model: account.voucher}: |
+ import netsvc
+ voucher = self.search(cr, uid, [('name', '=', 'First payment'), ('partner_id', '=', ref('res_partner_john0'))])
+ wf_service = netsvc.LocalService("workflow")
+ wf_service.trg_validate(uid, 'account.voucher', voucher[0], 'proforma_voucher', cr)
+-
+ I check that the move of my voucher is valid
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'First payment'), ('partner_id', '=', ref('res_partner_john0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', voucher_id.move_id.id)])
+ for move_line in move_line_obj.browse(cr, uid, move_lines):
+ assert move_line.state == 'valid', "Voucher move is not valid"
+ assert voucher_id.state == 'posted', "Voucher state is not posted"
+-
+ I check that my debtor account is correct
+-
+ I check that the debtor account has 1 new line with -186.74 as amount_currency columns and 149.39 of credit and currency is CHF.
+-
+ I check that my currency rate difference is correct. 0 in debit with no amount_currency
+-
+ I check that my writeoff is correct. 11.05 credit and 13.26 amount_currency
+-
+ !python {model: account.voucher}: |
+ voucher = self.search(cr, uid, [('name', '=', 'First payment'), ('partner_id', '=', ref('res_partner_john0'))])
+ voucher_id = self.browse(cr, uid, voucher[0])
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', voucher_id.move_id.id)])
+ for move_line in move_line_obj.browse(cr, uid, move_lines):
+ if move_line.amount_currency == 200:
+ assert move_line.debit == 160.00, "Bank account has wrong entry."
+ elif move_line.amount_currency == -186.74:
+ assert move_line.credit == 149.39, "Debtor account has wrong entry."
+ elif move_line.debit == 0.00 and move_line.credit == 0.00:
+ assert move_line.amount_currency == 0.00, "Incorrect Currency Difference."
+ elif move_line.credit == 10.61:
+ assert move_line.amount_currency == 13.26, "Writeoff amount is wrong."
+ else:
+ assert False, "Wrong entry"
+-
+ I check the residual amount of Invoice1, should be 0 in residual currency and 0 in amount_residual and paid
+-
+ !python {model: account.invoice}: |
+ invoice_id = self.browse(cr, uid, ref("account_first_invoice_jan_cad"))
+ move_line_obj = self.pool.get('account.move.line')
+ move_lines = move_line_obj.search(cr, uid, [('move_id', '=', invoice_id.move_id.id), ('invoice', '=', invoice_id.id), ('account_id', '=', invoice_id.account_id.id)])
+ move_line = move_line_obj.browse(cr, uid, move_lines[0])
+ assert (move_line.amount_residual_currency == 0.0 and move_line.amount_residual == 0.0 and invoice_id.state == 'paid') , "Residual amount is not correct for first Invoice"