diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index 2522e53b2a0..9b4af85164e 100755 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -100,6 +100,57 @@ class account_move_line(osv.osv): return query + def _amount_residual(self, cr, uid, ids, field_names, args, context=None): + """ + This function returns the residual amount on a receivable or payable account.move.line. + By default, it returns an amount in the currency of this journal entry (maybe different + of the company currency), but if you pass 'residual_in_company_currency' = True in the + context then the returned amount will be in company currency. + """ + res = {} + if context is None: + context = {} + cur_obj = self.pool.get('res.currency') + for move_line in self.browse(cr, uid, ids, context=context): + res[move_line.id] = { + 'amount_residual': 0.0, + 'amount_residual_currency': 0.0, + } + + if move_line.reconcile_id: + continue + if not move_line.account_id.type in ('payable', 'receivable'): + #this function does not suport to be used on move lines not related to payable or receivable accounts + continue + + if move_line.currency_id: + move_line_total = move_line.amount_currency + sign = move_line.amount_currency < 0 and -1 or 1 + else: + move_line_total = move_line.debit - move_line.credit + sign = (move_line.debit - move_line.credit) < 0 and -1 or 1 + line_total_in_company_currency = move_line.debit - move_line.credit + context_unreconciled = context.copy() + if move_line.reconcile_partial_id: + for payment_line in move_line.reconcile_partial_id.line_partial_ids: + if payment_line.id == move_line.id: + continue + if payment_line.currency_id and move_line.currency_id and payment_line.currency_id.id == move_line.currency_id.id: + move_line_total += payment_line.amount_currency + else: + if move_line.currency_id: + context_unreconciled.update({'date': payment_line.date}) + amount_in_foreign_currency = cur_obj.compute(cr, uid, move_line.company_id.currency_id.id, move_line.currency_id.id, (payment_line.debit - payment_line.credit), round=False, context=context_unreconciled) + move_line_total += amount_in_foreign_currency + else: + move_line_total += (payment_line.debit - payment_line.credit) + line_total_in_company_currency += (payment_line.debit - payment_line.credit) + + result = move_line_total + res[move_line.id]['amount_residual_currency'] = sign * (move_line.currency_id and self.pool.get('res.currency').round(cr, uid, move_line.currency_id, result) or result) + res[move_line.id]['amount_residual'] = sign * line_total_in_company_currency + return res + def default_get(self, cr, uid, fields, context=None): data = self._default_get(cr, uid, fields, context=context) for f in data.keys(): @@ -433,6 +484,8 @@ class account_move_line(osv.osv): 'reconcile_id': fields.many2one('account.move.reconcile', 'Reconcile', readonly=True, ondelete='set null', select=2), 'reconcile_partial_id': fields.many2one('account.move.reconcile', 'Partial Reconcile', readonly=True, ondelete='set null', select=2), 'amount_currency': fields.float('Amount Currency', help="The amount expressed in an optional other currency if it is a multi-currency entry.", digits_compute=dp.get_precision('Account')), + 'amount_residual_currency': fields.function(_amount_residual, method=True, string='Residual Amount', multi="residual", help="The residual amount on a receivable or payable of a journal entry expressed in its currency (maybe different of the company currency)."), + 'amount_residual': fields.function(_amount_residual, method=True, string='Residual Amount', multi="residual", help="The residual amount on a receivable or payable of a journal entry expressed in the company currency."), 'currency_id': fields.many2one('res.currency', 'Currency', help="The optional other currency if it is a multi-currency entry."), 'period_id': fields.many2one('account.period', 'Period', required=True, select=2), 'journal_id': fields.many2one('account.journal', 'Journal', required=True, select=1), @@ -676,6 +729,7 @@ 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.reconcile_id: raise osv.except_osv(_('Warning'), _('Already Reconciled!')) if line.reconcile_partial_id: @@ -688,8 +742,7 @@ class account_move_line(osv.osv): else: unmerge.append(line.id) total += (line.debit or 0.0) - (line.credit or 0.0) - - if not total: + if self.pool.get('res.currency').is_zero(cr, uid, company_currency_id, total): res = self.reconcile(cr, uid, merges+unmerge, context=context) return res r_id = move_rec_obj.create(cr, uid, { @@ -771,6 +824,19 @@ class account_move_line(osv.osv): libelle = context['comment'] else: libelle = _('Write-Off') + + cur_obj = self.pool.get('res.currency') + cur_id = False + amount_currency_writeoff = 0.0 + if context.get('company_currency_id',False) != context.get('currency_id',False): + cur_id = context.get('currency_id',False) + for line in unrec_lines: + if line.currency_id and line.currency_id.id == context.get('currency_id',False): + amount_currency_writeoff += line.amount_currency + else: + tmp_amount = cur_obj.compute(cr, uid, line.account_id.company_id.currency_id.id, context.get('currency_id',False), abs(line.debit-line.credit), context={'date': line.date}) + amount_currency_writeoff += (line.debit > 0) and tmp_amount or -tmp_amount + writeoff_lines = [ (0, 0, { 'name': libelle, @@ -779,8 +845,8 @@ class account_move_line(osv.osv): 'account_id': account_id, 'date': date, 'partner_id': partner_id, - 'currency_id': account.currency_id.id or False, - 'amount_currency': account.currency_id.id and -currency or 0.0 + 'currency_id': cur_id or (account.currency_id.id or False), + 'amount_currency': amount_currency_writeoff and -1 * amount_currency_writeoff or (account.currency_id.id and -1 * currency or 0.0) }), (0, 0, { 'name': libelle, @@ -789,7 +855,9 @@ class account_move_line(osv.osv): 'account_id': writeoff_acc_id, 'analytic_account_id': context.get('analytic_id', False), 'date': date, - 'partner_id': partner_id + 'partner_id': partner_id, + 'currency_id': cur_id or (account.currency_id.id or False), + 'amount_currency': amount_currency_writeoff and amount_currency_writeoff or (account.currency_id.id and currency or 0.0) }) ] @@ -802,6 +870,8 @@ class account_move_line(osv.osv): }) writeoff_line_ids = self.search(cr, uid, [('move_id', '=', writeoff_move_id), ('account_id', '=', account_id)]) + if account_id == writeoff_acc_id: + writeoff_line_ids = [writeoff_line_ids[1]] ids += writeoff_line_ids r_id = move_rec_obj.create(cr, uid, { @@ -1283,4 +1353,4 @@ class account_move_line(osv.osv): account_move_line() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/invoice.py b/addons/account/invoice.py index f094e1c5f3b..f9bf0b26efc 100755 --- a/addons/account/invoice.py +++ b/addons/account/invoice.py @@ -88,32 +88,14 @@ class account_invoice(osv.osv): return [('none', _('Free Reference'))] def _amount_residual(self, cr, uid, ids, name, args, context=None): - res = {} - if context is None: - context = {} - - cur_obj = self.pool.get('res.currency') - data_inv = self.browse(cr, uid, ids, context=context) - for inv in data_inv: - if inv.reconciled: - res[inv.id] = 0.0 - continue - inv_total = inv.amount_total - context_unreconciled = context.copy() - for lines in inv.move_lines: - if lines.currency_id and lines.currency_id.id == inv.currency_id.id: - if inv.type in ('out_invoice','in_refund'): - inv_total += lines.amount_currency - else: - inv_total -= lines.amount_currency - else: - context_unreconciled.update({'date': lines.date}) - amount_in_invoice_currency = cur_obj.compute(cr, uid, inv.company_id.currency_id.id, inv.currency_id.id,abs(lines.debit-lines.credit),round=False,context=context_unreconciled) - inv_total -= amount_in_invoice_currency - - result = inv_total - res[inv.id] = self.pool.get('res.currency').round(cr, uid, inv.currency_id, result) - return res + result = {} + for invoice in self.browse(cr, uid, ids, context=context): + result[invoice.id] = 0.0 + if invoice.move_id: + for m in invoice.move_id.line_id: + if m.account_id.type in ('receivable','payable'): + result[invoice.id] = m.amount_residual_currency + return result # Give Journal Items related to the payment reconciled to this invoice # Return ids of partial and total payments related to the selected invoices diff --git a/addons/account/report/common_report_header.py b/addons/account/report/common_report_header.py index 809cb38e879..48e26e839d3 100755 --- a/addons/account/report/common_report_header.py +++ b/addons/account/report/common_report_header.py @@ -64,8 +64,8 @@ class common_report_header(object): def _get_target_move(self, data): if data.get('form', False) and data['form'].get('target_move', False): if data['form']['target_move'] == 'all': - return 'All Entries' - return 'All Posted Entries' + return _('All Entries') + return _('All Posted Entries') return '' def _get_end_date(self, data): @@ -94,10 +94,10 @@ class common_report_header(object): def _get_filter(self, data): if data.get('form', False) and data['form'].get('filter', False): if data['form']['filter'] == 'filter_date': - return 'Date' + return _('Date') elif data['form']['filter'] == 'filter_period': - return 'Periods' - return 'No Filter' + return _('Periods') + return _('No Filter') def _sum_debit_period(self, period_id, journal_id=None): journals = journal_id or self.journal_ids diff --git a/addons/account_voucher/account_voucher.py b/addons/account_voucher/account_voucher.py index fadef9a475f..5be5ed63cc1 100755 --- a/addons/account_voucher/account_voucher.py +++ b/addons/account_voucher/account_voucher.py @@ -27,25 +27,6 @@ from osv import osv, fields import decimal_precision as dp from tools.translate import _ -class account_move_line(osv.osv): - _inherit = 'account.move.line' - - def _unreconciled(self, cr, uid, ids, prop, unknow_none, context=None): - res = {} - for line in self.browse(cr, uid, ids, context=context): - res[line.id] = line.debit - line.credit - if line.reconcile_partial_id: - res[line.id] = 0 - for partial in line.reconcile_partial_id.line_partial_ids: - res[line.id] += partial.debit - partial.credit - res[line.id] = abs(res[line.id]) - return res - - _columns = { - 'amount_unreconciled': fields.function(_unreconciled, method=True, string='Unreconciled Amount'), - } - -account_move_line() class account_voucher(osv.osv): @@ -165,6 +146,8 @@ class account_voucher(osv.osv): return abs(amount - abs(credit - debit)) def onchange_line_ids(self, cr, uid, ids, line_dr_ids, line_cr_ids, amount): + if not line_dr_ids and not line_cr_ids: + return {'value':{}} line_dr_ids = [x[2] for x in line_dr_ids] line_cr_ids = [x[2] for x in line_cr_ids] return {'value': {'writeoff_amount': self._compute_writeoff_amount(cr, uid, line_dr_ids, line_cr_ids, amount)}} @@ -491,31 +474,32 @@ class account_voucher(osv.osv): continue total_credit += line.credit or 0.0 total_debit += line.debit or 0.0 - for line in moves: if line.credit and line.reconcile_partial_id and ttype == 'receipt': continue if line.debit and line.reconcile_partial_id and ttype == 'payment': continue - original_amount = line.credit or line.debit or 0.0 + amount_unreconciled = currency_pool.compute(cr, uid, line.currency_id and line.currency_id.id or company_currency, currency_id, abs(line.amount_residual_currency), context=context_multi_currency) rs = { 'name':line.move_id.name, 'type': line.credit and 'dr' or 'cr', 'move_line_id':line.id, 'account_id':line.account_id.id, - 'amount_original':currency_pool.compute(cr, uid, company_currency, currency_id, original_amount, context=context_multi_currency), + 'amount_original': currency_pool.compute(cr, uid, line.currency_id and line.currency_id.id or company_currency, currency_id, line.currency_id and abs(line.amount_currency) or original_amount, context=context_multi_currency), 'date_original':line.date, 'date_due':line.date_maturity, - 'amount_unreconciled':currency_pool.compute(cr, uid, company_currency, currency_id, line.amount_unreconciled, context=context_multi_currency) + 'amount_unreconciled': amount_unreconciled, + } + if line.credit: - amount = min(line.amount_unreconciled, total_debit) - rs['amount'] = currency_pool.compute(cr, uid, company_currency, currency_id, amount, context=context_multi_currency) + amount = min(amount_unreconciled, currency_pool.compute(cr, uid, company_currency, currency_id, abs(total_debit), context=context_multi_currency)) + rs['amount'] = amount total_debit -= amount else: - amount = min(line.amount_unreconciled, total_credit) - rs['amount'] = currency_pool.compute(cr, uid, company_currency, currency_id, amount, context=context_multi_currency) + amount = min(amount_unreconciled, currency_pool.compute(cr, uid, company_currency, currency_id, abs(total_credit), context=context_multi_currency)) + rs['amount'] = amount total_credit -= amount default['value']['line_ids'].append(rs) @@ -687,6 +671,7 @@ class account_voucher(osv.osv): debit = -credit credit = 0.0 sign = debit - credit < 0 and -1 or 1 + #create the first line of the voucher move_line = { 'name': inv.name or '/', 'debit': debit, @@ -701,9 +686,7 @@ class account_voucher(osv.osv): 'date': inv.date, 'date_maturity': inv.date_due } - if (debit == 0.0 or credit == 0.0 or debit+credit > 0) and (debit > 0.0 or credit > 0.0): - master_line = move_line_pool.create(cr, uid, move_line) - + move_line_pool.create(cr, uid, move_line) rec_list_ids = [] line_total = debit - credit if inv.type == 'sale': @@ -712,9 +695,14 @@ class account_voucher(osv.osv): line_total = line_total + currency_pool.compute(cr, uid, inv.currency_id.id, company_currency, inv.tax_amount, context=context_multi_currency) for line in inv.line_ids: + #create one move line per voucher line where amount is not 0.0 if not line.amount: continue - amount = currency_pool.compute(cr, uid, current_currency, company_currency, line.untax_amount or line.amount, context=context_multi_currency) + #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 = line.move_line_id.amount_residual #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) move_line = { 'journal_id': inv.journal_id.id, 'period_id': inv.period_id.id, @@ -753,9 +741,9 @@ class account_voucher(osv.osv): 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 0.0 - master_line = move_line_pool.create(cr, uid, move_line) + voucher_line = move_line_pool.create(cr, uid, move_line) if line.move_line_id.id: - rec_ids = [master_line, line.move_line_id.id] + rec_ids = [voucher_line, line.move_line_id.id] rec_list_ids.append(rec_ids) if not currency_pool.is_zero(cr, uid, inv.currency_id, line_total): @@ -764,7 +752,6 @@ class account_voucher(osv.osv): if inv.payment_option == 'with_writeoff': account_id = inv.writeoff_acc_id.id elif inv.type in ('sale', 'receipt'): -# if inv.journal_id.type in ('sale','sale_refund', 'cash', 'bank'): account_id = inv.partner_id.property_account_receivable.id else: account_id = inv.partner_id.property_account_payable.id @@ -776,12 +763,10 @@ class account_voucher(osv.osv): '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 currency_pool.compute(cr, uid, company_currency, current_currency, diff * -1, context=context_multi_currency) or 0.0, - 'currency_id': company_currency <> current_currency and current_currency or False, - 'analytic_account_id': inv.analytic_id.id, + #'amount_currency': company_currency <> current_currency and currency_pool.compute(cr, uid, company_currency, current_currency, diff * -1, context=context_multi_currency) or 0.0, + #'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], { 'move_id': move_id, 'state': 'posted', @@ -817,6 +802,8 @@ class account_voucher_line(osv.osv): currency_pool = self.pool.get('res.currency') rs_data = {} for line in self.browse(cr, uid, ids, context=context): + ctx = context.copy() + ctx.update({'date': line.voucher_id.date}) res = {} company_currency = line.voucher_id.journal_id.company_id.currency_id.id voucher_currency = line.voucher_id.currency_id.id @@ -826,13 +813,15 @@ class account_voucher_line(osv.osv): res['amount_original'] = 0.0 res['amount_unreconciled'] = 0.0 + elif move_line.currency_id: + res['amount_original'] = currency_pool.compute(cr, uid, move_line.currency_id.id, voucher_currency, move_line.amount_currency, context=ctx) elif move_line and move_line.credit > 0: - res['amount_original'] = currency_pool.compute(cr, uid, company_currency, voucher_currency, move_line.credit) + res['amount_original'] = currency_pool.compute(cr, uid, company_currency, voucher_currency, move_line.credit, context=ctx) else: - res['amount_original'] = currency_pool.compute(cr, uid, company_currency, voucher_currency, move_line.debit) + res['amount_original'] = currency_pool.compute(cr, uid, company_currency, voucher_currency, move_line.debit, context=ctx) if move_line: - res['amount_unreconciled'] = currency_pool.compute(cr, uid, company_currency, voucher_currency, move_line.amount_unreconciled) + res['amount_unreconciled'] = currency_pool.compute(cr, uid, move_line.currency_id and move_line.currency_id.id or company_currency, voucher_currency, abs(move_line.amount_residual_currency), context=ctx) rs_data[line.id] = res return rs_data diff --git a/addons/account_voucher/test/sales_receipt.yml b/addons/account_voucher/test/sales_receipt.yml index a1793527f67..d3fd720ec6d 100755 --- a/addons/account_voucher/test/sales_receipt.yml +++ b/addons/account_voucher/test/sales_receipt.yml @@ -3,7 +3,7 @@ - !record {model: account.voucher, id: account_voucher_seagate_0}: account_id: account.a_recv - amount: 0.0 + amount: 30000.0 company_id: base.main_company currency_id: base.EUR journal_id: account.sales_journal @@ -13,7 +13,6 @@ type: cr partner_id: base.res_partner_seagate period_id: account.period_9 - tax_amount: 0.0 type: sale - diff --git a/addons/account_voucher/voucher_payment_receipt_view.xml b/addons/account_voucher/voucher_payment_receipt_view.xml index 3a3e996975f..e73354eb59a 100755 --- a/addons/account_voucher/voucher_payment_receipt_view.xml +++ b/addons/account_voucher/voucher_payment_receipt_view.xml @@ -89,13 +89,13 @@