[IMP] account_voucher: improvements inj usability + changed the semantic of the payment_rate, which now depicts the rate of the payment_rate_currency_id against the voucher currency (instead of the main currency)
bzr revid: qdp-launchpad@openerp.com-20111130101110-p19ujgsaqgfnuv1r
This commit is contained in:
@@ -159,15 +159,6 @@ class account_voucher(osv.osv):
|
||||
res = super(account_voucher, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=submenu)
|
||||
doc = etree.XML(res['arch'])
|
||||
|
||||
# replace the label of the field payment_rate
|
||||
currency_obj = self.pool.get('res.currency')
|
||||
base_currency_id = currency_obj.search(cr, uid, [('rate','=',1.0),('rate_ids','=',1.0)], context=context)
|
||||
symbol = base_currency_id and currency_obj.name_get(cr, uid, base_currency_id, context=context)[0][1]
|
||||
string = _("Rate for this operation: 1 %s is") % symbol
|
||||
payment_rate_field = doc.xpath("//field[@name='payment_rate']")
|
||||
for field in payment_rate_field:
|
||||
field.set('string', string)
|
||||
|
||||
if context.get('type', 'sale') in ('purchase', 'payment'):
|
||||
nodes = doc.xpath("//field[@name='partner_id']")
|
||||
for node in nodes:
|
||||
@@ -183,17 +174,25 @@ class account_voucher(osv.osv):
|
||||
credit += l['amount']
|
||||
return abs(amount - abs(credit - debit))
|
||||
|
||||
def onchange_line_ids(self, cr, uid, ids, line_dr_ids, line_cr_ids, amount, context=None):
|
||||
def onchange_line_ids(self, cr, uid, ids, line_dr_ids, line_cr_ids, amount, voucher_currency, context=None):
|
||||
context = context or {}
|
||||
if not line_dr_ids and not line_cr_ids:
|
||||
return {'value':{}}
|
||||
line_osv = self.pool.get("account.voucher.line")
|
||||
line_dr_ids = resolve_o2m_operations(cr, uid, line_osv, line_dr_ids, ['amount'], context)
|
||||
line_cr_ids = resolve_o2m_operations(cr, uid, line_osv, line_cr_ids, ['amount'], context)
|
||||
return {'value': {'writeoff_amount': self._compute_writeoff_amount(cr, uid, line_dr_ids, line_cr_ids, amount)}}
|
||||
|
||||
#loop into the lines to see if there is an amount allocated on a voucher line with a currency different than the voucher currency
|
||||
is_multi_currency = False
|
||||
for voucher_line in line_dr_ids+line_cr_ids:
|
||||
if voucher_line.get('currency_id',False) != voucher_currency:
|
||||
is_multi_currency = True
|
||||
break
|
||||
return {'value': {'writeoff_amount': self._compute_writeoff_amount(cr, uid, line_dr_ids, line_cr_ids, amount), 'is_multi_currency': is_multi_currency}}
|
||||
|
||||
def _get_writeoff_amount(self, cr, uid, ids, name, args, context=None):
|
||||
if not ids: return {}
|
||||
currency_obj = self.pool.get('res.currency')
|
||||
res = {}
|
||||
debit = credit = 0.0
|
||||
for voucher in self.browse(cr, uid, ids, context=context):
|
||||
@@ -201,18 +200,24 @@ class account_voucher(osv.osv):
|
||||
debit += l.amount
|
||||
for l in voucher.line_cr_ids:
|
||||
credit += l.amount
|
||||
res[voucher.id] = abs(voucher.amount - abs(credit - debit))
|
||||
currency = voucher.currency_id or voucher.company_id.currency_id
|
||||
res[voucher.id] = currency_obj.round(cr, uid, currency, abs(voucher.amount - abs(credit - debit)))
|
||||
return res
|
||||
|
||||
def _paid_amount_in_company_currency(self, cr, uid, ids, name, args, context=None):
|
||||
if not ids: return {}
|
||||
res = {}
|
||||
debit = credit = 0.0
|
||||
voucher_rate = company_currency_rate = 1.0
|
||||
for voucher in self.browse(cr, uid, ids, context=context):
|
||||
rate = voucher.currency_id.rate or voucher.company_id.currency_id.rate
|
||||
if voucher.currency_id == voucher.payment_rate_currency_id:
|
||||
rate = voucher.payment_rate
|
||||
res[voucher.id] = voucher.amount / rate * voucher.company_id.currency_id.rate
|
||||
if voucher.currency_id:
|
||||
ctx = context.copy()
|
||||
ctx.update({'date': voucher.date})
|
||||
voucher_rate = self.browse(cr, uid, voucher.id, context=ctx).currency_id.rate
|
||||
if voucher.company_id.currency_id.id == voucher.payment_rate_currency_id.id:
|
||||
company_currency_rate = voucher.payment_rate
|
||||
else:
|
||||
company_currency_rate = voucher.company_id.currency_id.rate
|
||||
res[voucher.id] = voucher.amount / voucher_rate * company_currency_rate
|
||||
return res
|
||||
|
||||
_name = 'account.voucher'
|
||||
@@ -275,9 +280,10 @@ class account_voucher(osv.osv):
|
||||
'analytic_id': fields.many2one('account.analytic.account','Write-Off Analytic Account', readonly=True, states={'draft': [('readonly', False)]}),
|
||||
'writeoff_amount': fields.function(_get_writeoff_amount, string='Reconcile Amount', type='float', readonly=True),
|
||||
'payment_rate_currency_id': fields.many2one('res.currency', 'Payment Rate Currency', required=True, readonly=True, states={'draft':[('readonly',False)]}),
|
||||
'payment_rate': fields.float('Payment Rate', digits=(12,6), required=True, readonly=True, states={'draft': [('readonly', False)]},
|
||||
help='The specific rate that will be used for this voucher for the selected currency.'),
|
||||
'payment_rate': fields.float('Exchange Rate', digits=(12,6), required=True, readonly=True, states={'draft': [('readonly', False)]},
|
||||
help='The specific rate that will be used, in this voucher, between the selected currency (in \'Payment Rate Currency\' field) and the voucher currency.'),
|
||||
'paid_amount_in_company_currency': fields.function(_paid_amount_in_company_currency, string='Paid Amount in Company Currency', type='float', readonly=True),
|
||||
'is_multi_currency': fields.boolean('Multi Currency Voucher', help='Fields with internal purpose only that depicts if the voucher is a multi currency one or not'),
|
||||
}
|
||||
_defaults = {
|
||||
'period_id': _get_period,
|
||||
@@ -448,10 +454,15 @@ class account_voucher(osv.osv):
|
||||
return default
|
||||
|
||||
def onchange_rate(self, cr, uid, ids, rate, amount, currency_id, payment_rate_currency_id, company_id, context=None):
|
||||
res = {'value': {}}
|
||||
if rate and amount and currency_id and currency_id == payment_rate_currency_id:
|
||||
company_rate = self.pool.get('res.company').browse(cr, uid, company_id, context=context).currency_id.rate
|
||||
res['value']['paid_amount_in_company_currency'] = amount / rate * company_rate
|
||||
res = {'value': {'paid_amount_in_company_currency': amount}}
|
||||
company_currency = self.pool.get('res.company').browse(cr, uid, company_id, context=context).currency_id
|
||||
if rate and amount and currency_id:# and currency_id == payment_rate_currency_id:
|
||||
voucher_rate = self.pool.get('res.currency').browse(cr, uid, currency_id, context).rate
|
||||
if company_currency.id == payment_rate_currency_id:
|
||||
company_rate = rate
|
||||
else:
|
||||
company_rate = self.pool.get('res.company').browse(cr, uid, company_id, context=context).currency_id.rate
|
||||
res['value']['paid_amount_in_company_currency'] = amount / voucher_rate * company_rate
|
||||
return res
|
||||
|
||||
def onchange_amount(self, cr, uid, ids, amount, rate, partner_id, journal_id, currency_id, ttype, date, payment_rate_currency_id, company_id, context=None):
|
||||
@@ -578,6 +589,7 @@ class account_voucher(osv.osv):
|
||||
else:
|
||||
amount_original = currency_pool.compute(cr, uid, company_currency, currency_id, line.credit or line.debit or 0.0)
|
||||
amount_unreconciled = currency_pool.compute(cr, uid, company_currency, currency_id, abs(line.amount_residual))
|
||||
currency_id = line.currency_id and line.currency_id.id or line.company_id.currency_id.id
|
||||
rs = {
|
||||
'name':line.move_id.name,
|
||||
'type': line.credit and 'dr' or 'cr',
|
||||
@@ -588,6 +600,7 @@ class account_voucher(osv.osv):
|
||||
'date_original':line.date,
|
||||
'date_due':line.date_maturity,
|
||||
'amount_unreconciled': amount_unreconciled,
|
||||
'currency_id': currency_id,
|
||||
}
|
||||
|
||||
#split voucher amount by most old first, but only for lines in the same currency
|
||||
@@ -650,7 +663,9 @@ class account_voucher(osv.osv):
|
||||
res['value'].update({'period_id':pids[0]})
|
||||
if payment_rate_currency_id:
|
||||
ctx.update({'date': date})
|
||||
payment_rate = self.pool.get('res.currency').browse(cr, uid, payment_rate_currency_id, context=ctx).rate
|
||||
payment_rate = 1.0
|
||||
if payment_rate_currency_id != currency_id:
|
||||
payment_rate = self.pool.get('res.currency').browse(cr, uid, payment_rate_currency_id, context=ctx).rate
|
||||
vals = self.onchange_payment_rate_currency(cr, uid, ids, currency_id, payment_rate, payment_rate_currency_id, date, amount, company_id, context=context)
|
||||
vals['value'].update({'payment_rate': payment_rate})
|
||||
for key in vals.keys():
|
||||
@@ -674,12 +689,13 @@ class account_voucher(osv.osv):
|
||||
currency_id = journal.currency.id
|
||||
ctx = context.copy()
|
||||
ctx.update({'date': date})
|
||||
payment_rate = self.pool.get('res.currency').browse(cr, uid, currency_id, context=ctx).rate
|
||||
vals['value'].update({'payment_rate': payment_rate})
|
||||
#on change of the journal, we need to TODO coment me
|
||||
payment_rate = 1.0
|
||||
|
||||
res = self.onchange_rate(cr, uid, ids, payment_rate, amount, currency_id, currency_id, company_id, context=ctx)
|
||||
for key in res.keys():
|
||||
vals[key].update(res[key])
|
||||
if currency_id:
|
||||
vals['value'].update({'payment_rate': payment_rate})
|
||||
vals['value'].update({'currency_id': currency_id})
|
||||
vals['value'].update({'payment_rate_currency_id': currency_id})
|
||||
res = self.onchange_partner_id(cr, uid, ids, partner_id, journal_id, amount, currency_id, ttype, date, context)
|
||||
@@ -912,12 +928,7 @@ class account_voucher(osv.osv):
|
||||
# the rate specified on the voucher is for the company currency
|
||||
rate_between_voucher_and_base = voucher.currency_id.rate or 1.0
|
||||
rate_between_base_and_company = voucher.payment_rate or 1.0
|
||||
res = amount / rate_between_voucher_and_base * rate_between_base_and_company
|
||||
elif voucher.payment_rate_currency_id.id == voucher.currency_id.id:
|
||||
# the rate specified on the voucher is for the voucher currency
|
||||
rate_between_base_and_company = voucher.company_id.currency_id.rate or 1.0
|
||||
rate_between_voucher_and_base = voucher.payment_rate or 1.0
|
||||
res = amount / rate_between_voucher_and_base * rate_between_base_and_company
|
||||
res = currency_obj.round(cr, uid, voucher.company_id.currency_id, (amount / rate_between_voucher_and_base * rate_between_base_and_company))
|
||||
else:
|
||||
# the rate specified on the voucher is not relevant, we use all the rates in the system
|
||||
res = currency_obj.compute(cr, uid, voucher.currency_id.id, voucher.company_id.currency_id.id, amount, context=context)
|
||||
@@ -997,7 +1008,7 @@ class account_voucher(osv.osv):
|
||||
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))
|
||||
|
||||
# compute the amount in foreign currency.
|
||||
# compute the amount in foreign currency
|
||||
amount_currency = False
|
||||
if line.move_line_id:
|
||||
# We want to set it on the account move line as soon as the original line had a foreign currency
|
||||
@@ -1200,6 +1211,20 @@ class account_voucher_line(osv.osv):
|
||||
rs_data[line.id] = res
|
||||
return rs_data
|
||||
|
||||
def _currency_id(self, cr, uid, ids, name, args, context=None):
|
||||
'''
|
||||
This function returns the currency id of a voucher line. It's either the currency of the
|
||||
associated move line (if any) or the currency of the voucher or the company currency.
|
||||
'''
|
||||
res = {}
|
||||
for line in self.browse(cr, uid, ids, context=context):
|
||||
move_line = line.move_line_id
|
||||
if move_line:
|
||||
res[line.id] = move_line.currency_id and move_line.currency_id.id or move_line.company_id.currency_id.id
|
||||
else:
|
||||
res[line.id] = line.voucher_id.currency_id and line.voucher_id.currency_id.id or line.voucher_id.company_id.currency_id.id
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'voucher_id':fields.many2one('account.voucher', 'Voucher', required=1, ondelete='cascade'),
|
||||
'name':fields.char('Description', size=256),
|
||||
@@ -1216,6 +1241,7 @@ class account_voucher_line(osv.osv):
|
||||
'amount_original': fields.function(_compute_balance, multi='dc', type='float', string='Original Amount', store=True),
|
||||
'amount_unreconciled': fields.function(_compute_balance, multi='dc', type='float', string='Open Balance', store=True),
|
||||
'company_id': fields.related('voucher_id','company_id', relation='res.company', type='many2one', string='Company', store=True, readonly=True),
|
||||
'currency_id': fields.function(_currency_id, string='Currency', type='many2one', relation='res.currency', readonly=True),
|
||||
}
|
||||
_defaults = {
|
||||
'name': '',
|
||||
@@ -1252,10 +1278,10 @@ class account_voucher_line(osv.osv):
|
||||
ttype = 'dr'
|
||||
else:
|
||||
ttype = 'cr'
|
||||
account_id = move_line.account_id.id
|
||||
res.update({
|
||||
'account_id':account_id,
|
||||
'type': ttype
|
||||
'account_id': move_line.account_id.id,
|
||||
'type': ttype,
|
||||
'currency_id': move_line.currency_id and move_line.currency_id.id or move_line.company_id.currency_id.id,
|
||||
})
|
||||
return {
|
||||
'value':res,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
-
|
||||
Demo for Account Voucher
|
||||
-
|
||||
!record {model: account.voucher, id: account_voucher_voucheraxelor0}:
|
||||
!record {model: account.voucher, id: account_voucher_voucheraxelor0again}:
|
||||
account_id: account.cash
|
||||
company_id: base.main_company
|
||||
journal_id: account.bank_journal
|
||||
@@ -19,6 +19,6 @@
|
||||
-
|
||||
!python {model: account.voucher}: |
|
||||
import netsvc, tools, os
|
||||
(data, format) = netsvc.LocalService('report.voucher.cash_receipt.drcr').create(cr, uid, [ref("account_voucher_voucheraxelor0")], {}, {})
|
||||
(data, format) = netsvc.LocalService('report.voucher.cash_receipt.drcr').create(cr, uid, [ref("account_voucher_voucheraxelor0again")], {}, {})
|
||||
if tools.config['test_report_directory']:
|
||||
file(os.path.join(tools.config['test_report_directory'], 'account_voucher-report.'+format), 'wb+').write(data)
|
||||
|
||||
@@ -128,6 +128,8 @@
|
||||
for item in voucher_id.line_cr_ids:
|
||||
if item.amount_unreconciled == 186.74:
|
||||
data += [(item.id, 186.74)]
|
||||
else:
|
||||
data += [(item.id, 0.0)]
|
||||
for line_id, amount in data:
|
||||
self.pool.get('account.voucher.line').write(cr, uid, [line_id], {'amount': amount})
|
||||
assert (voucher_id.state=='draft'), "Voucher is not in draft state"
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Payment Information">
|
||||
<field name="line_dr_ids" attrs="{'invisible': [('type', '=', 'receipt')]}" default_get="{'journal_id':journal_id, 'type':type, 'partner_id':partner_id}" colspan="4" nolabel="1" height="140" on_change="onchange_line_ids(line_dr_ids, line_cr_ids, amount, context)">
|
||||
<field name="line_dr_ids" attrs="{'invisible': [('type', '=', 'receipt')]}" default_get="{'journal_id':journal_id, 'type':type, 'partner_id':partner_id}" colspan="4" nolabel="1" height="140" on_change="onchange_line_ids(line_dr_ids, line_cr_ids, amount, currency_id, context)">
|
||||
<tree string="Open Supplier Journal Entries" editable="bottom" colors="gray:amount==0">
|
||||
<field name="move_line_id" context="{'journal_id':parent.journal_id, 'partner_id':parent.partner_id}"
|
||||
on_change="onchange_move_line_id(move_line_id)"
|
||||
@@ -106,7 +106,7 @@
|
||||
<field name="amount" sum="Payment"/>
|
||||
</tree>
|
||||
</field>
|
||||
<field name="line_cr_ids" colspan="4" nolabel="1" attrs="{'invisible': [('type', '=', 'payment')]}" default_get="{'journal_id':journal_id, 'partner_id':partner_id}" on_change="onchange_line_ids(line_dr_ids, line_cr_ids, amount, context)">
|
||||
<field name="line_cr_ids" colspan="4" nolabel="1" attrs="{'invisible': [('type', '=', 'payment')]}" default_get="{'journal_id':journal_id, 'partner_id':partner_id}" on_change="onchange_line_ids(line_dr_ids, line_cr_ids, amount, currency_id, context)">
|
||||
<tree string="Open Customer Journal Entries" editable="bottom" colors="gray:amount==0">
|
||||
<field name="move_line_id" context="{'journal_id':parent.journal_id, 'partner_id':parent.partner_id}"
|
||||
on_change="onchange_move_line_id(move_line_id)"
|
||||
@@ -129,7 +129,7 @@
|
||||
<field name="currency_id" colspan="4"/>
|
||||
<field name="payment_rate" required="1" on_change="onchange_rate(payment_rate, amount, currency_id, payment_rate_currency_id, company_id, context)" groups='base.group_extended' colspan="3"/>
|
||||
<field name="payment_rate_currency_id" groups='base.group_extended' colspan="1" nolabel="1" on_change="onchange_payment_rate_currency(currency_id, payment_rate, payment_rate_currency_id, date, amount, company_id, context)"/>
|
||||
<field name="paid_amount_in_company_currency" groups='base.group_extended' colspan="4"/>
|
||||
<field name="paid_amount_in_company_currency" groups='base.group_extended' colspan="4" invisible="1"/>
|
||||
<field name="number" colspan="4"/>
|
||||
</group>
|
||||
</page>
|
||||
@@ -203,11 +203,11 @@
|
||||
<field name="narration" colspan="2" nolabel="1"/>
|
||||
</group>
|
||||
<group col="2" colspan="1">
|
||||
<group col="4" colspan="1" attrs="{'invisible':[('currency_id','=',False)]}">
|
||||
<group col="4" colspan="1" attrs="{'invisible':[('currency_id','=',False),('is_multi_currency','=',False)]}">
|
||||
<separator string="Currency Options" colspan="4"/>
|
||||
<field name="payment_rate" required="1" on_change="onchange_rate(payment_rate, amount, currency_id, payment_rate_currency_id, company_id, context)" groups='base.group_extended' colspan="3"/>
|
||||
<field name="payment_rate_currency_id" groups='base.group_extended' colspan="1" nolabel="1" on_change="onchange_payment_rate_currency(currency_id, payment_rate, payment_rate_currency_id, date, amount, company_id, context)"/>
|
||||
<field name="paid_amount_in_company_currency" groups='base.group_extended' colspan="4"/>
|
||||
<field name="paid_amount_in_company_currency" groups='base.group_extended' colspan="4" invisible="1"/>
|
||||
</group>
|
||||
<group col="2" colspan="1">
|
||||
<separator string="Payment Options" colspan="2"/>
|
||||
@@ -318,7 +318,7 @@
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Payment Information">
|
||||
<field name="line_cr_ids" default_get="{'journal_id':journal_id, 'type':type, 'partner_id':partner_id}" colspan="4" nolabel="1" height="140" on_change="onchange_line_ids(line_dr_ids, line_cr_ids, amount, context)">
|
||||
<field name="line_cr_ids" default_get="{'journal_id':journal_id, 'type':type, 'partner_id':partner_id}" colspan="4" nolabel="1" height="140" on_change="onchange_line_ids(line_dr_ids, line_cr_ids, amount, currency_id, context)">
|
||||
<tree string="Invoices and outstanding transactions" editable="bottom" colors="gray:amount==0">
|
||||
<field name="move_line_id" context="{'journal_id':parent.journal_id, 'partner_id':parent.partner_id}"
|
||||
on_change="onchange_move_line_id(move_line_id)"
|
||||
@@ -334,7 +334,7 @@
|
||||
<field name="amount" sum="Payment" on_change="onchange_amount(amount, amount_unreconciled, context)"/>
|
||||
</tree>
|
||||
</field>
|
||||
<field name="line_dr_ids" colspan="4" nolabel="1" attrs="{'invisible': [('pre_line','=',False)]}" default_get="{'journal_id':journal_id, 'partner_id':partner_id}" on_change="onchange_line_ids(line_dr_ids, line_cr_ids, amount, context)">
|
||||
<field name="line_dr_ids" colspan="4" nolabel="1" attrs="{'invisible': [('pre_line','=',False)]}" default_get="{'journal_id':journal_id, 'partner_id':partner_id}" on_change="onchange_line_ids(line_dr_ids, line_cr_ids, amount, currency_id, context)">
|
||||
<tree string="Credits" editable="bottom" colors="gray:amount==0">
|
||||
<field name="move_line_id" context="{'journal_id':parent.journal_id, 'partner_id':parent.partner_id}"
|
||||
on_change="onchange_move_line_id(move_line_id)"
|
||||
@@ -355,11 +355,11 @@
|
||||
<field name="narration" colspan="2" nolabel="1"/>
|
||||
</group>
|
||||
<group col="2" colspan="1">
|
||||
<group col="4" colspan="1" attrs="{'invisible':[('currency_id','=',False)]}">
|
||||
<group col="4" colspan="1" attrs="{'invisible':[('currency_id','=',False),('is_multi_currency','=',False)]}">
|
||||
<separator string="Currency Options" colspan="4"/>
|
||||
<field name="payment_rate" required="1" on_change="onchange_rate(payment_rate, amount, currency_id, payment_rate_currency_id, company_id, context)" groups='base.group_extended' colspan="3"/>
|
||||
<field name="payment_rate_currency_id" groups='base.group_extended' colspan="1" nolabel="1" on_change="onchange_payment_rate_currency(currency_id, payment_rate, payment_rate_currency_id, date, amount, company_id, context)"/>
|
||||
<field name="paid_amount_in_company_currency" groups='base.group_extended' colspan="4"/>
|
||||
<field name="paid_amount_in_company_currency" groups='base.group_extended' colspan="4" invisible="1"/>
|
||||
</group>
|
||||
<group col="2" colspan="1">
|
||||
<separator string="Payment Options" colspan="2"/>
|
||||
|
||||
Reference in New Issue
Block a user