[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:
@@ -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
|
||||
|
||||
@@ -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,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>
|
||||
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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
|
||||
# ---------------------------------------------------
|
||||
|
||||
@@ -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
|
||||
|
@@ -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>
|
||||
@@ -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"/>
|
||||
|
||||
Reference in New Issue
Block a user