[FIX] account: another way to resolve multi currency reconciliation on bank statements: show the amount in statement line currency instead of converting them into the statement currency. This is needed in order to have a balance of 0 in the foreign currency. The only remaining thing is to make a foreign currency exchange writeoff automatic at the reconciliation time if we reconcile 2 lines having the same currency_id

This commit is contained in:
qdp-odoo 2014-06-02 02:28:15 +02:00
parent dc4178a962
commit c4bc4dc3f5
2 changed files with 68 additions and 40 deletions

View File

@ -414,22 +414,33 @@ class account_bank_statement(osv.osv):
'domain':[('statement_id','in',ids)],
'context':ctx,
}
def get_format_currency_js_function(self, cr, uid, id, context=None):
""" Returns a string that can be used to instanciate a javascript function.
That function formats a number according to the statement line's currency or the statement currency"""
company_currency = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id
st = id and self.browse(cr, uid, id, context=context)
if not st:
return
statement_currency = st.journal_id.currency or company_currency
digits = 2 # TODO : from currency_obj
function = "debugger;"
done_currencies = []
for st_line in st.line_ids:
st_line_currency = st_line.currency_id or statement_currency
if st_line_currency.id not in done_currencies:
if st_line_currency.position == 'after':
return_str = "return amount.toFixed(" + str(digits) + ") + ' " + st_line_currency.symbol + "';"
else:
return_str = "return '" + st_line_currency.symbol + " ' + amount.toFixed(" + str(digits) + ");"
function += "if (currency_id === " + str(st_line_currency.id) + "){ " + return_str + " }"
done_currencies.append(st_line_currency.id)
return function
def number_of_lines_reconciled(self, cr, uid, id, context=None):
bsl_obj = self.pool.get('account.bank.statement.line')
return bsl_obj.search_count(cr, uid, [('statement_id','=',id), ('journal_entry_id','!=',False)], context=context)
def get_format_currency_js_function(self, cr, uid, id, context=None):
""" Returns a string that can be used to instanciate a javascript function.
That function formats a number according to the statement's journal currency """
company_currency = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id
currency_obj = id and self.browse(cr, uid, id, context=context).journal_id.currency or company_currency
digits = 2 # TODO : from currency_obj
if currency_obj.position == 'after':
return "return amount.toFixed("+str(digits)+") + ' "+currency_obj.symbol+"';"
elif currency_obj.position == 'before':
return "return '"+currency_obj.symbol+" ' + amount.toFixed("+str(digits)+");"
class account_bank_statement_line(osv.osv):
def get_data_for_reconciliations(self, cr, uid, ids, context=None):
@ -457,12 +468,15 @@ class account_bank_statement_line(osv.osv):
""" Returns the data required by the bank statement reconciliation use case """
line = self.browse(cr, uid, id, context=context)
statement_currency = line.journal_id.currency or line.journal_id.company_id.currency_id
amount = line.amount
rml_parser = report_sxw.rml_parse(cr, uid, 'statement_line_widget', context=context)
amount_str = line.amount > 0 and line.amount or -line.amount
amount_str = rml_parser.formatLang(amount_str, currency_obj=statement_currency)
amount_currency_str = ""
if line.amount_currency and line.currency_id:
amount_currency_str = rml_parser.formatLang(line.amount_currency, currency_obj=line.currency_id)
amount_currency_str = amount_str
amount_str = rml_parser.formatLang(line.amount_currency, currency_obj=line.currency_id)
amount = line.amount_currency
dict = {
'id': line.id,
@ -470,8 +484,9 @@ class account_bank_statement_line(osv.osv):
'note': line.note or "",
'name': line.name,
'date': line.date,
'amount': line.amount,
'amount': amount,
'amount_str': amount_str,
'currency_id': line.currency_id.id or statement_currency.id,
'no_match': self.get_move_lines_counterparts(cr, uid, id, count=True, context=context) == 0 and line.partner_id.id,
'partner_id': line.partner_id.id,
'statement_id': line.statement_id.id,
@ -482,7 +497,7 @@ class account_bank_statement_line(osv.osv):
'has_no_partner': not line.partner_id.id,
}
if line.partner_id.id:
if line.amount > 0:
if amount > 0:
dict['open_balance_account_id'] = line.partner_id.property_account_receivable.id
else:
dict['open_balance_account_id'] = line.partner_id.property_account_payable.id
@ -596,7 +611,8 @@ class account_bank_statement_line(osv.osv):
'journal_name': line.journal_id.name,
'amount_currency_str': amount_currency_str,
}
if statement_currency.id != company_currency.id and line.currency_id and line.currency_id.id == statement_currency.id:
st_line_currency = st_line.currency_id or statement_currency
if st_line.currency_id and line.currency_id and line.currency_id.id == st_line.currency_id.id:
if line.amount_residual_currency < 0:
ret_line['debit'] = 0
ret_line['credit'] = -line.amount_residual_currency
@ -613,10 +629,10 @@ class account_bank_statement_line(osv.osv):
ret_line['credit'] = line.amount_residual if line.debit != 0 else 0
ctx = context.copy()
ctx.update({'date': st_line.date})
ret_line['debit'] = currency_obj.compute(cr, uid, statement_currency.id, company_currency.id, ret_line['debit'], context=ctx)
ret_line['credit'] = currency_obj.compute(cr, uid, statement_currency.id, company_currency.id, ret_line['credit'], context=ctx)
ret_line['debit_str'] = rml_parser.formatLang(ret_line['debit'], currency_obj=statement_currency)
ret_line['credit_str'] = rml_parser.formatLang(ret_line['credit'], currency_obj=statement_currency)
ret_line['debit'] = currency_obj.compute(cr, uid, st_line_currency.id, company_currency.id, ret_line['debit'], context=ctx)
ret_line['credit'] = currency_obj.compute(cr, uid, st_line_currency.id, company_currency.id, ret_line['credit'], context=ctx)
ret_line['debit_str'] = rml_parser.formatLang(ret_line['debit'], currency_obj=st_line_currency)
ret_line['credit_str'] = rml_parser.formatLang(ret_line['credit'], currency_obj=st_line_currency)
ret.append(ret_line)
if line.reconcile_partial_id:
reconcile_partial_ids.append(line.reconcile_partial_id.id)
@ -657,14 +673,14 @@ class account_bank_statement_line(osv.osv):
amount = currency_obj.compute(cr, uid, st_line.statement_id.currency.id, company_currency.id, st_line.amount, context=context)
bank_st_move_vals = bs_obj._prepare_bank_move_line(cr, uid, st_line, move_id, amount, company_currency.id, context=context)
aml_obj.create(cr, uid, bank_st_move_vals, context=context)
st_line_currency_rate = bank_st_move_vals['amount_currency'] and statement_currency.id == company_currency.id and (bank_st_move_vals['amount_currency'] / st_line.amount) or False
st_line_currency = bank_st_move_vals['currency_id']
# Complete the dicts
st_line_statement_id = st_line.statement_id.id
st_line_journal_id = st_line.journal_id.id
st_line_partner_id = st_line.partner_id.id
st_line_company_id = st_line.company_id.id
st_line_period_id = st_line.statement_id.period_id.id
st_line_currency = st_line.currency_id or statement_currency
st_line_currency_rate = st_line.currency_id and statement_currency.id == company_currency.id and (st_line.amount_currency / st_line.amount) or False
for mv_line_dict in mv_line_dicts:
mv_line_dict['ref'] = move_name
mv_line_dict['move_id'] = move_id
@ -676,15 +692,24 @@ class account_bank_statement_line(osv.osv):
if mv_line_dict.get('counterpart_move_line_id'):
mv_line = aml_obj.browse(cr, uid, mv_line_dict['counterpart_move_line_id'], context=context)
mv_line_dict['account_id'] = mv_line.account_id.id
if statement_currency.id != company_currency.id:
if st_line_currency.id != company_currency.id:
mv_line_dict['amount_currency'] = mv_line_dict['debit'] - mv_line_dict['credit']
mv_line_dict['currency_id'] = statement_currency.id
mv_line_dict['debit'] = currency_obj.compute(cr, uid, statement_currency.id, company_currency.id, mv_line_dict['debit'])
mv_line_dict['credit'] = currency_obj.compute(cr, uid, statement_currency.id, company_currency.id, mv_line_dict['credit'])
elif st_line_currency and st_line_currency_rate:
mv_line_dict['amount_currency'] = self.pool.get('res.currency').round(cr, uid, st_line.currency_id, (mv_line_dict['debit'] - mv_line_dict['credit']) * st_line_currency_rate)
mv_line_dict['currency_id'] = st_line_currency
mv_line_dict['currency_id'] = st_line_currency.id
if st_line.currency_id and statement_currency.id == company_currency.id and st_line_currency_rate:
mv_line_dict['debit'] = self.pool.get('res.currency').round(cr, uid, company_currency, mv_line_dict['debit'] / st_line_currency_rate)
mv_line_dict['credit'] = self.pool.get('res.currency').round(cr, uid, company_currency, mv_line_dict['credit'] / st_line_currency_rate)
else:
mv_line_dict['debit'] = currency_obj.compute(cr, uid, st_line_currency.id, company_currency.id, mv_line_dict['debit'])
mv_line_dict['credit'] = currency_obj.compute(cr, uid, st_line_currency.id, company_currency.id, mv_line_dict['credit'])
#if statement_currency.id != company_currency.id:
# mv_line_dict['amount_currency'] = mv_line_dict['debit'] - mv_line_dict['credit']
# mv_line_dict['currency_id'] = statement_currency.id
# mv_line_dict['debit'] = currency_obj.compute(cr, uid, statement_currency.id, company_currency.id, mv_line_dict['debit'])
# mv_line_dict['credit'] = currency_obj.compute(cr, uid, statement_currency.id, company_currency.id, mv_line_dict['credit'])
#elif st_line_currency and st_line_currency_rate:
# mv_line_dict['amount_currency'] = self.pool.get('res.currency').round(cr, uid, st_line.currency_id, (mv_line_dict['debit'] - mv_line_dict['credit']) * st_line_currency_rate)
# mv_line_dict['currency_id'] = st_line_currency
import pdb;pdb.set_trace()
# Create move lines
move_line_pairs_to_reconcile = []
for mv_line_dict in mv_line_dicts:

View File

@ -171,7 +171,7 @@ openerp.account = function (instance) {
deferred_promises.push(self.model_bank_statement
.call("get_format_currency_js_function", [self.statement_id])
.then(function(data){
self.formatCurrency = new Function("amount", data);
self.formatCurrency = new Function("amount, currency_id", data);
})
);
@ -1099,8 +1099,8 @@ openerp.account = function (instance) {
} else {
self.$(".button_ok").removeClass("oe_highlight");
self.$(".button_ok").text("Keep open");
var debit = (balance > 0 ? self.formatCurrency(balance) : "");
var credit = (balance < 0 ? self.formatCurrency(-1*balance) : "");
var debit = (balance > 0 ? self.formatCurrency(balance, self.st_line.currency_id) : "");
var credit = (balance < 0 ? self.formatCurrency(-1*balance, self.st_line.currency_id) : "");
var $line = $(QWeb.render("bank_statement_reconciliation_line_open_balance", {debit: debit, credit: credit, account_code: self.map_account_id_code[self.st_line.open_balance_account_id]}));
self.$(".tbody_open_balance").append($line);
}
@ -1198,6 +1198,8 @@ openerp.account = function (instance) {
var self = this;
var line_created_being_edited = self.get("line_created_being_edited");
line_created_being_edited[0][elt.corresponding_property] = val.newValue;
line_created_being_edited[0].currency_id = self.st_line.currency_id;
// Specific cases
if (elt === self.account_id_field)
@ -1215,7 +1217,7 @@ openerp.account = function (instance) {
var tax = data.taxes[0];
var tax_account_id = (amount > 0 ? tax.account_collected_id : tax.account_paid_id)
line_created_being_edited[0].amount = (data.total.toFixed(3) === amount.toFixed(3) ? amount : data.total);
line_created_being_edited[1] = {id: line_created_being_edited[0].id, account_id: tax_account_id, account_num: self.map_account_id_code[tax_account_id], label: tax.name, amount: tax.amount, no_remove_action: true};
line_created_being_edited[1] = {id: line_created_being_edited[0].id, account_id: tax_account_id, account_num: self.map_account_id_code[tax_account_id], label: tax.name, amount: tax.amount, no_remove_action: true, currency_id: self.st_line.currency_id};
}
);
} else {
@ -1227,11 +1229,11 @@ openerp.account = function (instance) {
$.when(deferred_tax).then(function(){
// Format amounts
debugger;
if (line_created_being_edited[0].amount)
line_created_being_edited[0].amount_str = self.formatCurrency(Math.abs(line_created_being_edited[0].amount));
line_created_being_edited[0].amount_str = self.formatCurrency(Math.abs(line_created_being_edited[0].amount), line_created_being_edited[0].currency_id);
if (line_created_being_edited[1] && line_created_being_edited[1].amount)
line_created_being_edited[1].amount_str = self.formatCurrency(Math.abs(line_created_being_edited[1].amount));
line_created_being_edited[1].amount_str = self.formatCurrency(Math.abs(line_created_being_edited[1].amount), line_created_being_edited[0].currency_id);
self.set("line_created_being_edited", line_created_being_edited);
self.createdLinesChanged(); // TODO For some reason, previous line doesn't trigger change handler
});
@ -1268,10 +1270,10 @@ openerp.account = function (instance) {
line.initial_amount = line.debit !== 0 ? line.debit : -1 * line.credit;
if (balance < 0) {
line.debit -= balance;
line.debit_str = self.formatCurrency(line.debit);
line.debit_str = self.formatCurrency(line.debit, self.st_line.currency_id);
} else {
line.credit -= balance;
line.credit_str = self.formatCurrency(line.credit);
line.credit_str = self.formatCurrency(line.credit, self.st_line.currency_id);
}
line.propose_partial_reconcile = false;
line.partial_reconcile = true;
@ -1291,12 +1293,13 @@ openerp.account = function (instance) {
},
unpartialReconcileLine: function(line) {
var self = this;
if (line.initial_amount > 0) {
line.debit = line.initial_amount;
line.debit_str = this.formatCurrency(line.debit);
line.debit_str = self.formatCurrency(line.debit, self.st_line.currency_id);
} else {
line.credit = -1 * line.initial_amount;
line.credit_str = this.formatCurrency(line.credit);
line.credit_str = self.formatCurrency(line.credit, self.st_line.currency_id);
}
line.propose_partial_reconcile = true;
line.partial_reconcile = false;