Project Changes
This commit is contained in:
parent
604d556501
commit
eb17d717dd
|
|
@ -46,7 +46,7 @@ class projectTask(models.Model):
|
|||
('normal', 'Normal'),
|
||||
], compute='_compute_deadline_status')
|
||||
|
||||
model_id = fields.Many2one('project.module.source', string="Module", related='project_id.module_id', store=True, readonly=True)
|
||||
model_id = fields.Many2one('project.module.source', string="Module", store=True, readonly=True)
|
||||
task_display_id = fields.Char(string="Task ID", compute="_compute_kanban_display_fields", compute_sudo=True)
|
||||
module_display_name = fields.Char(string="Module", compute="_compute_kanban_display_fields", compute_sudo=True)
|
||||
allocation_start_date = fields.Date(string="Allocation Start Date")
|
||||
|
|
@ -54,11 +54,11 @@ class projectTask(models.Model):
|
|||
reassignment_history = fields.Html(string="Reassignment History", readonly=True)
|
||||
|
||||
|
||||
@api.depends('sequence_name', 'project_id', 'project_id.module_id', 'project_id.module_id.name', 'model_id', 'model_id.name')
|
||||
@api.depends('sequence_name', 'project_id', 'model_id', 'model_id.name')
|
||||
def _compute_kanban_display_fields(self):
|
||||
for task in self:
|
||||
task.task_display_id = task.sequence_name or ("TASK-%03d" % task.id if task.id else "New Task")
|
||||
module = task.model_id or task.project_id.module_id
|
||||
module = task.model_id
|
||||
task.module_display_name = module.name if module else "No Module"
|
||||
|
||||
@api.depends('date_deadline')
|
||||
|
|
@ -841,7 +841,7 @@ class projectTask(models.Model):
|
|||
task.stage_id = n_stage
|
||||
task.approval_status = "approved"
|
||||
|
||||
activity_log = "%s: ✅ approved by %s and moved to %s" % (
|
||||
activity_log = "%s: approved by %s and moved to %s" % (
|
||||
current_stage.name,
|
||||
self.env.user.employee_id.name,
|
||||
n_stage.name)
|
||||
|
|
@ -849,7 +849,7 @@ class projectTask(models.Model):
|
|||
# Use the helper method to add activity log
|
||||
task._add_activity_log(activity_log)
|
||||
|
||||
user_notes = "%s: ✅ moved to %s and awaiting your completion" % (
|
||||
user_notes = "%s: moved to %s and awaiting your completion" % (
|
||||
task.sequence_name,
|
||||
n_stage.name
|
||||
)
|
||||
|
|
@ -882,9 +882,9 @@ class projectTask(models.Model):
|
|||
)
|
||||
else:
|
||||
task.approval_status = "approved"
|
||||
notes = "%s: ✅ Task approved and completed by %s" % (task.sequence_name, self.env.user.employee_id.name)
|
||||
notes = "%s: Task approved and completed by %s" % (task.sequence_name, self.env.user.employee_id.name)
|
||||
|
||||
activity_log = "%s: ✅ approved by %s" % (
|
||||
activity_log = "%s: approved by %s" % (
|
||||
current_stage.name,
|
||||
self.env.user.employee_id.name)
|
||||
|
||||
|
|
@ -920,9 +920,9 @@ class projectTask(models.Model):
|
|||
# Optional: find previous stage if you want to send back
|
||||
stage = task.assignees_timelines.filtered(lambda s: s.stage_id == task.stage_id)
|
||||
|
||||
notes = "%s: âÂÂÂÂÅ’ %s rejected by %s" % (task.sequence_name, current_stage.name, self.env.user.employee_id.name)
|
||||
notes = "%s: %s rejected by %s" % (task.sequence_name, current_stage.name, self.env.user.employee_id.name)
|
||||
|
||||
activity_log = "%s: âÂÂÂÂÅ’ rejected by %s: %s" % (
|
||||
activity_log = "%s: rejected by %s: %s" % (
|
||||
current_stage.name,
|
||||
self.env.user.employee_id.name,
|
||||
reason)
|
||||
|
|
|
|||
|
|
@ -1,49 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="project_project_form_module_inherit" model="ir.ui.view">
|
||||
<field name="name">project.project.form.module.inherit</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="inherit_id" ref="project_task_timesheet_extended.project_project_inherit_form_view2"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='project_lead']" position="after">
|
||||
<field name="module_id" options="{'no_open': True}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_project_search_project_by_module" model="ir.ui.view">
|
||||
<field name="name">project.project.search.project.by.module</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="inherit_id" ref="project.view_project_project_filter"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//search" position="inside">
|
||||
<filter name="group_by_module" string="Module" context="{'group_by': 'module_id'}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_project_by_module" model="ir.actions.act_window">
|
||||
<field name="name">Project by Module</field>
|
||||
<field name="res_model">project.project</field>
|
||||
<field name="view_mode">kanban,list,form,calendar,activity</field>
|
||||
<field name="search_view_id" ref="project.view_project_project_filter"/>
|
||||
<field name="context">{'search_default_group_by_module': 1}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No projects found.
|
||||
</p>
|
||||
<p>
|
||||
Create projects and set their Module to review projects module-wise.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_project_by_module"
|
||||
name="Project by Module"
|
||||
parent="project.menu_main_pm"
|
||||
action="action_project_by_module"
|
||||
sequence="25"/>
|
||||
|
||||
<record id="project_project_kanban_portfolio_inherit" model="ir.ui.view">
|
||||
<field name="name">project.project.kanban.portfolio.inherit</field>
|
||||
|
|
@ -79,6 +36,41 @@
|
|||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_task_search_project_by_module" model="ir.ui.view">
|
||||
<field name="name">project.task.search.project.by.module</field>
|
||||
<field name="model">project.task</field>
|
||||
<field name="inherit_id" ref="project.view_task_search_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//search" position="inside">
|
||||
<filter name="group_by_module" string="Module" context="{'group_by': 'model_id'}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
<record id="action_project_by_module" model="ir.actions.act_window">
|
||||
<field name="name">Project by Module</field>
|
||||
<field name="res_model">project.task</field>
|
||||
<field name="view_mode">kanban,list,form,calendar,activity</field>
|
||||
<field name="search_view_id" ref="project.view_task_search_form"/>
|
||||
<field name="context">{'search_default_group_by_module': 1}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No projects found.
|
||||
</p>
|
||||
<p>
|
||||
Create projects and set their Module to review projects module-wise.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_project_by_module"
|
||||
name="Project by Module"
|
||||
parent="project.menu_main_pm"
|
||||
action="action_project_by_module"
|
||||
sequence="25"/>
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
|
|
|
|||
|
|
@ -24,13 +24,13 @@
|
|||
<strong>THIS TASK IS CURRENTLY PAUSED</strong>
|
||||
</div>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='user_ids']" position="replace">
|
||||
<label for="user_ids" string="Assignees"/>
|
||||
<div class="o_task_assignees_inline">
|
||||
<field name="user_ids" nolabel="1" widget="involved_assignee_avatar_user" domain="[('id', 'in', involved_user_ids)]" options="{'no_create': True, 'no_quick_create': True, 'no_create_edit': True}" invisible="is_generic"/>
|
||||
<field name="user_ids" nolabel="1" class="o_task_user_field" options="{'no_open': True, 'no_quick_create': True}" widget="many2many_avatar_user" domain="[('id', 'in', assignee_domain_ids)]" invisible="not is_generic"/>
|
||||
<button name="action_open_reassign_wizard" type="object" icon="fa-caret-down" title="Re-Assign Assignees" class="btn-link o_task_reassign_arrow" invisible="record_paused"/>
|
||||
</div>
|
||||
<xpath expr="//field[@name='user_ids']" position="replace">
|
||||
<label for="user_ids" string="Assignees"/>
|
||||
<div class="o_task_assignees_inline">
|
||||
<field name="user_ids" nolabel="1" widget="involved_assignee_avatar_user" domain="[('id', 'in', involved_user_ids)]" options="{'no_create': True, 'no_quick_create': True, 'no_create_edit': True}" invisible="is_generic"/>
|
||||
<field name="user_ids" nolabel="1" class="o_task_user_field" options="{'no_open': True, 'no_quick_create': True}" widget="many2many_avatar_user" domain="[('id', 'in', assignee_domain_ids)]" invisible="not is_generic"/>
|
||||
<button name="action_open_reassign_wizard" type="object" icon="fa-caret-down" title="Re-Assign Assignees" class="btn-link o_task_reassign_arrow" invisible="record_paused"/>
|
||||
</div>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='timesheet_ids']" position="attributes">
|
||||
<attribute name="context">
|
||||
|
|
@ -61,12 +61,12 @@
|
|||
<!-- <field name="assigned_team"/>-->
|
||||
<!-- </xpath>-->
|
||||
|
||||
|
||||
<xpath expr="//div[hasclass('o_task_assignees_inline')]" position="after">
|
||||
<field name="involved_user_ids" widget="many2many_avatar_user" invisible="is_generic"/>
|
||||
<field name="is_generic" readonly="not has_supervisor_access"/>
|
||||
<field name="record_paused" invisible="1"/>
|
||||
<field name="model_id" readonly="not has_supervisor_access" options="{'no_open': True}"/>
|
||||
|
||||
<xpath expr="//div[hasclass('o_task_assignees_inline')]" position="after">
|
||||
<field name="involved_user_ids" widget="many2many_avatar_user" invisible="is_generic"/>
|
||||
<field name="is_generic" readonly="not has_supervisor_access"/>
|
||||
<field name="record_paused" invisible="1"/>
|
||||
<field name="model_id" readonly="not has_supervisor_access" options="{'no_open': True}"/>
|
||||
</xpath>
|
||||
<!-- <xpath expr="//field[@name='allocated_hours']" position="after">-->
|
||||
<!-- <field name="estimated_hours"/>-->
|
||||
|
|
@ -95,8 +95,8 @@
|
|||
</list>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Reassignment History" invisible="not reassignment_history">
|
||||
<field name="reassignment_history" widget="html" readonly="1"/>
|
||||
<page string="Reassignment History" invisible="not reassignment_history">
|
||||
<field name="reassignment_history" widget="html" readonly="1"/>
|
||||
</page>
|
||||
<page string="Task Activity Log" invisible="not show_approval_flow">
|
||||
<field name="task_activity_log" widget="html" options="{'sanitize': False}" readonly="1" force_save="1"/>
|
||||
|
|
@ -207,10 +207,10 @@
|
|||
<xpath expr="//filter[@name='my_tasks']" position="attributes">
|
||||
<attribute name="domain">['|', ('user_ids', 'in', uid), ('involved_user_ids', 'in', uid)]</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//filter[@name='my_tasks']" position="after">
|
||||
<filter name="task_need_approval" string="Need Approval" domain="[('approval_status', '=', 'submitted')]"/>
|
||||
<filter name="task_approved" string="Approved" domain="[('approval_status', '=', 'approved')]"/>
|
||||
<filter name="task_rejected" string="Rejected" domain="[('approval_status', '=', 'refused')]"/>
|
||||
<xpath expr="//filter[@name='my_tasks']" position="after">
|
||||
<filter name="task_need_approval" string="Need Approval" domain="[('approval_status', '=', 'submitted')]"/>
|
||||
<filter name="task_approved" string="Approved" domain="[('approval_status', '=', 'approved')]"/>
|
||||
<filter name="task_rejected" string="Rejected" domain="[('approval_status', '=', 'refused')]"/>
|
||||
</xpath> </field>
|
||||
</record>
|
||||
|
||||
|
|
@ -241,58 +241,59 @@
|
|||
|
||||
|
||||
|
||||
|
||||
<record id="project_task_kanban_task_id_module_my_tasks" model="ir.ui.view">
|
||||
<field name="name">project.task.kanban.task.id.module.my.tasks</field>
|
||||
<field name="model">project.task</field>
|
||||
<field name="inherit_id" ref="project.view_task_kanban_inherit_my_task"/>
|
||||
<field name="mode">primary</field>
|
||||
<field name="priority">80</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='subtask_count']" position="after">
|
||||
<field name="task_display_id"/>
|
||||
<field name="module_display_name"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_task_kanban_task_id_module_all_tasks" model="ir.ui.view">
|
||||
<field name="name">project.task.kanban.task.id.module.all.tasks</field>
|
||||
<field name="model">project.task</field>
|
||||
<field name="inherit_id" ref="project.view_task_kanban_inherit_all_task"/>
|
||||
<field name="mode">primary</field>
|
||||
<field name="priority">80</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='subtask_count']" position="after">
|
||||
<field name="task_display_id"/>
|
||||
<field name="module_display_name"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_task_kanban_task_id_module_project_tasks" model="ir.ui.view">
|
||||
<field name="name">project.task.kanban.task.id.module.project.tasks</field>
|
||||
<field name="model">project.task</field>
|
||||
<field name="inherit_id" ref="project.view_task_kanban_inherit_view_default_project"/>
|
||||
<field name="mode">primary</field>
|
||||
<field name="priority">80</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='subtask_count']" position="after">
|
||||
<field name="task_display_id"/>
|
||||
<field name="module_display_name"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project.open_view_my_task_list_kanban" model="ir.actions.act_window.view">
|
||||
<field name="view_id" ref="project_task_timesheet_extended.project_task_kanban_task_id_module_my_tasks"/>
|
||||
</record>
|
||||
<record id="project.open_view_all_task_list_kanban" model="ir.actions.act_window.view">
|
||||
<field name="view_id" ref="project_task_timesheet_extended.project_task_kanban_task_id_module_all_tasks"/>
|
||||
</record>
|
||||
<record id="project.project_task_kanban_action_view" model="ir.actions.act_window.view">
|
||||
<field name="view_id" ref="project_task_timesheet_extended.project_task_kanban_task_id_module_project_tasks"/>
|
||||
|
||||
<record id="project_task_kanban_task_id_module_my_tasks" model="ir.ui.view">
|
||||
<field name="name">project.task.kanban.task.id.module.my.tasks</field>
|
||||
<field name="model">project.task</field>
|
||||
<field name="inherit_id" ref="project.view_task_kanban_inherit_my_task"/>
|
||||
<field name="mode">primary</field>
|
||||
<field name="priority">80</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='subtask_count']" position="after">
|
||||
<field name="task_display_id"/>
|
||||
<field name="module_display_name"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_task_kanban_task_id_module_all_tasks" model="ir.ui.view">
|
||||
<field name="name">project.task.kanban.task.id.module.all.tasks</field>
|
||||
<field name="model">project.task</field>
|
||||
<field name="inherit_id" ref="project.view_task_kanban_inherit_all_task"/>
|
||||
<field name="mode">primary</field>
|
||||
<field name="priority">80</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='subtask_count']" position="after">
|
||||
<field name="task_display_id"/>
|
||||
<field name="module_display_name"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_task_kanban_task_id_module_project_tasks" model="ir.ui.view">
|
||||
<field name="name">project.task.kanban.task.id.module.project.tasks</field>
|
||||
<field name="model">project.task</field>
|
||||
<field name="inherit_id" ref="project.view_task_kanban_inherit_view_default_project"/>
|
||||
<field name="mode">primary</field>
|
||||
<field name="priority">80</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='subtask_count']" position="after">
|
||||
<field name="task_display_id"/>
|
||||
<field name="module_display_name"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project.open_view_my_task_list_kanban" model="ir.actions.act_window.view">
|
||||
<field name="view_id" ref="project_task_timesheet_extended.project_task_kanban_task_id_module_my_tasks"/>
|
||||
</record>
|
||||
<record id="project.open_view_all_task_list_kanban" model="ir.actions.act_window.view">
|
||||
<field name="view_id" ref="project_task_timesheet_extended.project_task_kanban_task_id_module_all_tasks"/>
|
||||
</record>
|
||||
<record id="project.project_task_kanban_action_view" model="ir.actions.act_window.view">
|
||||
<field name="view_id" ref="project_task_timesheet_extended.project_task_kanban_task_id_module_project_tasks"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ class TaskRejectReasonWizard(models.TransientModel):
|
|||
|
||||
reason = fields.Text(string="Rejection Reason", required=True)
|
||||
task_id = fields.Many2one("project.task", string="Task", required=True)
|
||||
stage_id = fields.Many2one("project.task.type", string="Return To Stage", required=True)
|
||||
return_to_previous_stages = fields.Boolean(default=False)
|
||||
stage_id = fields.Many2one("project.task.type", string="Return To Stage",)
|
||||
available_stage_ids = fields.Many2many("project.task.type", compute="_compute_available_stage_ids")
|
||||
|
||||
@api.depends("task_id", "task_id.project_id", "task_id.stage_id")
|
||||
|
|
@ -16,17 +17,20 @@ class TaskRejectReasonWizard(models.TransientModel):
|
|||
for wizard in self:
|
||||
stages = wizard.task_id.project_id.type_ids
|
||||
if wizard.task_id.stage_id:
|
||||
stages = stages.filtered(lambda s: s.id != wizard.task_id.stage_id.id)
|
||||
stages = stages.filtered(lambda s: s.id != wizard.task_id.stage_id.id and s.sequence < wizard.task_id.stage_id.sequence)
|
||||
wizard.available_stage_ids = [(6, 0, stages.ids)]
|
||||
|
||||
def action_reject(self):
|
||||
self.ensure_one()
|
||||
if not self.reason:
|
||||
raise UserError(_("Please enter a reason for rejection."))
|
||||
if not self.stage_id:
|
||||
if not self.stage_id and self.return_to_previous_stages:
|
||||
raise UserError(_("Please select the stage where the task should be returned."))
|
||||
|
||||
self.task_id.reject_and_return(reason=self.reason, return_stage=self.stage_id)
|
||||
if self.return_to_previous_stages:
|
||||
self.task_id.reject_and_return(reason=self.reason, return_stage=self.stage_id)
|
||||
else:
|
||||
self.task_id.reject_and_return(reason=self.reason)
|
||||
return {"type": "ir.actions.act_window_close"}
|
||||
|
||||
|
||||
|
|
@ -84,7 +88,7 @@ class TaskRequestTimelinesWizard(models.TransientModel):
|
|||
values["line_ids"] = [
|
||||
(0, 0, {
|
||||
"stage_id": line.stage_id.id,
|
||||
"responsible_user_id": line.responsible_lead.id,
|
||||
"responsible_user_id": line.responsible_lead.id,
|
||||
"user_ids": [(6, 0, line.assigned_to.ids)],
|
||||
})
|
||||
for line in task.assignees_timelines.sorted(lambda l: l.stage_sequence)
|
||||
|
|
@ -109,7 +113,7 @@ class TaskRequestTimelinesWizardLine(models.TransientModel):
|
|||
wizard_id = fields.Many2one("task.request.timelines.wizard", required=True, ondelete="cascade")
|
||||
task_id = fields.Many2one(related="wizard_id.task_id", store=False)
|
||||
stage_id = fields.Many2one("project.task.type", string="Stage")
|
||||
responsible_user_id = fields.Many2one("res.users", string="Responsible User")
|
||||
responsible_user_id = fields.Many2one("res.users", string="Responsible User")
|
||||
user_ids = fields.Many2many("res.users", string="Assignees")
|
||||
available_user_ids = fields.Many2many("res.users", compute="_compute_available_user_ids")
|
||||
|
||||
|
|
@ -215,4 +219,4 @@ class TaskReassignAssigneesWizardLine(models.TransientModel):
|
|||
users |= line.stage_id.team_id.all_members_ids
|
||||
if line.task_id.project_id:
|
||||
users |= line.task_id.project_id.members_ids | line.task_id.project_id.user_id | line.task_id.project_id.project_lead
|
||||
line.available_user_ids = [(6, 0, users.filtered(lambda u: not u.share).ids)]
|
||||
line.available_user_ids = [(6, 0, users.filtered(lambda u: not u.share).ids)]
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@
|
|||
<field name="task_id" invisible="1"/>
|
||||
<field name="available_stage_ids" invisible="1"/>
|
||||
<field name="reason" placeholder="Enter the reason for rejection..."/>
|
||||
<field name="stage_id" domain="[('id', 'in', available_stage_ids)]" options="{'no_create': True, 'no_open': True}"/>
|
||||
<field name="return_to_previous_stages" string="Return to Previous Stages"/>
|
||||
<field name="stage_id" required="return_to_previous_stages" invisible="not return_to_previous_stages" domain="[('id', 'in', available_stage_ids)]" options="{'no_create': True, 'no_open': True}"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button string="Reject" type="object" name="action_reject" class="btn-primary"/>
|
||||
|
|
@ -78,7 +79,7 @@
|
|||
<field name="line_ids" nolabel="1">
|
||||
<list editable="bottom" create="0" delete="0">
|
||||
<field name="stage_id" readonly="1" force_save="1" options="{'no_open': True}"/>
|
||||
<field name="responsible_user_id" force_save="1" options="{'no_create': True, 'no_open': True}"/>
|
||||
<field name="responsible_user_id" force_save="1" options="{'no_create': True, 'no_open': True}"/>
|
||||
<field name="available_user_ids" column_invisible="1"/>
|
||||
<field name="user_ids" string="Assignees" widget="many2many_tags" domain="[('id', 'in', available_user_ids)]" options="{'no_create': True, 'no_open': True}"/>
|
||||
</list>
|
||||
|
|
@ -118,4 +119,4 @@
|
|||
</form>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
</odoo>
|
||||
|
|
|
|||
Loading…
Reference in New Issue