[IMP] account_asset: needed some improvements (described bellow)

- put Assets Entries and Deferred Entries in group_no_one and put them in adviser
   - in customer invoice, deferred revenue category in group_no_one cause taken from product
   - in form view of asset, depreciation information in an other tab
   - demo data : maintenance contract is a sale type
   - split tree view of asset to display different labels
   - depreciation board : no serial number, next period depreciation --> residual, ...
   - cumulative depreciation takes into account the current period
   - account.move and account.move line : wrong ref and name
   - cron to generates entries of assets (once a month)
   - reporting of assets analysis : remove date col, add unposted_value
This commit is contained in:
Martin Geubelle
2015-06-23 10:32:05 +02:00
committed by qdp-odoo
parent 3a966957ea
commit 056987d9ac
9 changed files with 108 additions and 84 deletions
+1
View File
@@ -36,6 +36,7 @@ Keeps track of the revenue recognition installments, and creates corresponding j
'views/account_asset_invoice_view.xml',
'report/account_asset_report_view.xml',
'views/account_asset.xml',
'account_asset_cron.xml',
],
'qweb': [
"static/src/xml/account_asset_template.xml",
+15 -12
View File
@@ -58,8 +58,8 @@ class AccountAssetAsset(models.Model):
account_move_line_ids = fields.One2many('account.move.line', 'asset_id', string='Entries', readonly=True, states={'draft': [('readonly', False)]})
entry_count = fields.Integer(compute='_entry_count', string='# Asset Entries')
name = fields.Char(string='Asset/Deferred Revenue Name', required=True, readonly=True, states={'draft': [('readonly', False)]})
code = fields.Char(string='Reference', size=32, readonly=True, states={'draft': [('readonly', False)]}, default=lambda self: self.env['ir.sequence'].next_by_code('account.asset.code'))
name = fields.Char(string='Asset Name', required=True, readonly=True, states={'draft': [('readonly', False)]})
code = fields.Char(string='Reference', size=32, readonly=True, states={'draft': [('readonly', False)]})
value = fields.Float(string='Gross Value', required=True, readonly=True, digits=0, states={'draft': [('readonly', False)]}, oldname='purchase_value')
currency_id = fields.Many2one('res.currency', string='Currency', required=True, readonly=True, states={'draft': [('readonly', False)]},
default=lambda self: self.env.user.company_id.currency_id.id)
@@ -104,6 +104,7 @@ class AccountAssetAsset(models.Model):
if asset.account_move_line_ids:
raise UserError(_('You cannot delete a document that contains posted lines.'))
return super(AccountAssetAsset, self).unlink()
@api.multi
def _get_last_depreciation_date(self):
"""
@@ -119,6 +120,11 @@ class AccountAssetAsset(models.Model):
result = dict(self.env.cr.fetchall())
return result
@api.model
def _cron_generate_entries(self):
assets = self.env['account.asset.asset'].search([('state', '=', 'open')])
assets._compute_entries(datetime.today())
def _compute_board_amount(self, sequence, residual_amount, amount_to_depr, undone_dotation_number, posted_depreciation_line_ids, total_days, depreciation_date):
amount = 0
if sequence == undone_dotation_number:
@@ -193,9 +199,9 @@ class AccountAssetAsset(models.Model):
'amount': amount,
'asset_id': self.id,
'sequence': sequence,
'name': (self.code or str(self.id)) + '/' + str(sequence),
'name': (self.code or '') + '/' + str(sequence),
'remaining_value': residual_amount,
'depreciated_value': (self.value - self.salvage_value) - (residual_amount + amount),
'depreciated_value': self.value - (self.salvage_value + residual_amount),
'depreciation_date': depreciation_date.strftime(DF),
}
commands.append((0, False, vals))
@@ -329,7 +335,7 @@ class AccountAssetDepreciationLine(models.Model):
parent_state = fields.Selection(related='asset_id.state', string='State of Asset')
amount = fields.Float(string='Current Depreciation', digits=0, required=True)
remaining_value = fields.Float(string='Next Period Depreciation', digits=0, required=True)
depreciated_value = fields.Float(string='Amount Already Depreciated', required=True)
depreciated_value = fields.Float(string='Cumulative Depreciation', required=True)
depreciation_date = fields.Date('Depreciation Date', index=True)
move_id = fields.Many2one('account.move', string='Depreciation Entry')
move_check = fields.Boolean(compute='_get_move_check', string='Posted', track_visibility='always', store=True)
@@ -349,16 +355,15 @@ class AccountAssetDepreciationLine(models.Model):
current_currency = line.asset_id.currency_id
amount = company_currency.compute(line.amount, current_currency)
sign = (line.asset_id.category_id.journal_id.type == 'purchase' or line.asset_id.category_id.journal_id.type == 'sale' and 1) or -1
asset_name = line.asset_id.name
reference = line.name
asset_name = line.asset_id.name + ' (%s/%s)' % (line.sequence, line.asset_id.method_number)
reference = line.asset_id.code
journal_id = line.asset_id.category_id.journal_id.id
partner_id = line.asset_id.partner_id.id
categ_type = line.asset_id.category_id.type
debit_account = line.asset_id.category_id.account_asset_id.id
credit_account = line.asset_id.category_id.account_depreciation_id.id
move_line_1 = {
'name': asset_name or reference,
'ref': reference,
'name': asset_name,
'account_id': credit_account,
'debit': 0.0,
'credit': amount,
@@ -371,8 +376,7 @@ class AccountAssetDepreciationLine(models.Model):
'asset_id': line.asset_id.id if categ_type == 'sale' else False,
}
move_line_2 = {
'name': asset_name or reference,
'ref': reference,
'name': asset_name,
'account_id': debit_account,
'credit': 0.0,
'debit': amount,
@@ -385,7 +389,6 @@ class AccountAssetDepreciationLine(models.Model):
'asset_id': line.asset_id.id if categ_type == 'purchase' else False
}
move_vals = {
'name': asset_name,
'ref': reference,
'date': depreciation_date or False,
'journal_id': line.asset_id.category_id.journal_id.id,
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding='UTF-8'?>
<odoo>
<record model="ir.cron" id="account_asset_cron">
<field name="name">Generate Asset Entries</field>
<field name="interval_number">1</field>
<field name="interval_type">months</field>
<field name="numbercall">-1</field>
<field name="doall" eval="False"/>
<field name="model" eval="'account.asset.asset'"/>
<field name="function" eval="'_cron_generate_entries'"/>
<field name="args" eval="'()'" />
</record>
</odoo>
+10 -7
View File
@@ -2,16 +2,17 @@
Creating demo data that require looking for accounts
-
!python {model: ir.model.data} : |
expenses_journal_id = self.pool.get('account.journal').search(cr, uid, [('type', '=', 'purchase')])
company = self.pool.get('res.users').browse(cr, uid, uid).company_id
journal_id = self.pool.get('account.journal').search(cr, uid, [('type', '=', 'general'), ('id', '!=', company.currency_exchange_journal_id.id)])
expense_account_id = self.pool.get('account.account').search(cr, uid, [('user_type', '=', ref('account.data_account_type_expenses'))])
xfa_account_id = self.pool.get('account.account').search(cr, uid, [('user_type', '=', ref('account.data_account_type_fixed_assets'))])
if not xfa_account_id:
xfa_account_id = self.pool.get('account.account').search(cr, uid, [('user_type', '=', ref('account.data_account_type_current_assets'))])
from datetime import datetime, timedelta
import time
if xfa_account_id and expense_account_id and expenses_journal_id:
if xfa_account_id and expense_account_id and journal_id:
vals = {
'journal_id': expenses_journal_id[0],
'journal_id': journal_id[0],
'name': 'Hardware - 3 Years',
'method_number': 3,
'account_asset_id': xfa_account_id[0],
@@ -20,7 +21,7 @@
}
self._update(cr, uid, 'account.asset.category', 'account_asset', vals, 'account_asset_category_fixedassets0')
vals = {
'journal_id': expenses_journal_id[0],
'journal_id': journal_id[0],
'name': 'Cars - 5 Years',
'method_number': 5,
'account_asset_id': xfa_account_id[0],
@@ -64,11 +65,13 @@
sale_account_id = self.pool.get('account.account').search(cr, uid, [('user_type', '=', ref('account.data_account_type_revenue'))])
if xfa_account_id and sale_account_id:
vals = {
'journal_id': expenses_journal_id[0],
'name': 'Revenue Recognition Maintenance Contract - 3 Years',
'method_number': 6,
'journal_id': journal_id[0],
'name': 'Revenue Recognition Maintenance Contract - 1 Years',
'method_number': 12,
'method_period': 1,
'account_asset_id': xfa_account_id[0],
'account_depreciation_id': xfa_account_id[0],
'account_income_recognition_id': sale_account_id[0],
'type': 'sale',
}
self._update(cr, uid, 'account.asset.category', 'account_asset', vals, 'account_asset_category_sale')
+7 -19
View File
@@ -70,28 +70,16 @@ class AccountInvoiceLine(models.Model):
asset.validate()
return True
@api.multi
def product_id_change(self, product, uom_id, qty=0, name='', type='out_invoice',
partner_id=False, fposition_id=False, price_unit=False, currency_id=False,
company_id=None, date_invoice=None):
res = super(AccountInvoiceLine, self).product_id_change(
product, uom_id, qty=qty, name=name, type=type, partner_id=partner_id,
fposition_id=fposition_id, price_unit=price_unit, currency_id=currency_id,
company_id=company_id, date_invoice=date_invoice
)
if product and res['value']:
product_obj = self.env['product.product'].browse(product)
if type == 'out_invoice':
res['value']['asset_category_id'] = product_obj.product_tmpl_id.deferred_revenue_category_id
elif type == 'in_invoice':
res['value']['asset_category_id'] = product_obj.product_tmpl_id.asset_category_id
return res
@api.onchange('product_id')
def onchange_product_id(self):
if self.product_id:
if self.invoice_id.type == 'out_invoice':
self.asset_category_id = self.product_id.product_tmpl_id.deferred_revenue_category_id
elif self.invoice_id.type == 'in_invoice':
self.asset_category_id = self.product_id.product_tmpl_id.asset_category_id
class ProductTemplate(models.Model):
_inherit = 'product.template'
asset_category_id = fields.Many2one('account.asset.category', string='Asset Type', ondelete="restrict")
deferred_revenue_category_id = fields.Many2one('account.asset.category', string='Deferred Revenue Type', ondelete="restrict")
@@ -7,10 +7,8 @@
<field name="arch" type="xml">
<pivot string="Assets Analysis" disable_linking="True">
<field name="asset_category_id" type="row"/>
<field name="date" type="col"/>
<field name="posted_value" type="measure"/>
<field name="gross_value" type="measure"/>
<field name="depreciation_value" type="measure"/>
<field name="unposted_value" type="measure"/>
</pivot>
</field>
</record>
@@ -20,8 +18,8 @@
<field name="arch" type="xml">
<graph string="Assets Analysis" type="pivot">
<field name="asset_category_id" type="row"/>
<field name="date" type="col"/>
<field name="gross_value" type="measure"/>
<field name="unposted_value" type="measure"/>
</graph>
</field>
</record>
@@ -157,12 +155,7 @@
<menuitem action="action_asset_asset_report"
id="menu_action_asset_asset_report"
parent="account.menu_finance_reports" sequence="21"/>
<!--
Asset Revenue Recognition Menu
-->
<menuitem action="action_asset_revenue_report"
id="menu_action_asset_revenue_report"
parent="account.menu_finance_reports" sequence="20"/>
parent="account.menu_finance_reports" sequence="22"/>
</odoo>
@@ -31,7 +31,7 @@
<field name="inherit_id" ref="account.invoice_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='invoice_line_ids']/tree/field[@name='quantity']" position="before">
<field string="Deferred Revenue Category" name="asset_category_id" domain="[('type','=','sale')]" context="{'default_type':'sale'}"/>
<field string="Deferred Revenue Category" name="asset_category_id" domain="[('type','=','sale')]" context="{'default_type':'sale'}" groups="base.group_no_one"/>
</xpath>
</field>
</record>
@@ -101,7 +101,7 @@
<sheet>
<div class="oe_button_box" name="button_box">
<button class="oe_stat_button" name="open_entries" type="object" icon="fa-pencil">
<field string="Entries" name="entry_count" widget="statinfo" />
<field string="Items" name="entry_count" widget="statinfo" />
</button>
</div>
<div class="oe_title">
@@ -121,21 +121,24 @@
<field name="currency_id" groups="base.group_multi_currency"/>
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
<field name="value" widget="monetary" options="{'currency_field': 'currency_id'}" help="Gross value of asset"/>
<field name="salvage_value" widget="monetary" options="{'currency_field': 'currency_id'}"/>
<field name="salvage_value" widget="monetary" options="{'currency_field': 'currency_id'}" attrs="{'invisible': [('type','=','sale')]}"/>
<field name="value_residual" widget="monetary" options="{'currency_field': 'currency_id'}"/>
<field name="partner_id" string="Partner"/>
<field name="invoice_id" string="Invoice" domain="[('invoice_line_ids.asset_category_id.type','=','purchase')]"/>
<div>
<label for="partner_id" string="Customer" attrs="{'invisible': [('type','==','purchase')]}"/>
<label for="partner_id" string="Supplier" attrs="{'invisible': [('type','!=','purchase')]}"/>
</div>
<field name="partner_id" string="Partner" nolabel="1"/>
<field name="invoice_id" string="Invoice"/>
</group>
</group>
<notebook colspan="4">
<page string="Depreciation Board">
<field name="depreciation_line_ids" mode="tree" options="{'reload_whole_on_button': true}">
<tree string="Depreciation Lines" decoration-info="(move_check == False)" create="false">
<field name="sequence" string="Serial Number"/>
<field name="depreciation_date"/>
<field name="depreciated_value" readonly="1"/>
<field name="amount" widget="monetary"/>
<field name="remaining_value" readonly="1" widget="monetary"/>
<field name="amount" widget="monetary" string="Depreciation"/>
<field name="remaining_value" readonly="1" widget="monetary" string="Residual"/>
<field name="move_check" invisible="1"/>
<field name="parent_state" invisible="1"/>
<button name="create_move" type="object" widget="widgetonbutton"/>
@@ -160,27 +163,26 @@
</form>
</field>
</page>
<page string="Depreciation Information">
<group>
<field name="method" widget="radio" attrs="{'invisible': [('type','=','sale')]}"/>
<field name="method_progress_factor" attrs="{'invisible':[('method','=','linear')], 'required':[('method','=','degressive')]}"/>
<label for="method_time"/>
<div>
<field name="method_time"/>
</div>
<field name="prorata" attrs="{'invisible': [('method_time','=','end')]}"/>
</group>
<group>
<field name="method_number" attrs="{'invisible':[('method_time','=','end')], 'required':[('method_time','=','number')]}"/>
<field name="method_period"/>
<field name="method_end" attrs="{'required': [('method_time','=','end')], 'invisible':[('method_time','=','number')]}"/>
</group>
</page>
<page string="History">
<field name="history_ids" readonly="1"/>
</page>
</notebook>
<separator string="Depreciation Information" colspan="4"/>
<group>
<group>
<field name="method" widget="radio" attrs="{'invisible': [('type','=','sale')]}"/>
<field name="method_progress_factor" attrs="{'invisible':[('method','=','linear')], 'required':[('method','=','degressive')]}"/>
<label for="method_time"/>
<div>
<field name="method_time"/>
</div>
<field name="prorata" attrs="{'invisible': [('method_time','=','end')]}"/>
</group>
<group>
<field name="method_number" attrs="{'invisible':[('method_time','=','end')], 'required':[('method_time','=','number')]}"/>
<field name="method_period"/>
<field name="method_end" attrs="{'required': [('method_time','=','end')], 'invisible':[('method_time','=','number')]}"/>
</group>
</group>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
@@ -190,15 +192,35 @@
</field>
</record>
<record model="ir.ui.view" id="view_account_asset_asset_tree">
<field name="name">account.asset.asset.tree</field>
<!-- We need to have 2 tree views to display different labels according to the asset type -->
<!-- Purchase -->
<record model="ir.ui.view" id="view_account_asset_asset_purchase_tree">
<field name="name">account.asset.asset.purchase.tree</field>
<field name="model">account.asset.asset</field>
<field name="arch" type="xml">
<tree string="Assets" decoration-info="(state == 'draft')" decoration-muted="(state == 'close')">
<field name="name"/>
<field name="category_id"/>
<field name="date"/>
<field name="partner_id"/>
<field name="partner_id" string="Supplier"/>
<field name="value"/>
<field name="value_residual" widget="monetary"/>
<field name="currency_id" groups="base.group_multi_currency"/>
<field name="company_id" groups="base.group_multi_company"/>
<field name="state"/>
</tree>
</field>
</record>
<!-- Sale -->
<record model="ir.ui.view" id="view_account_asset_asset_sale_tree">
<field name="name">account.asset.asset.sale.tree</field>
<field name="model">account.asset.asset</field>
<field name="arch" type="xml">
<tree string="Assets" decoration-info="(state == 'draft')" decoration-muted="(state == 'close')">
<field name="name" string="Revenue Name"/>
<field name="category_id"/>
<field name="date"/>
<field name="partner_id" string="Customer"/>
<field name="value"/>
<field name="value_residual" widget="monetary"/>
<field name="currency_id" groups="base.group_multi_currency"/>
@@ -308,10 +330,11 @@
</field>
</record>
<menuitem id="menu_finance_assets" name="Assets and Revenues" parent="account.menu_finance_entries" sequence="9" groups="account.group_account_user"/>
<record model="ir.actions.act_window" id="action_account_asset_asset_form">
<field name="name">Assets</field>
<field name="res_model">account.asset.asset</field>
<field name="view_type">form</field>
<field name="view_id" ref="view_account_asset_asset_purchase_tree"/>
<field name="domain">[('category_id.type', '=', 'purchase')]</field>
<field name="context">{'default_type': 'purchase', 'default_category_id_type': 'purchase'}</field>
</record>
@@ -322,13 +345,13 @@
<field name="name">Deferred Revenues</field>
<field name="res_model">account.asset.asset</field>
<field name="view_type">form</field>
<field name="view_id" ref="view_account_asset_asset_sale_tree"/>
<field name="domain">[('category_id.type', '=', 'sale')]</field>
<field name="context">{'default_type': 'sale', 'default_category_id_type': 'sale'}</field>
</record>
<menuitem parent="menu_finance_assets" id="menu_revenue_recognition" action="action_account_revenue_form" sequence="102"/>
<menuitem parent="menu_finance_assets" id="menu_action_account_asset_asset_form" action="action_account_asset_asset_form" sequence="104"/>
<menuitem parent="account.menu_finance_entries" id="menu_action_account_revenue_recognition" action="action_account_revenue_form" sequence="102" groups="account.group_account_user"/>
<menuitem parent="account.menu_finance_entries" id="menu_action_account_asset_asset_form" action="action_account_asset_asset_form" sequence="101" groups="account.group_account_user"/>
<!-- Configuration -->
@@ -43,12 +43,12 @@
<field name="context">{'asset_type': 'sale'}</field>
</record>
<menuitem name="Deferred Revenue Entries" action="action_recognition_depreciation_confirmation_wizard"
<menuitem name="Generate Deferred Revenue Entries" action="action_recognition_depreciation_confirmation_wizard"
id="menu_recognition_depreciation_confirmation_wizard"
parent="account.menu_finance_payables" sequence="2"/>
parent="account.menu_finance_entries" sequence="112" groups="base.group_no_one"/>
<menuitem name="Assets Entries" action="action_asset_depreciation_confirmation_wizard"
<menuitem name="Generate Assets Entries" action="action_asset_depreciation_confirmation_wizard"
id="menu_asset_depreciation_confirmation_wizard"
parent="account.menu_finance_receivables" sequence="1"/>
parent="account.menu_finance_entries" sequence="111" groups="base.group_no_one"/>
</odoo>