odoo18/addons_extensions/project_task_timesheet_exte.../models/project.py

174 lines
6.8 KiB
Python

from odoo import api, fields, models, _
from odoo.exceptions import UserError, ValidationError
class ProjectProject(models.Model):
_inherit = 'project.project'
sequence_name = fields.Char("Project Number", copy=False, readonly=True)
task_sequence_id = fields.Many2one(
'ir.sequence',
string="Task Sequence",
readonly=True,
copy=False,
help="Sequence for tasks of this project"
)
discuss_channel_id = fields.Many2one(
'discuss.channel',
string="Project Channel",
domain="[('parent_channel_id', '=', default_projects_channel_id)]",
help="Select a channel for project communications. Channels must be sub-channels of the main Projects Channel."
)
default_projects_channel_id = fields.Many2one(
'discuss.channel',
default=lambda self: self._get_default_projects_channel(),
string="Default Projects Channel"
)
@api.model
def _get_default_projects_channel(self):
"""Get or create the default Projects Channel"""
channel = self.env['discuss.channel'].search([
('name', '=', 'Projects Channel'),
('channel_type', '=', 'channel')
], limit=1)
if not channel:
channel = self.env['discuss.channel'].create({
'name': 'Projects Channel',
'description': 'Main channel for all project communications',
'channel_type': 'channel',
})
return channel
def action_create_project_channel(self):
"""Create a new channel for this project under the Projects Channel"""
self.ensure_one()
if self.discuss_channel_id:
raise UserError(_("This project already has a channel assigned."))
# Create new channel
channel_vals = {
'name': self.name,
'description': _("Communication channel for project %s") % self.name,
'channel_type': 'channel',
'parent_channel_id': self.default_projects_channel_id.id,
}
new_channel = self.env['discuss.channel'].create(channel_vals)
self.discuss_channel_id = new_channel.id
# Add project members to the channel
self._add_project_members_to_channel()
return {
'type': 'ir.actions.act_window',
'res_model': 'discuss.channel',
'res_id': new_channel.id,
'view_mode': 'form',
'target': 'current',
'context': {'create': False}
}
def _add_project_members_to_channel(self):
"""Add all project members as followers of the channel"""
if not self.discuss_channel_id:
return
# Get all users related to this project
members_to_add = self.env['res.users']
# Add project members
if self.members_ids:
members_to_add |= self.members_ids
# Add project manager
if self.user_id:
members_to_add |= self.user_id
# Add project lead if exists
if hasattr(self, 'project_lead') and self.project_lead:
members_to_add |= self.project_lead
# Add members to channel
for member in members_to_add:
self.discuss_channel_id.add_members(member.partner_id.ids)
def write(self, vals):
"""Override write to update channel members when project members change"""
result = super().write(vals)
# If members changed, update channel members
if any(field in vals for field in ['members_ids', 'user_id', 'project_lead']):
for project in self:
if project.discuss_channel_id:
project._add_project_members_to_channel()
return result
@api.model
def _get_shared_project_sequence(self):
"""Get or create a shared sequence for all projects"""
sequence = self.env['ir.sequence'].sudo().search([('code', '=', 'project.project.sequence')], limit=1)
if not sequence:
sequence = self.env['ir.sequence'].sudo().create({
'name': _("Project Sequence"),
'implementation': 'no_gap',
'padding': 3,
'use_date_range': False,
'prefix': 'PROJ-',
'code': 'project.project.sequence',
})
return sequence
@api.model_create_multi
def create(self, vals_list):
projects = super().create(vals_list)
sequence = self._get_shared_project_sequence()
for project in projects:
if not project.sequence_name:
project.sequence_name = sequence.next_by_id()
if project.discuss_channel_id:
project._add_project_members_to_channel()
return projects
def _default_type_ids(self):
default_stage_ids = [
self.env.ref('project_task_timesheet_extended.task_type_backlog').id,
self.env.ref('project_task_timesheet_extended.task_type_development').id,
self.env.ref('project_task_timesheet_extended.task_type_code_review_and_merging').id,
self.env.ref('project_task_timesheet_extended.task_type_testing').id,
self.env.ref('project_task_timesheet_extended.task_type_deployment').id,
self.env.ref('project_task_timesheet_extended.task_type_completed').id,
]
# self.env.ref('project_task_timesheet_extended.task_type_cancelled').id,
# self.env.ref('project_task_timesheet_extended.task_type_hold').id,
return self.env['project.task.type'].browse(default_stage_ids)
project_lead = fields.Many2one("res.users", string="Project Lead")
members_ids = fields.Many2many('res.users', 'project_user_rel', 'project_id',
'user_id', 'Project Members', help="""Project's
members are users who can have an access to
the tasks related to this project."""
)
user_id = fields.Many2one('res.users', string='Project Manager', default=lambda self: self.env.user, tracking=True,
domain=lambda self: [('groups_id', 'in', [self.env.ref('project.group_project_manager').id,self.env.ref('project_task_timesheet_extended.group_project_supervisor').id]),('share','=',False)],)
type_ids = fields.Many2many(default=lambda self: self._default_type_ids())
def add_users(self):
return {
'type': 'ir.actions.act_window',
'name': 'Add Users',
'res_model': 'project.user.assign.wizard',
'view_mode': 'form',
'view_id': self.env.ref('project_task_timesheet_extended.project_user_assignment_form_view').id,
'target': 'new',
'context': {'default_members_ids':[(6, 0, self.members_ids.ids)],
},
}