[IMP] project: a project is not an analytic account anymore !
This commit removes the inheritS between account.analytic.account and project.project. This means : - When a project is created, an analytic account is not necessarily genareted - project has now its own name, company_id and partner_id fields - an analytic account can be linked to several project - project module does not depend anymore of analytic, but hr_timesheet does. This change implied - an analytic account is required on project to timesheet on its tasks. So, when checking 'allow_timsheets', if an AA is not provided at project creation, an AA will be generated. - to timesheet on project, an active AA is required. We don't want timesheeting on project linked to unused AA to avoid bad analytic entries. This prepare the fact a sale order can create multiple project, sharing the same analytic account (the one from the SO).
This commit is contained in:
@@ -20,7 +20,7 @@ It is completely integrated with the cost accounting module. It allows you to se
|
||||
up a management by affair.
|
||||
""",
|
||||
'website': 'https://www.odoo.com/page/employees',
|
||||
'depends': ['hr', 'project'],
|
||||
'depends': ['hr', 'analytic', 'project'],
|
||||
'data': [
|
||||
'security/hr_timesheet_security.xml',
|
||||
'security/ir.model.access.csv',
|
||||
|
||||
@@ -1,6 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="account_analytic_account_project_2" model="account.analytic.account">
|
||||
<field name="name">Research & Development Project</field>
|
||||
<field name="code">RD</field>
|
||||
<field name="active" eval="True"/>
|
||||
</record>
|
||||
|
||||
<record id="project.project_project_2" model="project.project">
|
||||
<field name="analytic_account_id" ref="account_analytic_account_project_2"/>
|
||||
</record>
|
||||
|
||||
<record id="project.project_project_4" model="project.project">
|
||||
<field name="analytic_account_id" ref="analytic.analytic_deltapc"/>
|
||||
</record>
|
||||
|
||||
<record id="working_hours_requirements" model="account.analytic.line">
|
||||
<field name="name">Requirements analysis and specification</field>
|
||||
<field name="user_id" ref='base.user_root'/>
|
||||
@@ -35,7 +49,7 @@
|
||||
<field name="unit_amount">1.00</field>
|
||||
<field name="project_id" ref='project.project_project_2'/>
|
||||
<field name="amount">-30.00</field>
|
||||
</record>
|
||||
</record>
|
||||
|
||||
<record id="working_hours_maintenance" model="account.analytic.line">
|
||||
<field name="name">Delivery and maintenance</field>
|
||||
@@ -44,6 +58,6 @@
|
||||
<field name="unit_amount">1.00</field>
|
||||
<field name="project_id" ref='project.project_project_2'/>
|
||||
<field name="amount">-30.00</field>
|
||||
</record>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -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 hr
|
||||
from . import hr_timesheet
|
||||
from . import res_config_settings
|
||||
|
||||
@@ -13,9 +13,12 @@ class AccountAnalyticAccount(models.Model):
|
||||
project_ids = fields.One2many('project.project', 'analytic_account_id', string='Projects')
|
||||
project_count = fields.Integer("Project Count", compute='_compute_project_count')
|
||||
|
||||
@api.multi
|
||||
def _compute_project_count(self):
|
||||
project_data = self.env['project.project'].read_group([('analytic_account_id', 'in', self.ids)], ['analytic_account_id'], ['analytic_account_id'])
|
||||
mapping = {m['analytic_account_id'][0]: m['analytic_account_id_count'] for m in project_data}
|
||||
for account in self:
|
||||
account.project_count = len(account.with_context(active_test=False).project_ids)
|
||||
account.project_count = mapping.get(account.id, 0)
|
||||
|
||||
@api.multi
|
||||
def unlink(self):
|
||||
@@ -25,18 +28,9 @@ class AccountAnalyticAccount(models.Model):
|
||||
raise UserError(_('Please remove existing tasks in the project linked to the accounts you want to delete.'))
|
||||
return super(AccountAnalyticAccount, self).unlink()
|
||||
|
||||
@api.model
|
||||
def name_search(self, name, args=None, operator='ilike', limit=100):
|
||||
if args is None:
|
||||
args = []
|
||||
if self.env.context.get('current_model') == 'project.project':
|
||||
return self.search(args + [('name', operator, name)], limit=limit).name_get()
|
||||
|
||||
return super(AccountAnalyticAccount, self).name_search(name, args=args, operator=operator, limit=limit)
|
||||
|
||||
@api.multi
|
||||
def projects_action(self):
|
||||
projects = self.with_context(active_test=False).mapped('project_ids')
|
||||
def action_view_projects(self):
|
||||
projects = self.mapped('project_ids')
|
||||
result = {
|
||||
"type": "ir.actions.act_window",
|
||||
"res_model": "project.project",
|
||||
@@ -1,7 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class AccountAnalyticLine(models.Model):
|
||||
@@ -64,6 +65,8 @@ class AccountAnalyticLine(models.Model):
|
||||
if vals.get('project_id') and not vals.get('account_id'):
|
||||
project = self.env['project.project'].browse(vals.get('project_id'))
|
||||
vals['account_id'] = project.analytic_account_id.id
|
||||
if not project.analytic_account_id.active:
|
||||
raise UserError(_('The project you are timesheeting on is not linked to a active analytic account. Please the project configuration.'))
|
||||
# employee implies user
|
||||
if vals.get('employee_id') and not vals.get('user_id'):
|
||||
employee = self.env['hr.employee'].browse(vals['employee_id'])
|
||||
|
||||
@@ -1,20 +1,89 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models, fields, api
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools.translate import _
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
|
||||
|
||||
class Project(models.Model):
|
||||
_inherit = "project.project"
|
||||
|
||||
allow_timesheets = fields.Boolean("Allow timesheets", default=True)
|
||||
analytic_account_id = fields.Many2one('account.analytic.account', string="Analytic Account", ondelete='set null',
|
||||
help="Link this project to an analytic account if you need financial management on projects. "
|
||||
"It enables you to connect projects with budgets, planning, cost and revenue analysis, timesheets on projects, etc.")
|
||||
|
||||
@api.onchange('partner_id')
|
||||
def _onchange_partner_id(self):
|
||||
domain = []
|
||||
if self.partner_id:
|
||||
domain = [('partner_id', '=', self.partner_id.id)]
|
||||
return {'domain': {'analytic_account_id': domain}}
|
||||
|
||||
@api.constrains('allow_timesheets', 'analytic_account_id')
|
||||
def _check_allow_timesheet(self):
|
||||
for project in self:
|
||||
if project.allow_timesheets and not project.analytic_account_id:
|
||||
raise ValidationError(_('To allow timesheet, your project %s should have an analytic account set.' % (project.name,)))
|
||||
|
||||
@api.model
|
||||
def name_create(self, name):
|
||||
""" Create a project with name_create should generate analytic account creation """
|
||||
values = {
|
||||
'name': name,
|
||||
'allow_timesheets': True,
|
||||
}
|
||||
return self.create(values).name_get()[0]
|
||||
|
||||
@api.model
|
||||
def create(self, values):
|
||||
""" Create an analytic account if project allow timesheet and don't provide one """
|
||||
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._create_analytic_account(values)
|
||||
values['analytic_account_id'] = analytic_account.id
|
||||
return super(Project, self).create(values)
|
||||
|
||||
@api.multi
|
||||
def write(self, values):
|
||||
result = super(Project, self).write(values)
|
||||
if values.get('allow_timesheets'):
|
||||
for project in self:
|
||||
if not project.analytic_account_id:
|
||||
analytic_account = project._create_analytic_account({
|
||||
'name': project.name,
|
||||
'company_id': project.company_id.id,
|
||||
'partner_id': project.partner_id.id,
|
||||
})
|
||||
project.write({'analytic_account_id': analytic_account.id})
|
||||
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
|
||||
|
||||
def _create_analytic_account(self, values):
|
||||
analytic_account = self.env['account.analytic.account'].create({
|
||||
'name': values.get('name', _('Unkwon 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
|
||||
|
||||
|
||||
class Task(models.Model):
|
||||
_inherit = "project.task"
|
||||
|
||||
analytic_account_id = fields.Many2one('account.analytic.account', string="Analytic Account", related='project_id.analytic_account_id', readonly=True)
|
||||
allow_timesheets = fields.Boolean("Allow timesheets", compute='_compute_allow_timesheets', help="Timesheets can be logged on this task.")
|
||||
remaining_hours = fields.Float("Remaining Hours", compute='_compute_progress_hours', inverse='_inverse_remaining_hours', store=True, help="Total remaining time, can be re-estimated periodically by the assignee of the task.")
|
||||
effective_hours = fields.Float("Hours Spent", compute='_compute_effective_hours', compute_sudo=True, store=True, help="Computed using the sum of the task work done.")
|
||||
total_hours_spent = fields.Float("Total Hours", compute='_compute_progress_hours', store=True, help="Computed as: Time Spent + Sub-tasks Hours.")
|
||||
@@ -22,10 +91,10 @@ class Task(models.Model):
|
||||
subtask_effective_hours = fields.Float("Sub-tasks Hours Spent", compute='_compute_subtask_effective_hours', store=True, help="Sum of actually spent hours on the subtask(s)", oldname='children_hours')
|
||||
timesheet_ids = fields.One2many('account.analytic.line', 'task_id', 'Timesheets')
|
||||
|
||||
@api.onchange('remaining_hours')
|
||||
def _inverse_remaining_hours(self):
|
||||
@api.depends('project_id.allow_timesheets', 'project_id.analytic_account_id')
|
||||
def _compute_allow_timesheets(self):
|
||||
for task in self:
|
||||
task.planned_hours = task.remaining_hours + task.effective_hours + task.subtask_effective_hours
|
||||
task.allow_timesheets = task.project_id.allow_timesheets and task.project_id.analytic_account_id.active
|
||||
|
||||
@api.depends('timesheet_ids.unit_amount')
|
||||
def _compute_effective_hours(self):
|
||||
@@ -47,6 +116,11 @@ class Task(models.Model):
|
||||
task.remaining_hours = task.planned_hours - task.effective_hours - task.subtask_effective_hours
|
||||
task.total_hours_spent = task.effective_hours + task.subtask_effective_hours
|
||||
|
||||
@api.onchange('remaining_hours')
|
||||
def _inverse_remaining_hours(self):
|
||||
for task in self:
|
||||
task.planned_hours = task.remaining_hours + task.effective_hours + task.subtask_effective_hours
|
||||
|
||||
@api.depends('child_ids.effective_hours', 'child_ids.subtask_effective_hours')
|
||||
def _compute_subtask_effective_hours(self):
|
||||
for task in self:
|
||||
|
||||
@@ -2,6 +2,10 @@ 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_product_product_user,product.product.timesheet.user,product.model_product_product,hr_timesheet.group_hr_timesheet_user,1,1,1,0
|
||||
access_product_template_timesheet_user,product.template.timesheet.user,product.model_product_template,hr_timesheet.group_hr_timesheet_user,1,1,1,0
|
||||
access_uom_uom_hr_timesheet,uom.uom.timesheet.user,uom.model_uom_uom,hr_timesheet.group_hr_timesheet_user,1,0,0,0
|
||||
|
||||
|
@@ -17,11 +17,18 @@ class TestCommonTimesheet(TransactionCase):
|
||||
'customer': True,
|
||||
})
|
||||
|
||||
self.analytic_account = self.env['account.analytic.account'].create({
|
||||
'name': 'Analytic Account for Test Customer',
|
||||
'partner_id': self.partner.id,
|
||||
'code': 'TEST'
|
||||
})
|
||||
|
||||
# project and tasks
|
||||
self.project_customer = self.env['project.project'].create({
|
||||
'name': 'Project X',
|
||||
'allow_timesheets': True,
|
||||
'partner_id': self.partner.id,
|
||||
'analytic_account_id': self.analytic_account.id,
|
||||
})
|
||||
self.task1 = self.env['project.task'].create({
|
||||
'name': 'Task One',
|
||||
|
||||
@@ -1,6 +1,26 @@
|
||||
<?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"
|
||||
name="Timesheets"
|
||||
sequence="55"
|
||||
|
||||
@@ -48,6 +48,9 @@
|
||||
<label for="allow_timesheets"/>
|
||||
</div>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='partner_id']" position="after">
|
||||
<field name="analytic_account_id"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -58,7 +61,9 @@
|
||||
<field name="groups_id" eval="[(6,0, (ref('hr_timesheet.group_hr_timesheet_user'),))]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//notebook/page[@name='description_page']" position="after">
|
||||
<page string="Timesheets" attrs="{'invisible': [('project_id', '=', False)]}">
|
||||
<field name="analytic_account_id" invisible="1"/>
|
||||
<field name="allow_timesheets" invisible="1"/>
|
||||
<page string="Timesheets" attrs="{'invisible': [('analytic_account_id', '=', False)]}">
|
||||
<group>
|
||||
<group>
|
||||
<field name="planned_hours" widget="float_time"/>
|
||||
@@ -71,7 +76,12 @@
|
||||
<field name="progress" widget="progressbar"/>
|
||||
</group>
|
||||
</group>
|
||||
<field name="timesheet_ids" context="{'default_project_id': project_id, 'default_name':''}">
|
||||
<group name="timesheet_error" attrs="{'invisible': [('allow_timesheets', '!=', False)]}">
|
||||
<div class="alert alert-warning">
|
||||
Your project is linked to an inactive analytic account. Change it, or reactivate the current one to timesheet on the project.
|
||||
</div>
|
||||
</group>
|
||||
<field name="timesheet_ids" attrs="{'invisible': [('allow_timesheets', '=', False)]}" context="{'default_project_id': project_id, 'default_name':'', 'default_analytic_account_id': analytic_account_id}">
|
||||
<tree editable="bottom" string="Timesheet Activities" default_order="date">
|
||||
<field name="date"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
@@ -81,13 +91,13 @@
|
||||
<field name="project_id" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
<group>
|
||||
<group class="oe_subtotal_footer oe_right" name="project_hours">
|
||||
<field name="effective_hours" widget="float_time" />
|
||||
<field name="subtask_effective_hours" widget="float_time" groups="project.group_subtask_project" attrs="{'invisible' : [('subtask_count', '=', 0)]}" />
|
||||
<field name="total_hours_spent" widget="float_time" class="oe_subtotal_footer_separator" attrs="{'invisible' : [('subtask_effective_hours', '=', 0.0)]}" />
|
||||
<field name="remaining_hours" widget="float_time" class="oe_subtotal_footer_separator"/>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('allow_timesheets', '=', False)]}">
|
||||
<group class="oe_subtotal_footer oe_right" name="project_hours">
|
||||
<field name="effective_hours" widget="float_time" />
|
||||
<field name="subtask_effective_hours" widget="float_time" attrs="{'invisible' : [('subtask_effective_hours', '=', 0.0)]}" />
|
||||
<field name="total_hours_spent" widget="float_time" class="oe_subtotal_footer_separator" attrs="{'invisible' : [('subtask_effective_hours', '=', 0.0)]}" />
|
||||
<field name="remaining_hours" widget="float_time" class="oe_subtotal_footer_separator" readonly="1"/>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
</xpath>
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
'depends': [
|
||||
'base_setup',
|
||||
'product',
|
||||
'analytic',
|
||||
'mail',
|
||||
'portal',
|
||||
'rating',
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import analytic
|
||||
from . import project
|
||||
from . import res_config_settings
|
||||
from . import res_company
|
||||
|
||||
@@ -69,7 +69,6 @@ class Project(models.Model):
|
||||
_name = "project.project"
|
||||
_description = "Project"
|
||||
_inherit = ['portal.mixin', 'mail.alias.mixin', 'mail.thread']
|
||||
_inherits = {'account.analytic.account': "analytic_account_id"}
|
||||
_order = "sequence, name, id"
|
||||
_period_number = 5
|
||||
|
||||
@@ -83,15 +82,10 @@ class Project(models.Model):
|
||||
|
||||
@api.multi
|
||||
def unlink(self):
|
||||
analytic_accounts_to_delete = self.env['account.analytic.account']
|
||||
for project in self:
|
||||
if project.tasks:
|
||||
raise UserError(_('You cannot delete a project containing tasks. You can either delete all the project\'s tasks and then delete the project or simply deactivate the project.'))
|
||||
if project.analytic_account_id and not project.analytic_account_id.line_ids:
|
||||
analytic_accounts_to_delete |= project.analytic_account_id
|
||||
res = super(Project, self).unlink()
|
||||
analytic_accounts_to_delete.unlink()
|
||||
return res
|
||||
return super(Project, self).unlink()
|
||||
|
||||
def _compute_attached_docs_count(self):
|
||||
Attachment = self.env['ir.attachment']
|
||||
@@ -179,14 +173,14 @@ class Project(models.Model):
|
||||
def _get_default_favorite_user_ids(self):
|
||||
return [(6, 0, [self.env.uid])]
|
||||
|
||||
name = fields.Char("Name", index=True, required=True, track_visibility='onchange')
|
||||
active = fields.Boolean(default=True,
|
||||
help="If the active field is set to False, it will allow you to hide the project without removing it.")
|
||||
sequence = fields.Integer(default=10, help="Gives the sequence order when displaying a list of Projects.")
|
||||
analytic_account_id = fields.Many2one(
|
||||
'account.analytic.account', string='Contract/Analytic',
|
||||
help="Link this project to an analytic account if you need financial management on projects. "
|
||||
"It enables you to connect projects with budgets, planning, cost and revenue analysis, timesheets on projects, etc.",
|
||||
ondelete="cascade", required=True, auto_join=True)
|
||||
partner_id = fields.Many2one('res.partner', string='Customer', auto_join=True, track_visibility='onchange')
|
||||
company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env.user.company_id)
|
||||
currency_id = fields.Many2one('res.currency', related="company_id.currency_id", string="Currency", readonly=True)
|
||||
|
||||
favorite_user_ids = fields.Many2many(
|
||||
'res.users', 'project_favorite_user_rel', 'project_id', 'user_id',
|
||||
default=_get_default_favorite_user_ids,
|
||||
@@ -315,8 +309,6 @@ class Project(models.Model):
|
||||
if 'active' in vals:
|
||||
# archiving/unarchiving a project does it on its tasks, too
|
||||
self.with_context(active_test=False).mapped('tasks').write({'active': vals['active']})
|
||||
# archiving/unarchiving a project implies that we don't want to use the analytic account anymore
|
||||
self.with_context(active_test=False).mapped('analytic_account_id').write({'active': vals['active']})
|
||||
if vals.get('partner_id') or vals.get('privacy_visibility'):
|
||||
for project in self.filtered(lambda project: project.privacy_visibility == 'portal'):
|
||||
project.message_subscribe(project.partner_id.ids)
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_project_project,project.project,model_project_project,project.group_project_user,1,0,0,0
|
||||
access_project_project_manager,project.project,model_project_project,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_project_task_type_user,project.task.type.user,model_project_task_type,base.group_user,1,0,0,0
|
||||
access_project_task_type_project_user,project.task.type.project.user,model_project_task_type,project.group_project_user,1,0,0,0
|
||||
access_project_task_type_manager,project.task.type manager,model_project_task_type,project.group_project_manager,1,1,1,1
|
||||
@@ -15,7 +12,6 @@ access_task_on_partner,project.task on partners,model_project_task,base.group_us
|
||||
access_task_portal,task_portal,project.model_project_task,base.group_portal,1,0,0,0
|
||||
access_project_user,project.project on partners,model_project_project,base.group_user,1,0,0,0
|
||||
access_project_portal,project_portal,project.model_project_project,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_resource_calendar,project.resource_calendar user,resource.model_resource_calendar,project.group_project_user,1,0,0,0
|
||||
access_resource_calendar_attendance,project.resource_calendar_attendance user,resource.model_resource_calendar_attendance,project.group_project_user,1,0,0,0
|
||||
access_resource_calendar_leaves_user,resource.calendar.leaves user,resource.model_resource_calendar_leaves,project.group_project_user,1,1,1,1
|
||||
|
||||
|
@@ -102,7 +102,6 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Project">
|
||||
<sheet string="Project">
|
||||
<field name="analytic_account_id" invisible="1" required="0"/>
|
||||
<div class="oe_button_box" name="button_box" groups="base.group_user">
|
||||
<button class="oe_stat_button" name="attachment_tree_view" type="object" icon="fa-files-o">
|
||||
<field string="Documents" name="doc_count" widget="statinfo"/>
|
||||
@@ -150,8 +149,9 @@
|
||||
<field name="portal_show_rating" attrs="{'invisible': [('rating_status','==','no')]}" groups="project.group_project_rating"/>
|
||||
</group>
|
||||
<group name="misc">
|
||||
<group string="Configuration" groups="base.group_no_one">
|
||||
<group string="Configuration" groups="base.group_no_one" name="configuration">
|
||||
<field name="sequence" groups="base.group_no_one"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
</group>
|
||||
<group string="Time Scheduling" groups="base.group_no_one">
|
||||
<field name="resource_calendar_id" groups="base.group_no_one"/>
|
||||
@@ -666,21 +666,6 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="analytic_account_inherited_form" 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="projects_action"
|
||||
icon="fa-puzzle-piece" attrs="{'invisible': [('project_count', '=', 0)]}">
|
||||
<field string="Projects" name="project_count" widget="statinfo"/>
|
||||
</button>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_view_task" model="ir.actions.act_window">
|
||||
<field name="name">Tasks</field>
|
||||
<field name="res_model">project.task</field>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<field name="product_uom_qty">5.0</field>
|
||||
</record>
|
||||
|
||||
<!-- Projects and Stages -->
|
||||
<!-- Projects, Analytic Account and Stages -->
|
||||
<record id="project_stage_fixed" model="project.task.type">
|
||||
<field name="sequence">30</field>
|
||||
<field name="name">Fixed</field>
|
||||
@@ -19,17 +19,31 @@
|
||||
<field name="legend_done">Done</field>
|
||||
</record>
|
||||
|
||||
<record id="account_analytic_account_project_gap" model="account.analytic.account">
|
||||
<field name="name">Internal - GAP Analysis</field>
|
||||
<field name="code">INT</field>
|
||||
<field name="active" eval="True"/>
|
||||
</record>
|
||||
|
||||
<record id="project_GAP" model="project.project">
|
||||
<field name="date_start" eval="time.strftime('%Y-%m-01 10:00:00')"/>
|
||||
<field name="name">Internal - GAP Analysis</field>
|
||||
<field name="analytic_account_id" ref="account_analytic_account_project_gap"/>
|
||||
<field name="color">2</field>
|
||||
<field name="privacy_visibility">employees</field>
|
||||
<field name="type_ids" eval="[(4, ref('project.project_stage_0')) ,(4,ref('project.project_stage_1')) ,(4,ref('project.project_stage_2')) ,(4,ref('project.project_stage_3'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="account_analytic_account_project_support" model="account.analytic.account">
|
||||
<field name="name">Support</field>
|
||||
<field name="code">INT</field>
|
||||
<field name="active" eval="True"/>
|
||||
</record>
|
||||
|
||||
<record id="project_support" model="project.project">
|
||||
<field name="date_start" eval="time.strftime('%Y-%m-01 10:00:00')"/>
|
||||
<field name="name">Support</field>
|
||||
<field name="analytic_account_id" ref="account_analytic_account_project_support"/>
|
||||
<field name="type_ids" eval="[(4, ref('project.project_stage_data_0')), (4, ref('project.project_stage_1')), (4, ref('project_stage_fixed'))]"/>
|
||||
</record>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user