[IMP] project,hr_timesheet: move analytic account business to project

When we remove the inheritS between project and analytic account, we move the
analytic_accound_id field in timesheet because it was the only use case for
a project to be linked to an analytic account.
This commit prepares new cost origin for a project (other that timesheet).
Register costs on project will required an analytic account to keep analytic
costs tracking. The analytic account management is now moved to project, like
it was in 10.0, but without the inheritS.

Task-1911581
This commit is contained in:
jem-odoo
2019-05-24 09:20:06 +00:00
parent 299a61ecbc
commit db92ca5fce
12 changed files with 77 additions and 63 deletions
-1
View File
@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import analytic_account
from . import hr
from . import hr_timesheet
from . import ir_http
+4 -29
View File
@@ -9,9 +9,6 @@ class Project(models.Model):
_inherit = "project.project"
allow_timesheets = fields.Boolean("Allow timesheets", default=True, help="Enable timesheeting on the project.")
analytic_account_id = fields.Many2one('account.analytic.account', string="Analytic Account", copy=False, ondelete='set null',
help="Analytic account to which this project is linked for financial management."
"Use an analytic account to record cost and revenue on your project.")
@api.onchange('partner_id')
def _onchange_partner_id(self):
@@ -47,12 +44,7 @@ class Project(models.Model):
"""
allow_timesheets = values['allow_timesheets'] if 'allow_timesheets' in values else self.default_get(['allow_timesheets'])['allow_timesheets']
if allow_timesheets and not values.get('analytic_account_id'):
analytic_account = self.env['account.analytic.account'].create({
'name': values.get('name', _('Unknown Analytic Account')),
'company_id': values.get('company_id', self.env.company_id.id),
'partner_id': values.get('partner_id'),
'active': True,
})
analytic_account = self._create_analytic_account_from_values(values)
values['analytic_account_id'] = analytic_account.id
return super(Project, self).create(values)
@@ -66,31 +58,14 @@ class Project(models.Model):
result = super(Project, self).write(values)
return result
@api.multi
def unlink(self):
""" Delete the empty related analytic account """
analytic_accounts_to_delete = self.env['account.analytic.account']
for project in self:
if project.analytic_account_id and not project.analytic_account_id.line_ids:
analytic_accounts_to_delete |= project.analytic_account_id
result = super(Project, self).unlink()
analytic_accounts_to_delete.unlink()
return result
# ---------------------------------------------------
# Business Methods
# ---------------------------------------------------
@api.model
def _init_data_analytic_account(self):
self.search([('analytic_account_id', '=', False), ('allow_timesheets', '=', True)])._create_analytic_account()
def _create_analytic_account(self):
for project in self:
analytic_account = self.env['account.analytic.account'].create({
'name': project.name,
'company_id': project.company_id.id,
'partner_id': project.partner_id.id,
'active': True,
})
project.write({'analytic_account_id': analytic_account.id})
class Task(models.Model):
_inherit = "project.task"
@@ -2,10 +2,6 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_account_analytic_line_user,analytic.account.analytic.line.timesheet.user,analytic.model_account_analytic_line,hr_timesheet.group_hr_timesheet_user,1,1,1,1
access_account_analytic_line_portal,access_timesheets_portal,analytic.model_account_analytic_line,base.group_portal,1,0,0,0
access_account_analytic_user,analytic.account.analytic.timesheet.user,analytic.model_account_analytic_account,hr_timesheet.group_hr_timesheet_user,1,1,0,0
access_account_analytic_account_user,account.analytic.account,analytic.model_account_analytic_account,project.group_project_user,1,0,0,0
access_account_analytic_account_manager,account.analytic.account,analytic.model_account_analytic_account,project.group_project_manager,1,1,1,1
access_account_analytic_account_portal,account_analytic_account,analytic.model_account_analytic_account,base.group_portal,1,0,0,0
access_account_analytic_line_project,account.analytic.line project,analytic.model_account_analytic_line,project.group_project_manager,1,1,1,1
access_uom_uom_hr_timesheet,uom.uom.timesheet.user,uom.model_uom_uom,hr_timesheet.group_hr_timesheet_user,1,0,0,0
access_project_project,project.project.timesheet.user,model_project_project,hr_timesheet.group_hr_timesheet_user,1,0,0,0
access_project_task,project.task.timesheet.user,model_project_task,hr_timesheet.group_hr_timesheet_user,1,1,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_account_analytic_line_user analytic.account.analytic.line.timesheet.user analytic.model_account_analytic_line hr_timesheet.group_hr_timesheet_user 1 1 1 1
3 access_account_analytic_line_portal access_timesheets_portal analytic.model_account_analytic_line base.group_portal 1 0 0 0
4 access_account_analytic_user analytic.account.analytic.timesheet.user analytic.model_account_analytic_account hr_timesheet.group_hr_timesheet_user 1 1 0 0
access_account_analytic_account_user account.analytic.account analytic.model_account_analytic_account project.group_project_user 1 0 0 0
access_account_analytic_account_manager account.analytic.account analytic.model_account_analytic_account project.group_project_manager 1 1 1 1
access_account_analytic_account_portal account_analytic_account analytic.model_account_analytic_account base.group_portal 1 0 0 0
access_account_analytic_line_project account.analytic.line project analytic.model_account_analytic_line project.group_project_manager 1 1 1 1
5 access_uom_uom_hr_timesheet uom.uom.timesheet.user uom.model_uom_uom hr_timesheet.group_hr_timesheet_user 1 0 0 0
6 access_project_project project.project.timesheet.user model_project_project hr_timesheet.group_hr_timesheet_user 1 0 0 0
7 access_project_task project.task.timesheet.user model_project_task hr_timesheet.group_hr_timesheet_user 1 1 0 0
@@ -1,24 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!--
Analytic Accounts with project
-->
<record id="account_analytic_account_view_form_inherit" model="ir.ui.view">
<field name="name">account.analytic.account.form.inherit</field>
<field name="model">account.analytic.account</field>
<field name="inherit_id" ref="analytic.view_account_analytic_account_form"/>
<field eval="18" name="priority"/>
<field name="arch" type="xml">
<xpath expr="//button[@name='toggle_active']" position="before">
<button class="oe_stat_button" type="object" name="action_view_projects"
icon="fa-puzzle-piece" attrs="{'invisible': [('project_count', '=', 0)]}">
<field string="Projects" name="project_count" widget="statinfo"/>
</button>
</xpath>
</field>
</record>
<!-- Timesheet root menus -->
<menuitem id="timesheet_menu_root"
@@ -45,9 +45,6 @@
<xpath expr="//group[@name='extra_settings']" position="inside">
<field name="allow_timesheets"/>
</xpath>
<xpath expr="//field[@name='partner_id']" position="after">
<field name="analytic_account_id" groups="analytic.group_analytic_accounting" />
</xpath>
</field>
</record>
+2
View File
@@ -9,6 +9,7 @@
'sequence': 10,
'summary': 'Organize and schedule your projects ',
'depends': [
'analytic',
'base_setup',
'mail',
'portal',
@@ -23,6 +24,7 @@
'security/project_security.xml',
'security/ir.model.access.csv',
'report/project_report_views.xml',
'views/analytic_views.xml',
'views/digest_views.xml',
'views/rating_views.xml',
'views/project_views.xml',
+1
View File
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import analytic_account
from . import project
from . import res_config_settings
from . import res_partner
+43 -7
View File
@@ -80,13 +80,6 @@ class Project(models.Model):
values['alias_defaults'] = {'project_id': self.id}
return values
@api.multi
def unlink(self):
for project in self:
if project.tasks:
raise UserError(_('You cannot delete a project containing tasks. You can either archive it or first delete all of its tasks.'))
return super(Project, self).unlink()
def _compute_attached_docs_count(self):
Attachment = self.env['ir.attachment']
for project in self:
@@ -180,6 +173,9 @@ class Project(models.Model):
partner_id = fields.Many2one('res.partner', string='Customer', auto_join=True, tracking=True)
company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env.company_id)
currency_id = fields.Many2one('res.currency', related="company_id.currency_id", string="Currency", readonly=True)
analytic_account_id = fields.Many2one('account.analytic.account', string="Analytic Account", copy=False, ondelete='set null',
help="Analytic account to which this project is linked for financial management."
"Use an analytic account to record cost and revenue on your project.")
favorite_user_ids = fields.Many2many(
'res.users', 'project_favorite_user_rel', 'project_id', 'user_id',
@@ -324,6 +320,21 @@ class Project(models.Model):
project.message_subscribe(project.partner_id.ids)
return res
@api.multi
def unlink(self):
# Check project is empty
for project in self:
if project.tasks:
raise UserError(_('You cannot delete a project containing tasks. You can either archive it or first delete all of its tasks.'))
# Delete the empty related analytic account
analytic_accounts_to_delete = self.env['account.analytic.account']
for project in self:
if project.analytic_account_id and not project.analytic_account_id.line_ids:
analytic_accounts_to_delete |= project.analytic_account_id
result = super(Project, self).unlink()
analytic_accounts_to_delete.unlink()
return result
@api.multi
def message_subscribe(self, partner_ids=None, channel_ids=None, subtype_ids=None):
""" Subscribe to all existing active tasks when subscribing to a project """
@@ -383,6 +394,31 @@ class Project(models.Model):
action_context.pop('group_by', None)
return dict(action, context=action_context)
# ---------------------------------------------------
# Business Methods
# ---------------------------------------------------
@api.model
def _create_analytic_account_from_values(self, values):
analytic_account = self.env['account.analytic.account'].create({
'name': values.get('name', _('Unknown Analytic Account')),
'company_id': values.get('company_id', self.env.user.company_id.id),
'partner_id': values.get('partner_id'),
'active': True,
})
return analytic_account
@api.multi
def _create_analytic_account(self):
for project in self:
analytic_account = self.env['account.analytic.account'].create({
'name': project.name,
'company_id': project.company_id.id,
'partner_id': project.partner_id.id,
'active': True,
})
project.write({'analytic_account_id': analytic_account.id})
# ---------------------------------------------------
# Rating business
# ---------------------------------------------------
+5 -1
View File
@@ -19,4 +19,8 @@ access_project_tags_all,project.project_tags_all,model_project_tags,,1,0,0,0
access_project_tags_manager,project.project_tags_manager,model_project_tags,project.group_project_manager,1,1,1,1
access_project_tags_portal,project_tags_portal,project.model_project_tags,base.group_portal,1,0,0,0
access_mail_alias,mail.alias,mail.model_mail_alias,project.group_project_manager,1,1,1,1
access_mail_activity_type_project_manager,mail.activity.type.project.manager,mail.model_mail_activity_type,project.group_project_manager,1,1,1,1
access_mail_activity_type_project_manager,mail.activity.type.project.manager,mail.model_mail_activity_type,project.group_project_manager,1,1,1,1
access_account_analytic_account_user,account.analytic.account,analytic.model_account_analytic_account,project.group_project_user,1,0,0,0
access_account_analytic_account_manager,account.analytic.account,analytic.model_account_analytic_account,project.group_project_manager,1,1,1,1
access_account_analytic_account_portal,account_analytic_account,analytic.model_account_analytic_account,base.group_portal,1,0,0,0
access_account_analytic_line_project,account.analytic.line project,analytic.model_account_analytic_line,project.group_project_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
19 access_project_tags_manager project.project_tags_manager model_project_tags project.group_project_manager 1 1 1 1
20 access_project_tags_portal project_tags_portal project.model_project_tags base.group_portal 1 0 0 0
21 access_mail_alias mail.alias mail.model_mail_alias project.group_project_manager 1 1 1 1
22 access_mail_activity_type_project_manager mail.activity.type.project.manager mail.model_mail_activity_type project.group_project_manager 1 1 1 1
23 access_account_analytic_account_user account.analytic.account analytic.model_account_analytic_account project.group_project_user 1 0 0 0
24 access_account_analytic_account_manager account.analytic.account analytic.model_account_analytic_account project.group_project_manager 1 1 1 1
25 access_account_analytic_account_portal account_analytic_account analytic.model_account_analytic_account base.group_portal 1 0 0 0
26 access_account_analytic_line_project account.analytic.line project analytic.model_account_analytic_line project.group_project_manager 1 1 1 1
+21
View File
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!--
Analytic Accounts with project
-->
<record id="account_analytic_account_view_form_inherit" model="ir.ui.view">
<field name="name">account.analytic.account.form.inherit</field>
<field name="model">account.analytic.account</field>
<field name="inherit_id" ref="analytic.view_account_analytic_account_form"/>
<field eval="18" name="priority"/>
<field name="arch" type="xml">
<xpath expr="//button[@name='toggle_active']" position="before">
<button class="oe_stat_button" type="object" name="action_view_projects"
icon="fa-puzzle-piece" attrs="{'invisible': [('project_count', '=', 0)]}">
<field string="Projects" name="project_count" widget="statinfo"/>
</button>
</xpath>
</field>
</record>
</odoo>
+1
View File
@@ -140,6 +140,7 @@
</group>
<group>
<field name="partner_id" string="Customer"/>
<field name="analytic_account_id" context="{'default_partner_id': partner_id}" groups="analytic.group_analytic_accounting"/>
<label for="rating_status" groups="project.group_project_rating"/>
<div groups="project.group_project_rating">
<field name="rating_status" widget="radio"/>