Department silos
Combodo's customers only
- name:
- Department silos
- description:
- Ticket segmentation between delivery organizations
- version:
- 1.0.4
- release:
- 2025-10-10
- code:
- combodo-department-silos
- state:
- Stable
- php-version-max:
- PHP 8.3 tested
With this extension, you can ensure that your IT department agents won't be able to see HR related UserRequest and Incidents Tickets and vice versa.
Usecase
Different departments in your company want to use iTop, but each
department wants their agents to be the only one to see the Tickets
related to their business.
Out of the box, iTop does not offer this possibility. This
extension enables this, by changing UserRequest and Incidents
Tickets.
Features
Multiple departments can handle in iTop console, the Tickets which must be managed by their department.
-
Users are not able to see Tickets for other departments than their own.
-
Compatible with Simple Ticket Management and full ITIL.
Revision History
Release | Date Version | Comments |
---|---|---|
2025-10-10 | 1.0.4 | * N°8454 - Conflict between Department
Silos and Global Demand * N°8498 - Migrate UserRequest/Incident OnInsert/OnUpdate into event within Silo * N°6799 - Install even without EN or FR dictionaries |
2023-07-17 | 1.0.3 | N°5807 - API: Remove SetupPage:log* for iTop 3.1 compatibility |
2022-11-18 | 1.0.2 | First published version |
Limitations
-
It's not possible to dispatch a wrongly routed Ticket to another Department, the requestor/caller must create himself another ticket under the right service
-
Callers can only create and see their Tickets through the User Portal.
-
Even agents users must use the User Portal to handle Ticket for themselves (except tickets for their own department)
If you use iTop 2.7.6 or older, there is an known issue with
Notification, which are not triggered unless their
filter
is empty.
Requirements
-
Ticket management must be enabled.
-
The minimum required version for Approval Process Automation, if used, is 2.1.1.
Installation
Before
Otherwise, those Tickets won't be readable after installation!
Organization
/ org_id
Ticket field1) If you have customized UserRequest and Incident presentation, mirror those changes:
-
Search & List: Replace
org_id
bycustomer_id
-
Details: Replace
org_id
bycustomer_id
(Ticket creation in console crashes iforg_id
is displayed in the form)
2) If you have customized UserRequest and Incident methods OnInsert() / OnUpdate(), add this line of code to those functions:
- UserRequest / Incident :: OnInsert() / OnUpdate()
-
$this->Set('org_id', $this->Get('provider_id'));
3) If you have added an org_id
field on
ServiceSubcategory, you should remove it as it will
conflict with the one brought by this extension. It renames the
service_org_id
field into org_id
to make
it treated by iTop as a silo boundary. Thus Service Subcategories
are visible only to users having the service organization in their
Allowed organizations
or having no Allowed
Organizations
.
4) If you have customized the Ticket scopes in portal, make sure the Portal User can still see his own Tickets, and that the Portal Power User can see the Tickets he should.
Install
Use the Standard installation process for this extension.
DataModel changes
-
For class Ticket, it adds a computed
customer_id
field corresponding to the Organization of the Caller.-
French label of
org_id
changed from “Client” to “Organization” as it's no more the client on User request and Incident
-
-
For class UserRequest and Incident, it adds a computed
provider_id
field corresponding to the Organization of the Service. -
For class UserRequest and Incident, it forces the
org_id
Ticket field to be filled with theprovider_id
-
During the Setup/MTP of the first installation of this extension
-
When the Ticket is created and each time it is updated.
-
-
For class Service Subcategory, rename
service_org_id
intoorg_id
→ so the silo applied (otherwise all service subcategories are visible by everyone) -
Change Ticket scopes in User Portal, to allow a simple Portal User with “Allowed organizations” limited to his own organization, to still see his own Tickets.
-
If you install this extension on an already in use iTop with Dashboards, Notifications, QueryPhrases, WebHook, API Rest or Excel reporting on UserRequest or Incident classes, be aware that you may have to rework them as the Ticket.org_id field no more contains the Customer but the Provider for the corresponding service.
UI changes
In the details of UserRequest & Incidents
-
“Organization” label is replaced by “Customer”.
-
“Customer” (
customer_id
) field is not editable. It's always the Organization of the “Caller”. -
A new “Provider” (
provider_id
) field not displayed in details and not editable. It contains the Provider of the Service -
“Organization” (
org_id
) field is not displayed in the details, not editable and automatically fed with the “Provider” value.
In search banner of UserRequest & Incidents
-
“Organization” default search criteria was replaced by “Customer”
-
“Provider” can be used as a Search criteria,
In “Configure this List” for UserRequest & Incidents
-
“Provider” can be displayed,
-
“Organization” contains the same information as “Provider”
Search banner of Ticket
-
“Organization” is proposed by default but it does not correspond to the Customer anymore for User Request and Incident
-
The French label for
org_id
was changed from “Client” to “Organisation” to align to the English naming
Configuration
No configuration parameters
Usage
Setup
The purpose of this extension, is to separate User Request and
Incidents into silos, based on which organization is delivering the
Service.
Out of the box, User Request and Incidents are siloed by
customer.
To work as expected you must organize your data in a certain way:
-
Create separate organizations for each independent provider managing Tickets
-
Create separate organizations for each customer which must be visible to all providers agents
-
Decide under which organization you must put each object, so it is hidden/visible to the appropriate users
-
Give access to each user to the Organizations that they need to see and not more (User tab
Allowed Organizations
)
Below 2 examples which are pretty common:
Single company
Goal: Ensure that the IT department agents won't be able to see HR related UserRequest and Incidents Tickets and vice versa.
In order to use this extension, you must modify the organizations and the owner organization of some objects.
-
Create a company organization and put all shared company objects under that organization:
-
Locations
-
Teams & Persons
-
Contracts
-
Public/shared CIs
-
-
Create the different Departments as separated iTop Organizations,
-
but leave their
Parent
empty, Putting them under the main company would break the Silos, as iTop logic is to enable access to all sub-organizations of the UserAllowed organizations
, and that behavior can not be changed. -
Defines catalog of Services within each of those organizations
-
Defines private CIs under the Department in charge of handling them in a silo. Such CIs cannot be seen in the console by people outside of the Department.
-
-
Create one or multiple contracts under the main company to buy the services provided by the various departments
-
Assuming you have IT and HR agents, ensure that they all have
Allowed organizations
set on their iTop user. They must be allowed on their contact organization (this is an iTop portal requirement) and on their department organization, as well as on all their customers organizations.
-
As a result, all employee must use the User Portal to request services to other departments than their own, but once in the console, they are limited to the Tickets which are linked to a Service that they are responsible for.
Service Provider
Goal: Have different providers delivering services to different customers, but seeing in the console, only the Tickets related to the services that they deliver.
For example, a company with multiple departments providing different services to other companies and each Department must only see the Tickets they are responsible for:
Check the steps described above for a “Single company” and adapt it
-
There is a Provider Company with 3 Departments needing to work in Silos
-
None of the Department will have the “Provider Company” as its parent (same reason as described above in “Single company” model)
-
Theirs customers can be the same or different
-
The customers Tickets must only be seen by the Department handling them
-
Here we have imagined that the “Loan Department” does not deliver any services to “Client #2”, which explains why its Users do not need to see “Client #2” organization
Each Department users, must have theirs customers in their “Allowed Organizations”, which can be an administrative burden, if there are a lot of agents and/or a lot of customers on-boarding. But if all customers can be visible to all company departments employee, then it's easier: Define a generic “My-Customers” organization as parent of every true customers organization and just put the “My-Customers” organization in the “allowed organizations” of all your departments employees and job done.
Change of behavior
There is no visual change to the User Portal, but scopes to let callers see their own tickets, as they are no more under the user organization. Ticket's organizations are not guaranteed to be in the user “Allowed organizations” anymore.
In the Console for User Request and Incident, the Customer can no more be selected, it is computed from the Caller.
Questions & Answers
Silos on Contracts
Q: I want to avoid that an IT department person can
modify customer contract where the provider is the HR
department.
A: This is possible but requires a bit more
customization:
1) Add a customer_id
ExternalKey on class
Contract,
2) Replace org_id by customer_id everywhere in the presentation of
the CustomerContract and ProviderContract classes
3) Write some OnInsert and OnUpdate methods to copy in the
org_id
either the customer_id
or the
provider_id
for ProviderContract and CustomerContract
respectively.
4) Add some dictionary entries so org_id
is the
“Contract Owner” and customer_id
is the
“Customer”
5) After Setup / MTP run 2 SQL queries on contract table (either within the extension or manually)
-
the first one to initialize
customer_id
with theorg_id
on All Contracts
UPDATE `contract` SET `contract`.`customer_id` = `contract`.`org_id` WHERE `contract`.`customer_id` = 0
-
the second to change the “Contract owner” to be the “Provider” only for CustomerContract
UPDATE `contract` SET `contract`.`org_id` = `contract`.`provider_id` WHERE `contract`.`finalclass` = 'CustomerContract'
Department on Person
Q: I want to know the department of each Person, but if
I move the Person under his “HR Department”, IT users won't see
him. How can I do?
A: Add a department_id
ExternalKey to
the Organization class, to specify the optional sub-organization of
the user
Q: I want to be sure I set the correct Allowed
Organizations to each User. How can I do?
A: The best would be to add a method on User to
automatically add the department_id
and the
org_id
to the allowed organizations
of
the User, if it was possible 😦
The problem is that it is not possible to plug a method on User class for now…
-
That would avoid that a user is created without “allowed organizations” by mistake or without access to the Department they are working for
-
Adding “Allowed organizations” on Users with profile “Administrator” has no effect, as iTop ignores them, so it could be done for every users without side effect.
SLA and SLT
Q: Does it impacts my SLAs calculation?
A: Yes, for this you must modify one thing in 2
places.
:this->org_id must be replaced by :this->customer_id in:
-
The constant
RESPONSE_TICKET_SLT_QUERY
in the Designer:
- RESPONSE_TICKET_SLT_QUERY
-
SELECT SLT AS slt JOIN lnkSLAToSLT AS l1 ON l1.slt_id=slt.id JOIN SLA AS sla ON l1.sla_id=sla.id JOIN lnkCustomerContractToService AS l2 ON l2.sla_id=sla.id JOIN CustomerContract AS sc ON l2.customercontract_id=sc.id WHERE slt.metric = :metric AND l2.service_id = :this->service_id /* We get the SLT applicable for the customer defined in the Ticket (:this->customer_id) */ AND sc.org_id = :this->customer_id AND slt.request_type = :request_type AND slt.priority = :this->priority
-
The coverage OQL in iTop Configuration file:
'combodo-sla-computation' => array ( 'coverage_oql' => 'SELECT CoverageWindow AS cw JOIN lnkCustomerContractToService AS l1 ON l1.coveragewindow_id = cw.id JOIN CustomerContract AS cc ON l1.customercontract_id = cc.id WHERE cc.org_id_id= :this->customer_id AND l1.service_id = :this->service_id', 'holidays_oql' => 'SELECT Holiday', ),