|
@@ -37,8 +37,8 @@ class HelpdeskTeamExtras(models.Model):
|
|
|
"""Override create to regenerate form XML if template is set"""
|
|
"""Override create to regenerate form XML if template is set"""
|
|
|
teams = super().create(vals_list)
|
|
teams = super().create(vals_list)
|
|
|
# After create, if template is set and form view exists, regenerate
|
|
# After create, if template is set and form view exists, regenerate
|
|
|
- # This handles the case when team is created with template_id already set
|
|
|
|
|
- for team in teams.filtered(lambda t: t.use_website_helpdesk_form and t.template_id and t.website_form_view_id):
|
|
|
|
|
|
|
+ # This handles the case when team is created with template_id or workflow_template_id already set
|
|
|
|
|
+ for team in teams.filtered(lambda t: t.use_website_helpdesk_form and t.website_form_view_id and (t.template_id or (t.workflow_template_id and t.workflow_template_id.field_ids))):
|
|
|
team._regenerate_form_from_template()
|
|
team._regenerate_form_from_template()
|
|
|
return teams
|
|
return teams
|
|
|
|
|
|
|
@@ -47,7 +47,7 @@ class HelpdeskTeamExtras(models.Model):
|
|
|
result = super()._ensure_submit_form_view()
|
|
result = super()._ensure_submit_form_view()
|
|
|
# After view is created, if template is set, regenerate form
|
|
# After view is created, if template is set, regenerate form
|
|
|
# Note: super() may have created views, so we need to refresh to get updated website_form_view_id
|
|
# Note: super() may have created views, so we need to refresh to get updated website_form_view_id
|
|
|
- for team in self.filtered(lambda t: t.use_website_helpdesk_form and t.template_id):
|
|
|
|
|
|
|
+ for team in self.filtered(lambda t: t.use_website_helpdesk_form and (t.template_id or (t.workflow_template_id and t.workflow_template_id.field_ids))):
|
|
|
# Refresh to get updated website_form_view_id after super() created it
|
|
# Refresh to get updated website_form_view_id after super() created it
|
|
|
team.invalidate_recordset(['website_form_view_id'])
|
|
team.invalidate_recordset(['website_form_view_id'])
|
|
|
if team.website_form_view_id:
|
|
if team.website_form_view_id:
|
|
@@ -57,7 +57,7 @@ class HelpdeskTeamExtras(models.Model):
|
|
|
def write(self, vals):
|
|
def write(self, vals):
|
|
|
"""Override write to regenerate form XML when template changes"""
|
|
"""Override write to regenerate form XML when template changes"""
|
|
|
result = super().write(vals)
|
|
result = super().write(vals)
|
|
|
- if 'template_id' in vals:
|
|
|
|
|
|
|
+ if 'template_id' in vals or 'workflow_template_id' in vals:
|
|
|
# Regenerate form XML when template is assigned/changed
|
|
# Regenerate form XML when template is assigned/changed
|
|
|
# After super().write(), refresh teams to get updated values
|
|
# After super().write(), refresh teams to get updated values
|
|
|
teams_to_process = self.browse(self.ids).filtered('use_website_helpdesk_form')
|
|
teams_to_process = self.browse(self.ids).filtered('use_website_helpdesk_form')
|
|
@@ -66,11 +66,12 @@ class HelpdeskTeamExtras(models.Model):
|
|
|
# This handles the case when template is assigned but view doesn't exist yet
|
|
# This handles the case when template is assigned but view doesn't exist yet
|
|
|
if not team.website_form_view_id:
|
|
if not team.website_form_view_id:
|
|
|
# Call _ensure_submit_form_view which will create the view if needed
|
|
# Call _ensure_submit_form_view which will create the view if needed
|
|
|
- # This method already handles template regeneration if template_id is set
|
|
|
|
|
|
|
+ # This method handles template regeneration for both template_id and workflow_template_id
|
|
|
team._ensure_submit_form_view()
|
|
team._ensure_submit_form_view()
|
|
|
else:
|
|
else:
|
|
|
# View exists, regenerate or restore form based on template
|
|
# View exists, regenerate or restore form based on template
|
|
|
- if team.template_id:
|
|
|
|
|
|
|
+ has_template = team.template_id or (team.workflow_template_id and team.workflow_template_id.field_ids)
|
|
|
|
|
+ if has_template:
|
|
|
team._regenerate_form_from_template()
|
|
team._regenerate_form_from_template()
|
|
|
else:
|
|
else:
|
|
|
# If template is removed, restore default form
|
|
# If template is removed, restore default form
|
|
@@ -393,9 +394,22 @@ class HelpdeskTeamExtras(models.Model):
|
|
|
return result
|
|
return result
|
|
|
|
|
|
|
|
def _regenerate_form_from_template(self):
|
|
def _regenerate_form_from_template(self):
|
|
|
- """Regenerate the website form XML based on the template"""
|
|
|
|
|
|
|
+ """Regenerate the website form XML based on the template (supports both legacy template_id and workflow_template_id)"""
|
|
|
self.ensure_one()
|
|
self.ensure_one()
|
|
|
- if not self.template_id or not self.website_form_view_id:
|
|
|
|
|
|
|
+
|
|
|
|
|
+ # Get template fields from either legacy template or workflow template
|
|
|
|
|
+ template_fields = self.env['helpdesk.template.field']
|
|
|
|
|
+ template_source = None
|
|
|
|
|
+
|
|
|
|
|
+ # Priority: workflow_template_id over template_id (legacy)
|
|
|
|
|
+ if self.workflow_template_id and self.workflow_template_id.field_ids:
|
|
|
|
|
+ template_fields = self.workflow_template_id.field_ids.sorted('sequence')
|
|
|
|
|
+ template_source = f"workflow_template {self.workflow_template_id.id}"
|
|
|
|
|
+ elif self.template_id and self.template_id.field_ids:
|
|
|
|
|
+ template_fields = self.template_id.field_ids.sorted('sequence')
|
|
|
|
|
+ template_source = f"template {self.template_id.id}"
|
|
|
|
|
+
|
|
|
|
|
+ if not template_fields or not self.website_form_view_id:
|
|
|
return
|
|
return
|
|
|
|
|
|
|
|
# Get base form structure (from default template)
|
|
# Get base form structure (from default template)
|
|
@@ -422,12 +436,9 @@ class HelpdeskTeamExtras(models.Model):
|
|
|
|
|
|
|
|
# Create environment with website language for translations
|
|
# Create environment with website language for translations
|
|
|
env_lang = self.env(context=dict(self.env.context, lang=lang))
|
|
env_lang = self.env(context=dict(self.env.context, lang=lang))
|
|
|
-
|
|
|
|
|
- # Get template fields sorted by sequence
|
|
|
|
|
- template_fields = self.template_id.field_ids.sorted('sequence')
|
|
|
|
|
|
|
|
|
|
# Log template fields for debugging
|
|
# Log template fields for debugging
|
|
|
- _logger.info(f"Regenerating form for team {self.id}, template {self.template_id.id} with {len(template_fields)} fields")
|
|
|
|
|
|
|
+ _logger.info(f"Regenerating form for team {self.id}, {template_source} with {len(template_fields)} fields")
|
|
|
for tf in template_fields:
|
|
for tf in template_fields:
|
|
|
_logger.info(f" - Field: {tf.field_id.name if tf.field_id else 'None'} (type: {tf.field_id.ttype if tf.field_id else 'None'})")
|
|
_logger.info(f" - Field: {tf.field_id.name if tf.field_id else 'None'} (type: {tf.field_id.ttype if tf.field_id else 'None'})")
|
|
|
|
|
|
|
@@ -1303,21 +1314,67 @@ class HelpdeskTeamExtras(models.Model):
|
|
|
|
|
|
|
|
# Mapping: stage_template_id -> real_stage_id
|
|
# Mapping: stage_template_id -> real_stage_id
|
|
|
stage_mapping = {}
|
|
stage_mapping = {}
|
|
|
|
|
+ stages_created = 0
|
|
|
|
|
+ stages_reused = 0
|
|
|
|
|
|
|
|
- # 1. Create real stages from template stages
|
|
|
|
|
|
|
+ # 1. Create or reuse real stages from template stages
|
|
|
for stage_template in template.stage_template_ids.sorted('sequence'):
|
|
for stage_template in template.stage_template_ids.sorted('sequence'):
|
|
|
- stage_vals = {
|
|
|
|
|
- 'name': stage_template.name,
|
|
|
|
|
- 'sequence': stage_template.sequence,
|
|
|
|
|
- 'fold': stage_template.fold,
|
|
|
|
|
- 'description': stage_template.description or False,
|
|
|
|
|
- 'template_id': stage_template.template_id_email.id if stage_template.template_id_email else False,
|
|
|
|
|
- 'legend_blocked': stage_template.legend_blocked,
|
|
|
|
|
- 'legend_done': stage_template.legend_done,
|
|
|
|
|
- 'legend_normal': stage_template.legend_normal,
|
|
|
|
|
- 'team_ids': [(4, self.id)],
|
|
|
|
|
- }
|
|
|
|
|
- real_stage = self.env['helpdesk.stage'].create(stage_vals)
|
|
|
|
|
|
|
+ # Check if a stage with the same name already exists for this team
|
|
|
|
|
+ existing_stage = self.env['helpdesk.stage'].search([
|
|
|
|
|
+ ('name', '=', stage_template.name),
|
|
|
|
|
+ ('team_ids', 'in', [self.id])
|
|
|
|
|
+ ], limit=1)
|
|
|
|
|
+
|
|
|
|
|
+ if existing_stage:
|
|
|
|
|
+ # Reuse existing stage
|
|
|
|
|
+ stages_reused += 1
|
|
|
|
|
+ _logger.info(
|
|
|
|
|
+ f"Reusing existing stage '{existing_stage.name}' (ID: {existing_stage.id}) "
|
|
|
|
|
+ f"for team '{self.name}' instead of creating duplicate"
|
|
|
|
|
+ )
|
|
|
|
|
+ real_stage = existing_stage
|
|
|
|
|
+ # Update stage properties from template if needed
|
|
|
|
|
+ update_vals = {}
|
|
|
|
|
+ if stage_template.sequence != existing_stage.sequence:
|
|
|
|
|
+ update_vals['sequence'] = stage_template.sequence
|
|
|
|
|
+ if stage_template.fold != existing_stage.fold:
|
|
|
|
|
+ update_vals['fold'] = stage_template.fold
|
|
|
|
|
+ if stage_template.description and stage_template.description != existing_stage.description:
|
|
|
|
|
+ update_vals['description'] = stage_template.description
|
|
|
|
|
+ if stage_template.template_id_email and stage_template.template_id_email.id != existing_stage.template_id.id:
|
|
|
|
|
+ update_vals['template_id'] = stage_template.template_id_email.id
|
|
|
|
|
+ if stage_template.legend_blocked != existing_stage.legend_blocked:
|
|
|
|
|
+ update_vals['legend_blocked'] = stage_template.legend_blocked
|
|
|
|
|
+ if stage_template.legend_done != existing_stage.legend_done:
|
|
|
|
|
+ update_vals['legend_done'] = stage_template.legend_done
|
|
|
|
|
+ if stage_template.legend_normal != existing_stage.legend_normal:
|
|
|
|
|
+ update_vals['legend_normal'] = stage_template.legend_normal
|
|
|
|
|
+
|
|
|
|
|
+ if update_vals:
|
|
|
|
|
+ existing_stage.write(update_vals)
|
|
|
|
|
+
|
|
|
|
|
+ # Ensure stage is linked to this team (in case it wasn't)
|
|
|
|
|
+ if self.id not in existing_stage.team_ids.ids:
|
|
|
|
|
+ existing_stage.team_ids = [(4, self.id)]
|
|
|
|
|
+ else:
|
|
|
|
|
+ # Create new stage
|
|
|
|
|
+ stage_vals = {
|
|
|
|
|
+ 'name': stage_template.name,
|
|
|
|
|
+ 'sequence': stage_template.sequence,
|
|
|
|
|
+ 'fold': stage_template.fold,
|
|
|
|
|
+ 'description': stage_template.description or False,
|
|
|
|
|
+ 'template_id': stage_template.template_id_email.id if stage_template.template_id_email else False,
|
|
|
|
|
+ 'legend_blocked': stage_template.legend_blocked,
|
|
|
|
|
+ 'legend_done': stage_template.legend_done,
|
|
|
|
|
+ 'legend_normal': stage_template.legend_normal,
|
|
|
|
|
+ 'team_ids': [(4, self.id)],
|
|
|
|
|
+ }
|
|
|
|
|
+ real_stage = self.env['helpdesk.stage'].create(stage_vals)
|
|
|
|
|
+ stages_created += 1
|
|
|
|
|
+ _logger.info(
|
|
|
|
|
+ f"Created new stage '{real_stage.name}' (ID: {real_stage.id}) for team '{self.name}'"
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
stage_mapping[stage_template.id] = real_stage.id
|
|
stage_mapping[stage_template.id] = real_stage.id
|
|
|
|
|
|
|
|
# 2. Create real SLAs from template SLAs
|
|
# 2. Create real SLAs from template SLAs
|
|
@@ -1364,17 +1421,29 @@ class HelpdeskTeamExtras(models.Model):
|
|
|
if template.sla_template_ids and not self.use_sla:
|
|
if template.sla_template_ids and not self.use_sla:
|
|
|
self.use_sla = True
|
|
self.use_sla = True
|
|
|
|
|
|
|
|
|
|
+ # Build notification message
|
|
|
|
|
+ if stages_reused > 0:
|
|
|
|
|
+ message = _(
|
|
|
|
|
+ 'Successfully applied template "%s": %d stage(s) reused, %d new stage(s) created, and %d SLA policy(ies) created.',
|
|
|
|
|
+ template.name,
|
|
|
|
|
+ stages_reused,
|
|
|
|
|
+ stages_created,
|
|
|
|
|
+ len(template.sla_template_ids)
|
|
|
|
|
+ )
|
|
|
|
|
+ else:
|
|
|
|
|
+ message = _(
|
|
|
|
|
+ 'Successfully created %d stage(s) and %d SLA policy(ies) from template "%s".',
|
|
|
|
|
+ len(stage_mapping),
|
|
|
|
|
+ len(template.sla_template_ids),
|
|
|
|
|
+ template.name
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
return {
|
|
return {
|
|
|
'type': 'ir.actions.client',
|
|
'type': 'ir.actions.client',
|
|
|
'tag': 'display_notification',
|
|
'tag': 'display_notification',
|
|
|
'params': {
|
|
'params': {
|
|
|
'title': _('Workflow Template Applied'),
|
|
'title': _('Workflow Template Applied'),
|
|
|
- 'message': _(
|
|
|
|
|
- 'Successfully created %d stage(s) and %d SLA policy(ies) from template "%s".',
|
|
|
|
|
- len(stage_mapping),
|
|
|
|
|
- len(template.sla_template_ids),
|
|
|
|
|
- template.name
|
|
|
|
|
- ),
|
|
|
|
|
|
|
+ 'message': message,
|
|
|
'type': 'success',
|
|
'type': 'success',
|
|
|
'sticky': False,
|
|
'sticky': False,
|
|
|
}
|
|
}
|