1 # -*- encoding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as
9 # published by the Free Software Foundation, either version 3 of the
10 # License, or (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ##############################################################################
23 from datetime import datetime
24 from dateutil.relativedelta import relativedelta
26 from osv import osv, fields
27 import decimal_precision as dp
29 class account_asset_category(osv.osv):
30 _name = 'account.asset.category'
31 _description = 'Asset category'
34 'name': fields.char('Name', size=64, required=True, select=1),
35 'note': fields.text('Note'),
36 'account_analytic_id': fields.many2one('account.analytic.account', 'Analytic account'),
37 'account_asset_id': fields.many2one('account.account', 'Asset Account', required=True),
38 'account_depreciation_id': fields.many2one('account.account', 'Depreciation Account', required=True),
39 'account_expense_depreciation_id': fields.many2one('account.account', 'Depr. Expense Account', required=True),
40 'journal_id': fields.many2one('account.journal', 'Journal', required=True),
41 'company_id': fields.many2one('res.company', 'Company', required=True),
42 'method': fields.selection([('linear','Linear'),('progressif','Progressive')], 'Computation method', required=True),
43 'method_delay': fields.integer('Number of Depreciations'),
44 'method_period': fields.integer('Period Length', help="State here the time between 2 depreciations, in months"),
45 'method_progress_factor': fields.float('Progressif Factor'),
46 'method_time': fields.selection([('delay','Delay'),('end','Ending Period')], 'Time Method', required=True),
47 'method_end': fields.date('Ending date'),
48 'prorata':fields.boolean('Prorata Temporis', help='Indicates that the accounting entries for this asset have to be done from the purchase date instead of the first January'),
49 'open_asset': fields.boolean('Skip Draft State', help="Check this if you want to automatically confirm the assets of this category when created by invoice."),
53 'company_id': lambda self, cr, uid, context: self.pool.get('res.company')._company_default_get(cr, uid, 'account.asset.category', context=context),
56 'method_time': 'delay',
58 'method_progress_factor': 0.3,
61 def onchange_account_asset(self, cr, uid, ids, account_asset_id, context=None):
64 res['value'] = {'account_depreciation_id': account_asset_id}
67 account_asset_category()
69 #class one2many_mod_asset(fields.one2many):
71 # def get(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None):
72 # prinasset_property_id if context is None:
79 # #compute depreciation board
80 # depreciation_line_ids = obj.pool.get('account.asset.asset').compute_depreciation_board(cr, user, ids, context=context)
81 # for key, value in depreciation_line_ids.items():
82 # #write values on asset
83 # obj.pool.get(self._obj).write(cr, user, key, {'depreciation_line_ids': [6,0,value]})
84 # return depreciation_line_ids
86 class account_asset_asset(osv.osv):
87 _name = 'account.asset.asset'
88 _description = 'Asset'
90 def _get_period(self, cr, uid, context={}):
91 periods = self.pool.get('account.period').find(cr, uid)
97 def _get_last_depreciation_date(self, cr, uid, ids, context=None):
99 @param id: ids of a account.asset.asset objects
100 @return: Returns a dictionary of the effective dates of the last depreciation entry made for given asset ids. If there isn't any, return the purchase date of this asset
103 SELECT a.id as id, COALESCE(MAX(l.date),a.purchase_date) AS date
104 FROM account_asset_asset a
105 LEFT JOIN account_move_line l ON (l.asset_id = a.id)
107 GROUP BY a.id, a.purchase_date """, (tuple(ids),))
108 return dict(cr.fetchall())
110 def _compute_board_amount(self, cr, uid, asset, i, residual_amount, amount_to_depr, undone_dotation_number, posted_depreciation_line_ids, total_days, depreciation_date, context=None):
111 #by default amount = 0
113 if i == undone_dotation_number:
114 amount = residual_amount
116 if asset.method == 'linear':
117 amount = amount_to_depr / (undone_dotation_number - len(posted_depreciation_line_ids))
119 amount = amount_to_depr / asset.method_delay
120 days = total_days - float(depreciation_date.strftime('%j'))
122 amount = (amount_to_depr / asset.method_delay) / total_days * days
123 elif i == undone_dotation_number:
124 amount = (amount_to_depr / asset.method_delay) / total_days * (total_days - days)
125 elif asset.method == 'degressive':
126 amount = residual_amount * asset.method_progress_factor
129 def _compute_board_undone_dotation_nb(self, cr, uid, asset, depreciation_date, total_days, context=None):
130 undone_dotation_number = asset.method_delay
131 if asset.method_time == 'end':
132 end_date = datetime.strptime(asset.method_end, '%Y-%m-%d')
133 undone_dotation_number = (end_date - depreciation_date).days / total_days
134 if asset.prorata or asset.method_time == 'end':
135 undone_dotation_number += 1
136 return undone_dotation_number
138 def compute_depreciation_board(self, cr, uid,ids, context=None):
139 depreciation_lin_obj = self.pool.get('account.asset.depreciation.line')
140 for asset in self.browse(cr, uid, ids, context=context):
141 if asset.value_residual == 0.0:
143 posted_depreciation_line_ids = depreciation_lin_obj.search(cr, uid, [('asset_id', '=', asset.id), ('move_check', '=', True)])
144 old_depreciation_line_ids = depreciation_lin_obj.search(cr, uid, [('asset_id', '=', asset.id), ('move_id', '=', False)])
145 if old_depreciation_line_ids:
146 depreciation_lin_obj.unlink(cr, uid, old_depreciation_line_ids, context=context)
148 amount_to_depr = residual_amount = asset.value_residual
150 depreciation_date = datetime.strptime(self._get_last_depreciation_date(cr, uid, [asset.id], context)[asset.id], '%Y-%m-%d')
151 day = depreciation_date.day
152 month = depreciation_date.month
153 year = depreciation_date.year
154 total_days = (year % 4) and 365 or 366
156 undone_dotation_number = self._compute_board_undone_dotation_nb(cr, uid, asset, depreciation_date, total_days, context=context)
157 for x in range(len(posted_depreciation_line_ids), undone_dotation_number):
159 amount = self._compute_board_amount(cr, uid, asset, i, residual_amount, amount_to_depr, undone_dotation_number, posted_depreciation_line_ids, total_days, depreciation_date, context=context)
160 residual_amount -= amount
163 'asset_id': asset.id,
165 'name': str(asset.id) +'/' + str(i),
166 'remaining_value': residual_amount,
167 'depreciated_value': (asset.purchase_value - asset.salvage_value) - (residual_amount + amount),
168 'depreciation_date': depreciation_date.strftime('%Y-%m-%d'),
170 depreciation_lin_obj.create(cr, uid, vals, context=context)
171 # Considering Depr. Period as months
172 depreciation_date = (datetime(year, month, day) + relativedelta(months=+asset.method_period))
173 day = depreciation_date.day
174 month = depreciation_date.month
175 year = depreciation_date.year
178 def validate(self, cr, uid, ids, context={}):
179 return self.write(cr, uid, ids, {
183 def _amount_residual(self, cr, uid, ids, name, args, context=None):
185 l.asset_id as id, round(SUM(abs(l.debit-l.credit))) AS amount
189 l.asset_id IN %s GROUP BY l.asset_id """, (tuple(ids),))
190 res=dict(cr.fetchall())
191 for asset in self.browse(cr, uid, ids, context):
192 res[asset.id] = asset.purchase_value - res.get(asset.id, 0.0) - asset.salvage_value
194 res.setdefault(id, 0.0)
198 'period_id': fields.many2one('account.period', 'First Period', required=True, readonly=True, states={'draft':[('readonly',False)]}),
199 'account_move_line_ids': fields.one2many('account.move.line', 'asset_id', 'Entries', readonly=True, states={'draft':[('readonly',False)]}),
201 'name': fields.char('Asset', size=64, required=True, select=1),
202 'code': fields.char('Reference ', size=16, select=1),
203 'purchase_value': fields.float('Gross value ', required=True, size=16, select=1),
204 'currency_id': fields.many2one('res.currency','Currency',required=True,size=5,select=1),
205 'company_id': fields.many2one('res.company', 'Company', required=True),
206 'note': fields.text('Note'),
207 'category_id': fields.many2one('account.asset.category', 'Asset category',required=True, change_default=True),
208 'localisation': fields.char('Localisation', size=32, select=2),
209 'parent_id': fields.many2one('account.asset.asset', 'Parent Asset'),
210 'child_ids': fields.one2many('account.asset.asset', 'parent_id', 'Children Assets'),
211 'purchase_date': fields.date('Purchase Date', required=True),
212 'state': fields.selection([('draft','Draft'),('open','Running'),('close','Close')], 'State', required=True),
213 'active': fields.boolean('Active', select=2),
214 'partner_id': fields.many2one('res.partner', 'Partner'),
215 'method': fields.selection([('linear','Linear'),('degressive','Degressive')], 'Computation Method', required=True, readonly=True, states={'draft':[('readonly',False)]}, help="Linear: Calculated on basis of Gross Value/During (interval) \
216 \nDegressive: Calculated on basis of Gross Value * Degressive Factor"),
217 'method_delay': fields.integer('Number of Depreciations', readonly=True, states={'draft':[('readonly',False)]}, help="Calculates Depreciation within specified interval"),
218 'method_period': fields.integer('Period Length', readonly=True, states={'draft':[('readonly',False)]}, help="State here the time during 2 depreciations, in months"),
219 'method_end': fields.date('Ending date', readonly=True, states={'draft':[('readonly',False)]}),
220 'method_progress_factor': fields.float('Progressif Factor', readonly=True, states={'draft':[('readonly',False)]}),
221 'value_residual': fields.function(_amount_residual, method=True, digits_compute=dp.get_precision('Account'), string='Residual Value'),
222 'method_time': fields.selection([('delay','Delay'),('end','Ending Period')], 'Time Method', required=True, readonly=True, states={'draft':[('readonly',False)]}, help="Delay: Allow users to enter number of periods to generate depreciation lines \n Ending Period: Calculates depreciation lines on the basis of Ending Period Date and Number of Depreciation"),
223 'prorata':fields.boolean('Prorata Temporis', Readonly="True", help='Indicates that the accounting entries for this asset have to be done from the purchase date instead of the first January'),
224 'history_ids': fields.one2many('account.asset.history', 'asset_id', 'History', readonly=True),
225 'depreciation_line_ids': fields.one2many('account.asset.depreciation.line', 'asset_id', 'Depreciation Lines'),
226 'salvage_value': fields.float('Salvage Value', digits_compute=dp.get_precision('Account'), help="It is the amount you plan to have that you cannot depreciate."),
229 'code': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'account.asset.code'),
230 'purchase_date': lambda obj, cr, uid, context: time.strftime('%Y-%m-%d'),
231 'active': lambda obj, cr, uid, context: True,
232 'state': lambda obj, cr, uid, context: 'draft',
233 'period_id': _get_period,
234 'method': lambda obj, cr, uid, context: 'linear',
235 'method_delay': lambda obj, cr, uid, context: 5,
236 'method_time': lambda obj, cr, uid, context: 'delay',
237 'method_period': lambda obj, cr, uid, context: 12,
238 'method_progress_factor': lambda obj, cr, uid, context: 0.3,
239 'currency_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.currency_id.id,
240 'company_id': lambda self, cr, uid, context: self.pool.get('res.company')._company_default_get(cr, uid, 'account.asset.asset',context=context),
243 def _check_recursion(self, cr, uid, ids, context=None, parent=None):
244 return super(account_asset_asset, self)._check_recursion(cr, uid, ids, context=context, parent=parent)
246 def _check_prorata(self, cr, uid, ids, context=None):
247 for asset in self.browse(cr, uid, ids, context=context):
248 if asset.prorata and (asset.method != 'linear' or asset.method_time != 'delay'):
253 (_check_recursion, 'Error ! You can not create recursive assets.', ['parent_id']),
254 (_check_prorata, '\nProrata temporis can be applied only for computation method linear and time method delay.', ['prorata']),
257 def onchange_category_id(self, cr, uid, ids, category_id, context=None):
259 asset_categ_obj = self.pool.get('account.asset.category')
261 category_obj = asset_categ_obj.browse(cr, uid, category_id, context=context)
263 'method': category_obj.method,
264 'method_delay': category_obj.method_delay,
265 'method_time': category_obj.method_time,
266 'method_period': category_obj.method_period,
267 'method_progress_factor': category_obj.method_progress_factor,
268 'method_end': category_obj.method_end,
269 'prorata': category_obj.prorata,
273 def onchange_method_time(self, cr, uid, ids, method='linear', method_time='delay', context=None):
275 if method != 'linear' or method_time != 'delay':
276 res['value'] = {'prorata': False}
279 def copy(self, cr, uid, id, default=None, context=None):
284 default.update({'depreciation_line_ids': [], 'state': 'draft'})
285 return super(account_asset_asset, self).copy(cr, uid, id, default, context=context)
287 def _compute_period(self, cr, uid, property, context={}):
288 if (len(property.entry_asset_ids or [])/2)>=property.method_delay:
290 if len(property.entry_asset_ids):
291 cp = property.entry_asset_ids[-1].period_id
292 cpid = self.pool.get('account.period').next(cr, uid, cp, property.method_period, context)
293 current_period = self.pool.get('account.period').browse(cr, uid, cpid, context)
295 current_period = property.asset_id.period_id
296 return current_period
298 def _compute_move(self, cr, uid, property, period, context={}):
299 #FIXME: fucntion not working OK
302 for move in property.asset_id.entry_ids:
303 total += move.debit-move.credit
304 for move in property.entry_asset_ids:
305 if move.account_id == property.account_asset_ids:
307 total += -move.credit
308 periods = (len(property.entry_asset_ids)/2) - property.method_delay
313 if property.method == 'linear':
314 amount = total / periods
316 amount = total * property.method_progress_factor
318 move_id = self.pool.get('account.move').create(cr, uid, {
319 'journal_id': property.journal_id.id,
320 'period_id': period.id,
321 'name': property.name or property.asset_id.name,
322 'ref': property.asset_id.code
325 id = self.pool.get('account.move.line').create(cr, uid, {
326 'name': property.name or property.asset_id.name,
328 'account_id': property.account_asset_id.id,
329 'debit': amount>0 and amount or 0.0,
330 'credit': amount<0 and -amount or 0.0,
331 'ref': property.asset_id.code,
332 'period_id': period.id,
333 'journal_id': property.journal_id.id,
334 'partner_id': property.asset_id.partner_id.id,
335 'date': time.strftime('%Y-%m-%d'),
337 id2 = self.pool.get('account.move.line').create(cr, uid, {
338 'name': property.name or property.asset_id.name,
340 'account_id': property.account_actif_id.id,
341 'credit': amount>0 and amount or 0.0,
342 'debit': amount<0 and -amount or 0.0,
343 'ref': property.asset_id.code,
344 'period_id': period.id,
345 'journal_id': property.journal_id.id,
346 'partner_id': property.asset_id.partner_id.id,
347 'date': time.strftime('%Y-%m-%d'),
350 self.pool.get('account.asset.asset').write(cr, uid, [property.id], {
351 'entry_asset_ids': [(4, id2, False),(4,id,False)]
353 if property.method_delay - (len(property.entry_asset_ids)/2)<=1:
354 #self.pool.get('account.asset.property')._close(cr, uid, property, context)
358 def _compute_entries(self, cr, uid, asset, period_id, context={}):
359 #FIXME: function not working CHECK all res
361 date_start = self.pool.get('account.period').browse(cr, uid, period_id, context).date_start
362 for property in asset.property_ids:
363 if property.state=='open':
364 period = self._compute_period(cr, uid, property, context)
365 if period and (period.date_start<=date_start):
366 result += self._compute_move(cr, uid, property, period, context)
368 account_asset_asset()
370 class account_asset_depreciation_line(osv.osv):
371 _name = 'account.asset.depreciation.line'
372 _description = 'Asset depreciation line'
374 def _get_move_check(self, cr, uid, ids, name, args, context=None):
376 for line in self.browse(cr, uid, ids, context=context):
377 res[line.id] = bool(line.move_id)
381 'name': fields.char('Depreciation Name', size=64, required=True, select=1),
382 'sequence': fields.integer('Sequence of the depreciation', required=True),
383 'asset_id': fields.many2one('account.asset.asset', 'Asset', required=True),
384 'amount': fields.float('Depreciation Amount', required=True),
385 'remaining_value': fields.float('Amount to Depreciate', required=True),
386 'depreciated_value': fields.float('Amount Already Depreciated', required=True),
387 'depreciation_date': fields.char('Depreciation Date', size=64, select=1),
388 'move_id': fields.many2one('account.move', 'Depreciation Entry'),
389 'move_check': fields.function(_get_move_check, method=True, type='boolean', string='Posted', store=True)
392 def create_move(self, cr, uid,ids, context=None):
395 asset_obj = self.pool.get('account.asset.asset')
396 period_obj = self.pool.get('account.period')
397 move_obj = self.pool.get('account.move')
398 move_line_obj = self.pool.get('account.move.line')
399 currency_obj = self.pool.get('res.currency')
400 for line in self.browse(cr, uid, ids, context=context):
401 depreciation_date = line.asset_id.prorata and line.asset_id.purchase_date or time.strftime('%Y-%m-%d')
402 period_ids = period_obj.find(cr, uid, depreciation_date, context=context)
403 company_currency = line.asset_id.company_id.currency_id.id
404 current_currency = line.asset_id.currency_id.id
405 context.update({'date': depreciation_date})
406 amount = currency_obj.compute(cr, uid, current_currency, company_currency, line.amount, context=context)
407 sign = line.asset_id.category_id.journal_id.type = 'purchase' and 1 or -1
410 'date': depreciation_date,
412 'period_id': period_ids and period_ids[0] or False,
413 'journal_id': line.asset_id.category_id.journal_id.id,
415 move_id = move_obj.create(cr, uid, move_vals, context=context)
416 move_line_obj.create(cr, uid, {
420 'account_id': line.asset_id.category_id.account_depreciation_id.id,
423 'period_id': period_ids and period_ids[0] or False,
424 'journal_id': line.asset_id.category_id.journal_id.id,
425 'partner_id': line.asset_id.partner_id.id,
426 'currency_id': company_currency <> current_currency and current_currency or False,
427 'amount_currency': company_currency <> current_currency and - sign * line.amount or 0.0,
428 'date': depreciation_date,
430 move_line_obj.create(cr, uid, {
434 'account_id': line.asset_id.category_id.account_expense_depreciation_id.id,
437 'period_id': period_ids and period_ids[0] or False,
438 'journal_id': line.asset_id.category_id.journal_id.id,
439 'partner_id': line.asset_id.partner_id.id,
440 'currency_id': company_currency <> current_currency and current_currency or False,
441 'amount_currency': company_currency <> current_currency and sign * line.amount or 0.0,
442 'analytic_account_id': line.asset_id.category_id.account_analytic_id.id,
443 'date': depreciation_date,
444 'asset_id': line.asset_id.id
446 self.write(cr, uid, line.id, {'move_id': move_id}, context=context)
449 account_asset_depreciation_line()
451 #class account_asset_property(osv.osv):
452 # def _amount_total(self, cr, uid, ids, name, args, context={}):
453 # id_set=",".join(map(str,ids))
454 # cr.execute("""SELECT l.asset_id,abs(SUM(l.debit-l.credit)) AS amount FROM
455 # account_asset_property p
457 # account_move_line l on (p.asset_id=l.asset_id)
458 # WHERE p.id IN ("""+id_set+") GROUP BY l.asset_id ")
459 # res=dict(cr.fetchall())
461 # res.setdefault(id, 0.0)
464 # def _close(self, cr, uid, property, context={}):
465 # if property.state<>'close':
466 # self.pool.get('account.asset.property').write(cr, uid, [property.id], {
469 # property.state='close'
470 # ok = property.asset_id.state=='open'
471 # for prop in property.asset_id.property_ids:
472 # ok = ok and prop.state=='close'
473 # self.pool.get('account.asset.asset').write(cr, uid, [property.asset_id.id], {
478 # _name = 'account.asset.property'
479 # _description = 'Asset property'
481 # 'name': fields.char('Method name', size=64, select=1),
482 # 'type': fields.selection([('direct','Direct'),('indirect','Indirect')], 'Depr. method type', select=2, required=True),
483 # 'asset_id': fields.many2one('account.asset.asset', 'Asset', required=True),
484 # 'account_asset_id': fields.many2one('account.account', 'Asset account', required=True),
485 # 'account_actif_id': fields.many2one('account.account', 'Depreciation account', required=True),
486 # 'journal_id': fields.many2one('account.journal', 'Journal', required=True),
487 # 'journal_analytic_id': fields.many2one('account.analytic.journal', 'Analytic journal'),
488 # 'account_analytic_id': fields.many2one('account.analytic.account', 'Analytic account'),
490 # 'method': fields.selection([('linear','Linear'),('progressif','Progressive')], 'Computation method', required=True, readonly=True, states={'draft':[('readonly',False)]}),
491 # 'method_delay': fields.integer('During', readonly=True, states={'draft':[('readonly',False)]}),
492 # 'method_period': fields.integer('Depre. all', readonly=True, states={'draft':[('readonly',False)]}),
493 # 'method_end': fields.date('Ending date'),
495 # 'date': fields.date('Date created'),
496 # #'test': fields.one2many('account.pre', 'asset_id', readonly=True, states={'draft':[('readonly',False)]}),
497 # 'entry_asset_ids': fields.many2many('account.move.line', 'account_move_asset_entry_rel', 'asset_property_id', 'move_id', 'Asset Entries'),
498 # 'board_ids': fields.one2many('account.asset.board', 'asset_id', 'Asset board'),
500 # 'value_total': fields.function(_amount_total, method=True, digits=(16,2),string='Gross value'),
501 # 'state': fields.selection([('draft','Draft'), ('open','Open'), ('close','Close')], 'State', required=True),
502 # 'history_ids': fields.one2many('account.asset.property.history', 'asset_property_id', 'History', readonly=True)
503 ## 'parent_id': fields.many2one('account.asset.asset', 'Parent asset'),
504 ## 'partner_id': fields.many2one('res.partner', 'Partner'),
505 ## 'note': fields.text('Note'),
509 # 'type': lambda obj, cr, uid, context: 'direct',
510 # 'state': lambda obj, cr, uid, context: 'draft',
511 # 'method': lambda obj, cr, uid, context: 'linear',
512 # 'method_time': lambda obj, cr, uid, context: 'delay',
513 # 'method_progress_factor': lambda obj, cr, uid, context: 0.3,
514 # 'method_delay': lambda obj, cr, uid, context: 5,
515 # 'method_period': lambda obj, cr, uid, context: 12,
516 # 'date': lambda obj, cr, uid, context: time.strftime('%Y-%m-%d')
518 #account_asset_property()
520 class account_move_line(osv.osv):
521 _inherit = 'account.move.line'
523 'asset_id': fields.many2one('account.asset.asset', 'Asset'),
524 'entry_ids': fields.one2many('account.move.line', 'asset_id', 'Entries', readonly=True, states={'draft':[('readonly',False)]}),
529 class account_asset_history(osv.osv):
530 _name = 'account.asset.history'
531 _description = 'Asset history'
533 'name': fields.char('History name', size=64, select=1),
534 'user_id': fields.many2one('res.users', 'User', required=True),
535 'date': fields.date('Date', required=True),
536 'asset_id': fields.many2one('account.asset.asset', 'Asset', required=True),
537 'method_time': fields.selection([('delay','Delay'),('end','Ending Period')], 'Time Method', required=True, help="Delay: Allow users to enter number of periods to generate depreciation lines \n Ending Period: Calculates depreciation lines on the basis of Ending Period Date and Number of Depreciations"),
538 'method_delay': fields.integer('Number of Depreciations'),
539 'method_period': fields.integer('Period Length', help="Time in month between two depreciations"),
540 'method_end': fields.date('Ending date'),
541 'note': fields.text('Note'),
545 'date': lambda *args: time.strftime('%Y-%m-%d'),
546 'user_id': lambda self, cr, uid, ctx: uid
549 account_asset_history()
551 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: