File: onboarding_onboarding.py

package info (click to toggle)
odoo 18.0.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 878,716 kB
  • sloc: javascript: 927,937; python: 685,670; xml: 388,524; sh: 1,033; sql: 415; makefile: 26
file content (134 lines) | stat: -rw-r--r-- 6,203 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# -*- 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=lambda s: s.env._('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