[IMP] hr:revert plan automation on triggers
task - 2628793 closes odoo/odoo#75528 Related: odoo/enterprise#20430 Related: odoo/upgrade#2776 Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
This commit is contained in:
@@ -53,8 +53,6 @@
|
||||
|
||||
<record id="onboarding_plan" model='hr.plan'>
|
||||
<field name="name">Onboarding</field>
|
||||
<field name="plan_type">onboarding</field>
|
||||
<field name="trigger">manual</field>
|
||||
<field name="plan_activity_type_ids" eval="[(6, 0, [
|
||||
ref('hr.onboarding_setup_it_materials'),
|
||||
ref('hr.onboarding_plan_training'),
|
||||
@@ -64,8 +62,6 @@
|
||||
|
||||
<record id="offboarding_plan" model='hr.plan'>
|
||||
<field name="name">Offboarding</field>
|
||||
<field name="plan_type">offboarding</field>
|
||||
<field name="trigger">manual</field>
|
||||
<field name="plan_activity_type_ids" eval="[(6, 0, [
|
||||
ref('hr.offboarding_setup_compute_out_delais'),
|
||||
ref('hr.offboarding_take_back_hr_materials'),
|
||||
|
||||
@@ -291,15 +291,13 @@ class HrEmployeePrivate(models.Model):
|
||||
('subscription_department_ids', 'in', employee.department_id.id)
|
||||
])._subscribe_users_automatically()
|
||||
# Launch onboarding plans
|
||||
if not employee._launch_plans_from_trigger(trigger='employee_creation'):
|
||||
# Keep the recommend message if no plans are launched
|
||||
url = '/web#%s' % url_encode({
|
||||
'action': 'hr.plan_wizard_action',
|
||||
'active_id': employee.id,
|
||||
'active_model': 'hr.employee',
|
||||
'menu_id': self.env.ref('hr.menu_hr_root').id,
|
||||
})
|
||||
employee._message_log(body=_('<b>Congratulations!</b> May I recommend you to setup an <a href="%s">onboarding plan?</a>') % (url))
|
||||
url = '/web#%s' % url_encode({
|
||||
'action': 'hr.plan_wizard_action',
|
||||
'active_id': employee.id,
|
||||
'active_model': 'hr.employee',
|
||||
'menu_id': self.env.ref('hr.menu_hr_root').id,
|
||||
})
|
||||
employee._message_log(body=_('<b>Congratulations!</b> May I recommend you to setup an <a href="%s">onboarding plan?</a>') % (url))
|
||||
return employee
|
||||
|
||||
def write(self, vals):
|
||||
@@ -360,9 +358,6 @@ class HrEmployeePrivate(models.Model):
|
||||
if employee[field] in archived_employees.user_id:
|
||||
employee[field] = False
|
||||
|
||||
# Launch automatic offboarding plans
|
||||
archived_employees._launch_plans_from_trigger(trigger='employee_archive')
|
||||
|
||||
if len(self) == 1 and not self.active and not self.env.context.get('no_wizard', False):
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
@@ -436,71 +431,6 @@ class HrEmployeePrivate(models.Model):
|
||||
self = self.with_user(real_user)
|
||||
return self
|
||||
|
||||
def _launch_plans_from_trigger(self, trigger):
|
||||
'''
|
||||
Launches all plans for given trigger
|
||||
|
||||
Returns False if no plans are launched, True otherwise
|
||||
'''
|
||||
plan_ids = self.env['hr.plan'].search([('trigger', '=', trigger)])
|
||||
if not plan_ids or not self:
|
||||
return False
|
||||
#Group plans and employees by company id
|
||||
plans_per_company = defaultdict(lambda: self.env['hr.plan'])
|
||||
for plan_id in plan_ids:
|
||||
plans_per_company[plan_id.company_id.id] |= plan_id
|
||||
employees_per_company = defaultdict(lambda: self.env['hr.employee'])
|
||||
for employee_id in self:
|
||||
employees_per_company[employee_id.company_id.id] |= employee_id
|
||||
#Launch the plans
|
||||
for company_id in employees_per_company:
|
||||
employees_per_company[company_id]._launch_plan(plans_per_company[company_id])
|
||||
return True
|
||||
|
||||
def _launch_plan(self, plan_ids):
|
||||
'''
|
||||
Launch all given plans
|
||||
'''
|
||||
for employee_id in self:
|
||||
for plan_id in plan_ids:
|
||||
employee_id._message_log(
|
||||
body=_('Plan %s has been launched.', plan_id.name),
|
||||
)
|
||||
errors = []
|
||||
for activity_type in plan_id.plan_activity_type_ids:
|
||||
responsible = False
|
||||
try:
|
||||
responsible = activity_type.get_responsible_id(employee_id)
|
||||
except UserError as error:
|
||||
errors.append(_(
|
||||
'Warning ! The step "%(name)s: %(summary)s" assigned to %(responsible)s '
|
||||
'could not be started because: "%(error)s"',
|
||||
name=activity_type.activity_type_id.name,
|
||||
summary=activity_type.summary,
|
||||
responsible=activity_type.responsible,
|
||||
error=str(error)
|
||||
))
|
||||
continue
|
||||
|
||||
if self.env['hr.employee'].with_user(responsible).check_access_rights('read', raise_exception=False):
|
||||
if activity_type.deadline_type == 'default':
|
||||
date_deadline = self.env['mail.activity']._calculate_date_deadline(activity_type.activity_type_id)
|
||||
elif activity_type.deadline_type == 'plan_active':
|
||||
date_deadline = fields.Date.context_today(self)
|
||||
elif activity_type.deadline_type == 'trigger_offset':
|
||||
date_deadline = fields.Date.add(fields.Date.context_today(self), days=activity_type.deadline_days)
|
||||
|
||||
employee_id.activity_schedule(
|
||||
activity_type_id=activity_type.activity_type_id.id,
|
||||
summary=activity_type.summary,
|
||||
note=activity_type.note,
|
||||
user_id=responsible.id,
|
||||
date_deadline=date_deadline,
|
||||
)
|
||||
employee_id._message_log(
|
||||
body='<br/>'.join(errors),
|
||||
)
|
||||
|
||||
def _get_unusual_days(self, date_from, date_to=None):
|
||||
# Checking the calendar directly allows to not grey out the leaves taken
|
||||
# by the employee
|
||||
|
||||
@@ -10,12 +10,6 @@ class HrPlanActivityType(models.Model):
|
||||
_description = 'Plan activity type'
|
||||
_rec_name = 'summary'
|
||||
|
||||
_sql_constraints = [
|
||||
(
|
||||
'check_deadline_days', 'CHECK (COALESCE(deadline_days) >= 0)',
|
||||
'Days deadline must be positive.'
|
||||
),
|
||||
]
|
||||
|
||||
activity_type_id = fields.Many2one(
|
||||
'mail.activity.type', 'Activity Type',
|
||||
@@ -29,24 +23,10 @@ class HrPlanActivityType(models.Model):
|
||||
('manager', 'Manager'),
|
||||
('employee', 'Employee'),
|
||||
('other', 'Other')], default='employee', string='Responsible', required=True)
|
||||
# sgv todo change back to 'Responsible Person'
|
||||
responsible_id = fields.Many2one('res.users', 'Name', help='Specific responsible of activity if not linked to the employee.')
|
||||
note = fields.Html('Note')
|
||||
deadline_type = fields.Selection(
|
||||
[
|
||||
('default', 'Default value'),
|
||||
('plan_active', "At plan's activation"),
|
||||
('trigger_offset', 'Days after activation trigger'),
|
||||
],
|
||||
string='Activity Deadline',
|
||||
default='default',
|
||||
required=True,
|
||||
)
|
||||
deadline_days = fields.Integer(string='Days Deadline')
|
||||
company_id = fields.Many2one(
|
||||
'res.company',
|
||||
string='Company',
|
||||
default=lambda self: self.env.company,
|
||||
)
|
||||
|
||||
|
||||
@api.depends('activity_type_id')
|
||||
def _compute_default_summary(self):
|
||||
@@ -85,68 +65,3 @@ class HrPlan(models.Model):
|
||||
name = fields.Char('Name', required=True)
|
||||
plan_activity_type_ids = fields.Many2many('hr.plan.activity.type', string='Activities')
|
||||
active = fields.Boolean(default=True)
|
||||
plan_type = fields.Selection(
|
||||
[
|
||||
('onboarding', 'Onboarding'),
|
||||
('offboarding', 'Offboarding'),
|
||||
('other', 'Other'),
|
||||
], string='Type', default='onboarding', required=True,
|
||||
)
|
||||
trigger_onboarding = fields.Selection(
|
||||
[
|
||||
('manual', 'Manual'),
|
||||
('employee_creation', 'Employee Creation'),
|
||||
], compute='_compute_triggers', inverse='_inverse_triggers',
|
||||
required=True, readonly=False,
|
||||
)
|
||||
trigger_offboarding = fields.Selection(
|
||||
[
|
||||
('manual', 'Manual'),
|
||||
('employee_archive', 'Archived Employee'),
|
||||
], compute='_compute_triggers', inverse='_inverse_triggers',
|
||||
required=True, readonly=False,
|
||||
)
|
||||
trigger_other = fields.Selection(
|
||||
[
|
||||
('manual', 'Manual'),
|
||||
], compute='_compute_triggers', inverse='_inverse_triggers',
|
||||
required=True, readonly=False,
|
||||
)
|
||||
trigger = fields.Char(default='manual', compute='_compute_trigger', store=True)
|
||||
company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.company)
|
||||
|
||||
@api.depends('trigger')
|
||||
def _compute_triggers(self):
|
||||
trigger_types = {'trigger_onboarding', 'trigger_offboarding', 'trigger_other'}
|
||||
type_to_trigger = {
|
||||
'onboarding': 'trigger_onboarding',
|
||||
'offboarding': 'trigger_offboarding',
|
||||
'other': 'trigger_other',
|
||||
}
|
||||
for record in self:
|
||||
#trigger for active
|
||||
record[type_to_trigger[record.plan_type]] = record.trigger or 'manual'
|
||||
#'manual' for all others
|
||||
for disabled_trigger in trigger_types - {type_to_trigger[record.plan_type]}:
|
||||
record[disabled_trigger] = 'manual'
|
||||
|
||||
def _inverse_triggers(self):
|
||||
type_to_trigger = {
|
||||
'onboarding': 'trigger_onboarding',
|
||||
'offboarding': 'trigger_offboarding',
|
||||
'other': 'trigger_other',
|
||||
}
|
||||
for record in self:
|
||||
# or 'manual' required is for trigger_other since it can not be changed it's always False here
|
||||
record.trigger = record[type_to_trigger[record.plan_type]] or 'manual'
|
||||
|
||||
@api.depends('plan_type')
|
||||
def _compute_trigger(self):
|
||||
# In case only plan_type changes
|
||||
type_to_trigger = {
|
||||
'onboarding': 'trigger_onboarding',
|
||||
'offboarding': 'trigger_offboarding',
|
||||
'other': 'trigger_other',
|
||||
}
|
||||
for record in self:
|
||||
record.trigger = record[type_to_trigger[record.plan_type]] or 'manual'
|
||||
|
||||
@@ -49,18 +49,5 @@
|
||||
<field name="model_id" ref="model_hr_job"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id', 'in', company_ids)]</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_plan_comp_rule" model="ir.rule">
|
||||
<field name="name">Plan multi company rule</field>
|
||||
<field name="model_id" ref="model_hr_plan"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id', 'in', company_ids)]</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_plan_activity_type_comp_rule" model="ir.rule">
|
||||
<field name="name">Plan activity type multi company rule</field>
|
||||
<field name="model_id" ref="model_hr_plan_activity_type"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id', 'in', company_ids)]</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Planning">
|
||||
<field name="name"/>
|
||||
<field name="plan_type"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -38,23 +37,12 @@
|
||||
<field name="name" placeholder="e.g. Onboarding"/>
|
||||
</h1>
|
||||
</div>
|
||||
<field name="active" invisible="1"/>
|
||||
<group>
|
||||
<group>
|
||||
<field name="plan_type" widget="radio"/>
|
||||
<field name="trigger" invisible="1"/>
|
||||
<field name="trigger_onboarding" string="Activation Trigger" attrs="{'invisible': [('plan_type', '!=', 'onboarding')]}"/>
|
||||
<field name="trigger_offboarding" string="Activation Trigger" attrs="{'invisible': [('plan_type', '!=', 'offboarding')]}"/>
|
||||
<field name="trigger_other" string="Activation Trigger" attrs="{'invisible': [('plan_type', '!=', 'other')], 'readonly': True}"/>
|
||||
</group>
|
||||
</group>
|
||||
<group string="Activities">
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="plan_activity_type_ids" nolabel="1">
|
||||
<tree editable="bottom">
|
||||
<field name="activity_type_id"/>
|
||||
<field name="summary"/>
|
||||
<field name="deadline_type"/>
|
||||
<field name="deadline_days" attrs="{'readonly': [('deadline_type', '!=', 'trigger_offset')]}"/>
|
||||
<field name="responsible"/>
|
||||
<field name="responsible_id" attrs="{'readonly': [('responsible', '!=', 'other')]}"/>
|
||||
</tree>
|
||||
@@ -72,8 +60,6 @@
|
||||
<tree string="Activities">
|
||||
<field name="activity_type_id"/>
|
||||
<field name="summary"/>
|
||||
<field name="deadline_type"/>
|
||||
<field name="deadline_days" attrs="{'invisible': [('deadline_type', '!=', 'trigger_offset')]}"/>
|
||||
<field name="responsible"/>
|
||||
</tree>
|
||||
</field>
|
||||
@@ -88,8 +74,6 @@
|
||||
<group>
|
||||
<field name="activity_type_id"/>
|
||||
<field name="summary"/>
|
||||
<field name="deadline_type"/>
|
||||
<field name="deadline_days" attrs="{'invisible': [('deadline_type', '!=', 'trigger_offset')]}"/>
|
||||
<field name="responsible"/>
|
||||
<field name="responsible_id" attrs="{'invisible': [('responsible', '!=', 'other')]}"/>
|
||||
<field name="note"/>
|
||||
|
||||
@@ -8,20 +8,25 @@ class HrPlanWizard(models.TransientModel):
|
||||
_name = 'hr.plan.wizard'
|
||||
_description = 'Plan Wizard'
|
||||
|
||||
plan_id = fields.Many2one(
|
||||
'hr.plan',
|
||||
default=lambda self: self.env['hr.plan'].search([('trigger', '=', 'manual')], limit=1),
|
||||
domain="[('trigger', '=', 'manual')]",
|
||||
required=True,
|
||||
)
|
||||
plan_id = fields.Many2one('hr.plan', default=lambda self: self.env['hr.plan'].search([], limit=1))
|
||||
employee_id = fields.Many2one(
|
||||
'hr.employee', string='Employee', required=True,
|
||||
default=lambda self: self.env.context.get('active_id', None),
|
||||
)
|
||||
|
||||
def action_launch(self):
|
||||
self.ensure_one()
|
||||
self.employee_id._launch_plan(self.plan_id)
|
||||
for activity_type in self.plan_id.plan_activity_type_ids:
|
||||
responsible = activity_type.get_responsible_id(self.employee_id)
|
||||
|
||||
if self.env['hr.employee'].with_user(responsible).check_access_rights('read', raise_exception=False):
|
||||
date_deadline = self.env['mail.activity']._calculate_date_deadline(activity_type.activity_type_id)
|
||||
self.employee_id.activity_schedule(
|
||||
activity_type_id=activity_type.activity_type_id.id,
|
||||
summary=activity_type.summary,
|
||||
note=activity_type.note,
|
||||
user_id=responsible.id,
|
||||
date_deadline=date_deadline
|
||||
)
|
||||
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
|
||||
Reference in New Issue
Block a user