Environment
- GLPI: 10.0.20
- Behaviors: 2.7.8
- Feature involved: Single technician/group assignment
- GLPI feature involved: Ticket business rules assigning SLA according to the assigned group
Description
We identified an interaction between the Behaviors automatic single-group replacement and GLPI ticket business rules.
In our environment, GLPI business rules assign an SLA according to the technician group assigned to the ticket.
Example:
- Group A → SLA A
- Group B → SLA B
A ticket is initially assigned to Group A and GLPI correctly applies SLA A.
Later, the ticket must be reassigned to Group B.
The issue only occurs when Group A is left assigned and Group B is added, relying on Behaviors to automatically remove the previous group.
After the first save, Behaviors correctly leaves only Group B assigned, but the ticket still keeps SLA A.
A second save, without any additional assignment change, causes GLPI to correctly apply SLA B.
Important additional test
We also tested manually removing Group A before saving.
When the user explicitly removes Group A and leaves only Group B before saving, GLPI correctly applies SLA B on the first save.
This happens in both situations:
- Behaviors enabled
- Behaviors disabled
Therefore, the problem does not seem to be caused simply by Behaviors being enabled.
The relevant difference appears to be the assignment state that GLPI sees when the business rules are evaluated.
When GLPI receives only Group B as the resulting assignment, the business rule works correctly.
The problem occurs specifically when Group A is still present during the update and Behaviors removes it automatically later in the processing.
Steps to reproduce
-
Configure Behaviors to use the single technician/group functionality.
-
Create two technician groups:
-
Configure GLPI ticket business rules:
- Group A → assign SLA A
- Group B → assign SLA B
-
Create or update a ticket so that only Group A is assigned.
-
Confirm that SLA A is correctly applied.
-
Edit the ticket.
-
Add Group B without manually removing Group A.
-
Save the ticket.
Actual result
After the save, Behaviors automatically removes Group A.
The final ticket state is:
Assigned group: Group B
SLA: SLA A
If the same ticket is saved again without changing the assignment, the result becomes:
Assigned group: Group B
SLA: SLA B
Expected result
After the first save, the final ticket state should already be:
Assigned group: Group B
SLA: SLA B
The business rule should evaluate the assignment state that will effectively remain on the ticket after the single-group behavior is applied.
Comparison test
Scenario 1 — Automatic removal by Behaviors
Initial state:
User adds Group B and does not manually remove Group A.
After save:
The issue occurs.
Scenario 2 — Manual removal of the previous group, Behaviors enabled
Initial state:
Before saving, the user manually removes Group A and leaves only Group B.
After save:
The business rule works correctly.
Scenario 3 — Manual removal of the previous group, Behaviors disabled
The same manual reassignment is performed with Behaviors disabled.
After save:
The business rule also works correctly.
Scenario 4 — Second save after automatic replacement
After Scenario 1, the ticket is already stored with only Group B assigned.
Saving the ticket again causes GLPI to apply:
No additional group change is required.
Source code investigation
We compared the source code from the affected environment with the official sources.
GLPI
The relevant files from the customer environment were compared with the official GLPI 10.0.20 source code, including:
src/Ticket.php
src/CommonITILObject.php
src/CommonITILActor.php
src/CommonDBTM.php
src/RuleTicket.php
src/RuleCriteria.php
src/RuleCollection.php
The relevant files match the official GLPI 10.0.20 sources.
No local core modification was identified that could explain this behavior.
Behaviors
The relevant Behaviors files were also compared with the official Behaviors 2.7.8 source:
setup.php
inc/ticket.class.php
inc/group_ticket.class.php
These files also match the official Behaviors 2.7.8 implementation.
No local modification was identified in the plugin processing involved in this issue.
Technical investigation
Based on the source code flow and the tests above, our current hypothesis is related to processing order.
GLPI prepares the ticket update and evaluates ticket business rules before all actor changes have reached their final persisted state.
Behaviors enforces the single-group configuration in:
PluginBehaviorsGroup_Ticket::afterAdd()
After the new Group_Ticket is created, Behaviors queries the currently assigned groups and removes the previous ones.
Conceptually, the sequence appears to be:
Ticket initially has Group A
↓
User submits Group A + Group B
↓
GLPI prepares ticket update
↓
GLPI evaluates ticket business rules
↓
Group B is added
↓
Behaviors Group_Ticket::afterAdd()
↓
Behaviors removes Group A
↓
Final persisted assignment = Group B
The important observation is that when Group A is explicitly removed before saving, GLPI correctly applies the Group B SLA.
This suggests that the SLA rule itself is working correctly.
The inconsistency appears only when the final single-group state is produced later by Behaviors.
Our current hypothesis is therefore:
The ticket business rules may be evaluated while the previous group is still part of the assignment context, while Behaviors removes that group afterward. The final assignment is correct, but the SLA may already have been calculated using the earlier assignment context.
This also explains why a second save fixes the SLA: at that point the ticket already starts the update with only Group B assigned.
Why we believe this is related to the automatic replacement timing
The following results are consistent:
Manual A → B, Behaviors enabled
Result: Group B / SLA B
Manual A → B, Behaviors disabled
Result: Group B / SLA B
Add B while A remains, Behaviors removes A automatically
Result: Group B / SLA A
Save again
Result: Group B / SLA B
Because the first two scenarios work correctly regardless of whether Behaviors is enabled, this does not appear to be a general SLA or business-rule failure.
The issue appears specifically related to the timing of the automatic old-group removal.
Question / possible direction
We are not proposing a specific code change yet because moving group-removal logic earlier in the ticket lifecycle may affect other assignment workflows.
However, it may be useful to evaluate whether the single-group behavior could expose the intended final assignment before GLPI evaluates ticket business rules, rather than enforcing the replacement only after the new Group_Ticket has already been added.
The objective would be to allow GLPI's native rule engine to evaluate the same group assignment that will ultimately remain on the ticket.
We can provide additional logs, rule configuration screenshots, ticket history, or further tests if useful.
Environment
Description
We identified an interaction between the Behaviors automatic single-group replacement and GLPI ticket business rules.
In our environment, GLPI business rules assign an SLA according to the technician group assigned to the ticket.
Example:
A ticket is initially assigned to Group A and GLPI correctly applies SLA A.
Later, the ticket must be reassigned to Group B.
The issue only occurs when Group A is left assigned and Group B is added, relying on Behaviors to automatically remove the previous group.
After the first save, Behaviors correctly leaves only Group B assigned, but the ticket still keeps SLA A.
A second save, without any additional assignment change, causes GLPI to correctly apply SLA B.
Important additional test
We also tested manually removing Group A before saving.
When the user explicitly removes Group A and leaves only Group B before saving, GLPI correctly applies SLA B on the first save.
This happens in both situations:
Therefore, the problem does not seem to be caused simply by Behaviors being enabled.
The relevant difference appears to be the assignment state that GLPI sees when the business rules are evaluated.
When GLPI receives only Group B as the resulting assignment, the business rule works correctly.
The problem occurs specifically when Group A is still present during the update and Behaviors removes it automatically later in the processing.
Steps to reproduce
Configure Behaviors to use the single technician/group functionality.
Create two technician groups:
Configure GLPI ticket business rules:
Create or update a ticket so that only Group A is assigned.
Confirm that SLA A is correctly applied.
Edit the ticket.
Add Group B without manually removing Group A.
Save the ticket.
Actual result
After the save, Behaviors automatically removes Group A.
The final ticket state is:
If the same ticket is saved again without changing the assignment, the result becomes:
Expected result
After the first save, the final ticket state should already be:
The business rule should evaluate the assignment state that will effectively remain on the ticket after the single-group behavior is applied.
Comparison test
Scenario 1 — Automatic removal by Behaviors
Initial state:
User adds Group B and does not manually remove Group A.
After save:
The issue occurs.
Scenario 2 — Manual removal of the previous group, Behaviors enabled
Initial state:
Before saving, the user manually removes Group A and leaves only Group B.
After save:
The business rule works correctly.
Scenario 3 — Manual removal of the previous group, Behaviors disabled
The same manual reassignment is performed with Behaviors disabled.
After save:
The business rule also works correctly.
Scenario 4 — Second save after automatic replacement
After Scenario 1, the ticket is already stored with only Group B assigned.
Saving the ticket again causes GLPI to apply:
No additional group change is required.
Source code investigation
We compared the source code from the affected environment with the official sources.
GLPI
The relevant files from the customer environment were compared with the official GLPI 10.0.20 source code, including:
src/Ticket.phpsrc/CommonITILObject.phpsrc/CommonITILActor.phpsrc/CommonDBTM.phpsrc/RuleTicket.phpsrc/RuleCriteria.phpsrc/RuleCollection.phpThe relevant files match the official GLPI 10.0.20 sources.
No local core modification was identified that could explain this behavior.
Behaviors
The relevant Behaviors files were also compared with the official Behaviors 2.7.8 source:
setup.phpinc/ticket.class.phpinc/group_ticket.class.phpThese files also match the official Behaviors 2.7.8 implementation.
No local modification was identified in the plugin processing involved in this issue.
Technical investigation
Based on the source code flow and the tests above, our current hypothesis is related to processing order.
GLPI prepares the ticket update and evaluates ticket business rules before all actor changes have reached their final persisted state.
Behaviors enforces the single-group configuration in:
PluginBehaviorsGroup_Ticket::afterAdd()After the new
Group_Ticketis created, Behaviors queries the currently assigned groups and removes the previous ones.Conceptually, the sequence appears to be:
The important observation is that when Group A is explicitly removed before saving, GLPI correctly applies the Group B SLA.
This suggests that the SLA rule itself is working correctly.
The inconsistency appears only when the final single-group state is produced later by Behaviors.
Our current hypothesis is therefore:
This also explains why a second save fixes the SLA: at that point the ticket already starts the update with only Group B assigned.
Why we believe this is related to the automatic replacement timing
The following results are consistent:
Because the first two scenarios work correctly regardless of whether Behaviors is enabled, this does not appear to be a general SLA or business-rule failure.
The issue appears specifically related to the timing of the automatic old-group removal.
Question / possible direction
We are not proposing a specific code change yet because moving group-removal logic earlier in the ticket lifecycle may affect other assignment workflows.
However, it may be useful to evaluate whether the single-group behavior could expose the intended final assignment before GLPI evaluates ticket business rules, rather than enforcing the replacement only after the new
Group_Tickethas already been added.The objective would be to allow GLPI's native rule engine to evaluate the same group assignment that will ultimately remain on the ticket.
We can provide additional logs, rule configuration screenshots, ticket history, or further tests if useful.