[17.0] [ADD] helpdesk_mgmt_team_customer#878
Conversation
61f0302 to
06b8fdf
Compare
|
@DantePereyra @ChristianSantamaria Could you review? Thanks! |
DantePereyra
left a comment
There was a problem hiding this comment.
Tested on runboat, problems found:
- When ticket had team and contact assigned, and that team add or changes
default_partner, it gives an OWL error. - With
default_partneron team, team and contact assigned on ticket, saved, and then change partner (with allowed partners or not) gives an strange error.
Also, I can't check if test are working.
| def _compute_partner_id_domain(self): | ||
| for record in self: | ||
| if record.team_id: | ||
| if record.team_id.default_partner_id: |
There was a problem hiding this comment.
| if record.team_id.default_partner_id: | |
| if record.team_id.default_partner_id and not record.partner_id: |
With this you can only select the default partner, and will give an error when saving. Try this.
There was a problem hiding this comment.
why dont't you use the field: commercial_partner_id?
When a contact from a company open a ticket, do you what to apply the restriction on the contact or on the company?
There was a problem hiding this comment.
The purpose of this feature is not to restrict which user/contact can open a ticket, but to restrict which partner can be assigned to the ticket depending on the helpdesk team.
In our use case, an internal user creates a ticket (or assigns an existing one) and then sets the team_id. Once the team is chosen:
the partner_id is auto-filled with the team’s default_partner_id, and the partner_id field is restricted to a specific list of contacts configured on the team (default_partner_id and allowed_partner_ids).
This behaviour is independent from the contact/company of the user who opens the ticket (portal or internal). We are configuring which partners are allowed for a given team, not which company the ticket creator belongs to.
For this reason I’m using partner_id directly instead of commercial_partner_id. In our scenario, a team can be dedicated to specific contacts, even within the same company.
| @api.constrains("team_id", "partner_id") | ||
| def _check_partner_allowed_by_team(self): | ||
| for record in self: | ||
| if not record.team_id or not record.partner_id: | ||
| continue | ||
| if ( | ||
| record.team_id.is_unique_partner | ||
| and record.partner_id != record.team_id.default_partner_id | ||
| ): | ||
| raise ValidationError( | ||
| _("This partner is not allowed for selected team") | ||
| ) | ||
| elif ( | ||
| record.team_id.allowed_partner_ids | ||
| and record.partner_id not in record.team_id.allowed_partner_ids | ||
| and record.partner_id != record.team_id.default_partner_id | ||
| ): | ||
| raise ValidationError( | ||
| _("This partner is not allowed for selected team") | ||
| ) |
There was a problem hiding this comment.
I think this is unnecessary since you will not be capable of select different partners with above restrictions, but maybe I'm wrong.
There was a problem hiding this comment.
It’s necessary because tickets allow the creation of a partner 'on the fly'. I didn’t want to restrict that functionality, but I did want to block the possibility of assigning this new partner to the ticket, since it’s neither included in the 'allowed_partner_ids' group nor set as the 'default_partner_id'.
06b8fdf to
c5b8583
Compare
DantePereyra
left a comment
There was a problem hiding this comment.
Not a request, just a suggestion :)
| for record in self: | ||
| if not record.default_partner_id: | ||
| record.is_unique_partner = False |
There was a problem hiding this comment.
| for record in self: | |
| if not record.default_partner_id: | |
| record.is_unique_partner = False | |
| for record in self.filtered(lambda r: not r.default_partner_id): | |
| record.is_unique_partner = False |
Could you try this to see if it works right?
c5b8583 to
8e0ba62
Compare
DantePereyra
left a comment
There was a problem hiding this comment.
Tested! 👍 Code seems fine to me.
8e0ba62 to
8c374b4
Compare
Design Review: Functional Rationale and Architectural AlignmentHi authors, Thanks for submitting this PR. I've reviewed the code for However, as a fellow contributor, I have a few questions about the module's positioning and architectural choices, which would be essential to clarify in the README to ensure strong community alignment and future maintainability. 1. Use Case & Business Justification (The "Why")Could you please elaborate on the specific business process this module is targeting? We typically see constraints defined around the Customer (e.g., "This Customer can only raise tickets in Team A"). This module imposes the constraint in the reverse direction (Team A Is this designed primarily for highly segmented scenarios like Managed Service Providers (MSPs) or internal support teams where agents often switch roles but must be strictly prevented from associating tickets with out-of-scope contracts? Providing this context will solidify the module's legitimate place in the 2. Functional Philosophy (The "What": Restriction Ambiguity)The module implements a hybrid control mechanism:
This suggests that even if an agent bypasses the UI domain, the server will enforce the rule. Is this hard restriction a non-negotiable requirement of the use case? Sometimes, functional flexibility is key (e.g., allowing an exception for an emergency ticket). If the rule is for data hygiene/guidance only, the constraint is unnecessary; if it's for data integrity/security, it's essential, but the rationale should be clear. 3. Architectural Design Choice (The "How": Record Rules vs. Constraints)This is my main point regarding principle alignment (KISS, Separation of Concerns). You chose to implement the restriction as a transactional constraint on the I suggest considering the approach used in modules like
Was the Record Rule pattern considered? If so, why was it discarded in favor of custom constraints? The answer is critical:
Next Steps (my suggestion)To move this PR forward, please add a section to the README.rst addressing these three points. Clarifying the Why and the choice of the Constraint Pattern will help prevent other reviewers from raising the same questions and solidify the module's position in the OCA. Thanks again for the great work! |
Partner Restrictions by Helpdesk Team Allows dynamic control over which contact (partner_id) on ticket, based on the configuration of the assigned Helpdesk Team (team_id). The logic works as follows: - If the team has a default contact, it will fill the contact field with that value. - If the team has a unique contact, only that contact will be available. - If the team has a list of allowed contacts, only those contacts will be available. - If the team has no restrictions, all contacts will be available.
8c374b4 to
42f2fd1
Compare
|
Hi @rrebollo! Thanks for the review and for the detailed feedback. I’ve added a dedicated Use Case section to the README to clarify the functional rationale and intended positioning of the module. In short, this addon targets setups where Helpdesk Teams are organized per customer, rather than per functional support area. Each team represents a customer-dedicated working context, and the Helpdesk dashboard is used to track workload per customer (e.g. “Customer X – 4 open tickets”). In this scenario, every ticket created for a given team is implicitly related to a specific customer. The module aims to:
This also explains why the restriction is intentionally applied from Team → Customer, as this direction is required for the intended use case. Regarding the hard restriction: the Python constraint is intentional and required for data integrity. The dynamic domain provides UI-level guidance, but it can be bypassed in several standard Odoo ways (on-the-fly partner creation, imports, automated actions, etc.). A common example is creating a new customer directly from the ticket form: this is allowed, but assigning it to a team with a restricted customer list must be blocked to preserve consistency. For this reason, the constraint is not optional in this use case. Regarding the Record Rule approach: this module does not aim to restrict global access to partners. Partner availability is intentionally contextual and depends on the Helpdesk Team selected on each ticket. Record Rules operate at user or group level and are static by nature, while this use case requires per-record, per-team dynamic behavior. The same agent may legitimately work on tickets for different customers within the same session simply by switching teams. As a result, a record rule would either be too restrictive or require complex, non-standard workarounds (such as groups per customer or dynamic contexts). The domain + constraint pattern was therefore chosen to keep partner access contextual to the ticket, rather than global. Please let me know if further clarification would be helpful. |
|
This PR has the |
Partner Restrictions by Helpdesk Team
Allows dynamic control over which contact (partner_id) on ticket, based on the configuration of the assigned Helpdesk Team (team_id). The logic works as follows: