diff --git a/addons/hr_timesheet/models/__init__.py b/addons/hr_timesheet/models/__init__.py index ce7d853abca..5e18c694d32 100644 --- a/addons/hr_timesheet/models/__init__.py +++ b/addons/hr_timesheet/models/__init__.py @@ -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 diff --git a/addons/hr_timesheet/models/project.py b/addons/hr_timesheet/models/project.py index 3e7a5fc3668..8c6d21eab92 100644 --- a/addons/hr_timesheet/models/project.py +++ b/addons/hr_timesheet/models/project.py @@ -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" diff --git a/addons/hr_timesheet/security/ir.model.access.csv b/addons/hr_timesheet/security/ir.model.access.csv index c6776df9364..96723f93935 100644 --- a/addons/hr_timesheet/security/ir.model.access.csv +++ b/addons/hr_timesheet/security/ir.model.access.csv @@ -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 diff --git a/addons/hr_timesheet/views/hr_timesheet_views.xml b/addons/hr_timesheet/views/hr_timesheet_views.xml index f5a5c8a1929..700feb230fe 100644 --- a/addons/hr_timesheet/views/hr_timesheet_views.xml +++ b/addons/hr_timesheet/views/hr_timesheet_views.xml @@ -1,24 +1,6 @@ - - - account.analytic.account.form.inherit - account.analytic.account - - - - - - - - - - - - @@ -178,6 +175,9 @@ + + record.analytic_account_id.raw_value and !record.allow_timesheets.raw_value + diff --git a/addons/project/__manifest__.py b/addons/project/__manifest__.py index 3620923b452..e71a47d8286 100644 --- a/addons/project/__manifest__.py +++ b/addons/project/__manifest__.py @@ -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', diff --git a/addons/project/models/__init__.py b/addons/project/models/__init__.py index c796777486b..22a31e4bc71 100644 --- a/addons/project/models/__init__.py +++ b/addons/project/models/__init__.py @@ -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 diff --git a/addons/hr_timesheet/models/analytic_account.py b/addons/project/models/analytic_account.py similarity index 93% rename from addons/hr_timesheet/models/analytic_account.py rename to addons/project/models/analytic_account.py index 574e73962d9..f61059058be 100644 --- a/addons/hr_timesheet/models/analytic_account.py +++ b/addons/project/models/analytic_account.py @@ -9,7 +9,6 @@ class AccountAnalyticAccount(models.Model): _inherit = 'account.analytic.account' _description = 'Analytic Account' - company_uom_id = fields.Many2one('uom.uom', related='company_id.project_time_mode_id', string="Company UOM", readonly=False) project_ids = fields.One2many('project.project', 'analytic_account_id', string='Projects') project_count = fields.Integer("Project Count", compute='_compute_project_count') diff --git a/addons/project/models/project.py b/addons/project/models/project.py index 4e53288d2a8..627ec77b643 100644 --- a/addons/project/models/project.py +++ b/addons/project/models/project.py @@ -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 """ @@ -365,6 +376,13 @@ class Project(models.Model): action = self.env['ir.actions.act_window'].for_xml_id('project', 'act_project_project_2_project_task_all') return dict(action, context=ctx) + def action_view_account_analytic_line(self): + """ return the action to see all the analytic lines of the project's analytic account """ + action = self.env.ref('analytic.account_analytic_line_action').read()[0] + action['context'] = {'default_account_id': self.analytic_account_id.id} + action['domain'] = [('account_id', '=', self.analytic_account_id.id)] + return action + @api.multi def action_view_all_rating(self): """ return the action to see all the rating of the project, and activate default filters """ @@ -383,6 +401,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 # --------------------------------------------------- diff --git a/addons/project/security/ir.model.access.csv b/addons/project/security/ir.model.access.csv index ed22a1b4da7..f7bf080c5cf 100644 --- a/addons/project/security/ir.model.access.csv +++ b/addons/project/security/ir.model.access.csv @@ -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 \ No newline at end of file +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 \ No newline at end of file diff --git a/addons/project/views/analytic_views.xml b/addons/project/views/analytic_views.xml new file mode 100644 index 00000000000..bf6809dc5c4 --- /dev/null +++ b/addons/project/views/analytic_views.xml @@ -0,0 +1,21 @@ + + + + + account.analytic.account.form.inherit + account.analytic.account + + + + + + + + + + diff --git a/addons/project/views/project_views.xml b/addons/project/views/project_views.xml index 54eb70b7935..da0d1921500 100644 --- a/addons/project/views/project_views.xml +++ b/addons/project/views/project_views.xml @@ -140,6 +140,7 @@ +