onboarding/models/onboarding_onboarding.py

135 lines
6.0 KiB
Python
Raw Permalink Normal View History

2024-05-03 12:58:20 +03:00
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import _, api, fields, models
from odoo.addons.onboarding.models.onboarding_progress import ONBOARDING_PROGRESS_STATES
class Onboarding(models.Model):
_name = 'onboarding.onboarding'
_description = 'Onboarding'
_order = 'sequence asc, id desc'
name = fields.Char('Name of the onboarding', translate=True)
# One word identifier used to define the onboarding panel's route: `/onboarding/{route_name}`.
route_name = fields.Char('One word name', required=True)
step_ids = fields.Many2many('onboarding.onboarding.step', string='Onboarding steps')
text_completed = fields.Char(
'Message at completion', default=_('Nice work! Your configuration is done.'),
help='Text shown on onboarding when completed')
is_per_company = fields.Boolean(
'Should be done per company?', compute='_compute_is_per_company', readonly=True, store=False,
)
panel_close_action_name = fields.Char(
'Closing action', help='Name of the onboarding model action to execute when closing the panel.')
current_progress_id = fields.Many2one(
'onboarding.progress', 'Onboarding Progress', compute='_compute_current_progress',
help='Onboarding Progress for the current context (company).')
current_onboarding_state = fields.Selection(
ONBOARDING_PROGRESS_STATES, string='Completion State', compute='_compute_current_progress', readonly=True)
is_onboarding_closed = fields.Boolean(string='Was panel closed?', compute='_compute_current_progress')
progress_ids = fields.One2many(
'onboarding.progress', 'onboarding_id', string='Onboarding Progress Records', readonly=True,
help='All Onboarding Progress Records (across companies).')
sequence = fields.Integer(default=10)
_sql_constraints = [
('route_name_uniq', 'UNIQUE (route_name)', 'Onboarding alias must be unique.'),
]
@api.depends('progress_ids', 'progress_ids.company_id', 'step_ids', 'step_ids.is_per_company')
def _compute_is_per_company(self):
# Once an onboarding is made "per-company", there is no drawback to simply still consider
# it per-company even when if its last per-company step is unlinked. This allows to avoid
# handling the merging of existing progress (step) records.
onboardings_with_per_company_steps_or_progress = self.filtered(
lambda o: o.progress_ids.company_id or (True in o.step_ids.mapped('is_per_company')))
onboardings_with_per_company_steps_or_progress.is_per_company = True
(self - onboardings_with_per_company_steps_or_progress).is_per_company = False
@api.depends_context('company')
@api.depends('progress_ids', 'progress_ids.is_onboarding_closed', 'progress_ids.onboarding_state', 'progress_ids.company_id')
def _compute_current_progress(self):
for onboarding in self:
current_progress_id = onboarding.progress_ids.filtered(
lambda progress: progress.company_id.id in {False, self.env.company.id})
if current_progress_id:
onboarding.current_onboarding_state = current_progress_id.onboarding_state
onboarding.current_progress_id = current_progress_id
onboarding.is_onboarding_closed = current_progress_id.is_onboarding_closed
else:
onboarding.current_onboarding_state = 'not_done'
onboarding.current_progress_id = False
onboarding.is_onboarding_closed = False
def write(self, vals):
"""Recompute progress step ids if new steps are added/removed."""
already_linked_steps = self.step_ids
res = super().write(vals)
if self.step_ids != already_linked_steps:
self.progress_ids._recompute_progress_step_ids()
return res
def action_close(self):
"""Close the onboarding panel."""
self.current_progress_id.action_close()
@api.model
def action_close_panel(self, xmlid):
"""Close the onboarding panel identified by its `xmlid`.
If not found, quietly do nothing.
"""
if onboarding := self.env.ref(xmlid, raise_if_not_found=False):
onboarding.action_close()
def action_refresh_progress_ids(self):
"""Re-initialize onboarding progress records (after step is_per_company change).
Meant to be called when `is_per_company` of linked steps is modified (or per-company
steps are added to an onboarding).
"""
onboardings_to_refresh_progress = self.filtered(
lambda o: o.is_per_company and o.progress_ids and not o.progress_ids.company_id
)
onboardings_to_refresh_progress.progress_ids.unlink()
onboardings_to_refresh_progress._create_progress()
def action_toggle_visibility(self):
self.current_progress_id.action_toggle_visibility()
def _search_or_create_progress(self):
"""Create Progress record(s) as necessary for the context."""
onboardings_without_progress = self.filtered(lambda onboarding: not onboarding.current_progress_id)
onboardings_without_progress._create_progress()
return self.current_progress_id
def _create_progress(self):
return self.env['onboarding.progress'].create([
{
'company_id': self.env.company.id if onboarding.is_per_company else False,
'onboarding_id': onboarding.id,
'progress_step_ids': onboarding.step_ids.progress_ids.filtered(
lambda p: p.company_id.id in [False, self.env.company.id]
),
}
for onboarding in self
])
def _prepare_rendering_values(self):
self.ensure_one()
values = {
'close_method': self.panel_close_action_name,
'close_model': 'onboarding.onboarding',
'steps': self.step_ids,
'state': self.current_progress_id._get_and_update_onboarding_state(),
'text_completed': self.text_completed,
}
return values