Export/Import Overviews using the rails console

Infos:

  • Used Zammad version: 6.2.0-1709709730.4ab26fc3.jammy
  • Used Zammad installation type: package
  • Operating system: Ubuntu 22.04
  • Browser + version: 124.0.1 (64-bit)

Expected behavior:

  • Export Overviews consistently

Actual behavior:

  • It is possible export Overviews using the rails console
# Export Overviews to JSON file
roles = Overview.all
File.open('/tmp/overview.json', 'w') do |file|
  file.write(overview.to_json)
end

But the Available for the following roles * and Restrict to only the following users are missing in the JSON, which makes it hard(er) to add 430 roles to the overviews as it is necessary to click every single role instead of export/copy/paste/import

[
    {"id":11,"name":"My Assigned Tickets","link":"my_assigned","prio":1,"condition":{"ticket.state_id":{"operator":"is","value":["1","4","8","7","6"]},"ticket.owner_id":{"operator":"is","pre_condition":"current_user.id","value":[],"value_completion":""},"ticket.organization_id":{"operator":"is","pre_condition":"current_user.organization_id","value":[],"value_completion":""}},"order":{"by":"created_at","direction":"ASC"},"group_by":"organization","group_direction":"ASC","organization_shared":false,"out_of_office":false,"view":{"s":["title","customer","group","created_at"]},"active":true,"updated_by_id":85,"created_by_id":1,"created_at":"2024-03-18T08:38:02.820Z","updated_at":"2024-04-04T07:13:26.422Z"},
    {"id":12,"name":"đź“ĄUnassigned \u0026 Open Tickets","link":"all_unassigned","prio":2,"condition":{"ticket.state_id":{"operator":"is","value":["1","4","6"]},"ticket.owner_id":{"operator":"is","pre_condition":"not_set","value":[],"value_completion":""}},"order":{"by":"created_at","direction":"ASC"},"group_by":"","group_direction":"ASC","organization_shared":false,"out_of_office":false,"view":{"s":["title","customer","group","created_at"]},"active":true,"updated_by_id":85,"created_by_id":1,"created_at":"2024-03-18T08:38:02.877Z","updated_at":"2024-04-04T07:13:26.778Z"},
    {"id":13,"name":"My Pending Reached Tickets","link":"my_pending_reached","prio":3,"condition":{"ticket.state_id":{"operator":"is","value":[6]},"ticket.owner_id":{"operator":"is","pre_condition":"current_user.id"},"ticket.pending_time":{"operator":"before (relative)","value":0,"range":"minute"}},"order":{"by":"created_at","direction":"ASC"},"group_by":null,"group_direction":null,"organization_shared":false,"out_of_office":false,"view":{"d":["title","customer","group","created_at"],"s":["title","customer","group","created_at"],"m":["number","title","customer","group","created_at"],"view_mode_default":"s"},"active":true,"updated_by_id":85,"created_by_id":1,"created_at":"2024-03-18T08:38:02.898Z","updated_at":"2024-04-04T07:13:26.804Z"},
    {"id":14,"name":"My Subscribed Tickets","link":"my_subscribed_tickets","prio":4,"condition":{"ticket.mention_user_ids":{"operator":"is","pre_condition":"current_user.id","value":"","value_completion":""}},"order":{"by":"created_at","direction":"ASC"},"group_by":null,"group_direction":null,"organization_shared":false,"out_of_office":false,"view":{"d":["title","customer","group","created_at"],"s":["title","customer","group","created_at"],"m":["number","title","customer","group","created_at"],"view_mode_default":"s"},"active":true,"updated_by_id":85,"created_by_id":1,"created_at":"2024-03-18T08:38:02.915Z","updated_at":"2024-04-04T07:13:26.833Z"},
    {"id":15,"name":"Open Tickets","link":"all_open","prio":5,"condition":{"ticket.state_id":{"operator":"is","value":[1,6,4]}},"order":{"by":"created_at","direction":"ASC"},"group_by":null,"group_direction":null,"organization_shared":false,"out_of_office":false,"view":{"d":["title","customer","group","state","owner","created_at"],"s":["title","customer","group","state","owner","created_at"],"m":["number","title","customer","group","state","owner","created_at"],"view_mode_default":"s"},"active":true,"updated_by_id":85,"created_by_id":1,"created_at":"2024-03-18T08:38:02.934Z","updated_at":"2024-04-04T07:13:26.865Z"},
    {"id":16,"name":"Pending Reached Tickets","link":"all_pending_reached","prio":6,"condition":{"ticket.state_id":{"operator":"is","value":[6]},"ticket.pending_time":{"operator":"before (relative)","value":0,"range":"minute"}},"order":{"by":"created_at","direction":"ASC"},"group_by":null,"group_direction":null,"organization_shared":false,"out_of_office":false,"view":{"d":["title","customer","group","owner","created_at"],"s":["title","customer","group","owner","created_at"],"m":["number","title","customer","group","owner","created_at"],"view_mode_default":"s"},"active":true,"updated_by_id":85,"created_by_id":1,"created_at":"2024-03-18T08:38:02.954Z","updated_at":"2024-04-04T07:13:26.897Z"},
    {"id":17,"name":"Escalated Tickets","link":"all_escalated","prio":7,"condition":{"ticket.escalation_at":{"operator":"till (relative)","value":"10","range":"minute"}},"order":{"by":"escalation_at","direction":"ASC"},"group_by":null,"group_direction":null,"organization_shared":false,"out_of_office":false,"view":{"d":["title","customer","group","owner","escalation_at"],"s":["title","customer","group","owner","escalation_at"],"m":["number","title","customer","group","owner","escalation_at"],"view_mode_default":"s"},"active":true,"updated_by_id":85,"created_by_id":1,"created_at":"2024-03-18T08:38:02.971Z","updated_at":"2024-04-04T07:13:26.914Z"},
    {"id":18,"name":"My Replacement Tickets","link":"my_replacement_tickets","prio":9,"condition":{"ticket.state_id":{"operator":"is","value":[1,6,7,8,4]},"ticket.out_of_office_replacement_id":{"operator":"is","pre_condition":"current_user.id"}},"order":{"by":"created_at","direction":"DESC"},"group_by":null,"group_direction":null,"organization_shared":false,"out_of_office":true,"view":{"d":["title","customer","group","owner","escalation_at"],"s":["title","customer","group","owner","escalation_at"],"m":["number","title","customer","group","owner","escalation_at"],"view_mode_default":"s"},"active":true,"updated_by_id":85,"created_by_id":1,"created_at":"2024-03-18T08:38:02.990Z","updated_at":"2024-04-04T07:13:26.989Z"},
    {"id":19,"name":"My Tickets","link":"my_tickets","prio":10,"condition":{"ticket.state_id":{"operator":"is","value":[1,3,5,6,7,8,4,2]},"ticket.customer_id":{"operator":"is","pre_condition":"current_user.id"}},"order":{"by":"created_at","direction":"DESC"},"group_by":null,"group_direction":null,"organization_shared":false,"out_of_office":false,"view":{"d":["title","customer","state","created_at"],"s":["number","title","state","created_at"],"m":["number","title","state","created_at"],"view_mode_default":"s"},"active":true,"updated_by_id":85,"created_by_id":1,"created_at":"2024-03-18T08:38:03.012Z","updated_at":"2024-04-04T07:13:27.020Z"},
    {"id":20,"name":"My Organization Tickets","link":"my_organization_tickets","prio":11,"condition":{"ticket.state_id":{"operator":"is","value":[1,3,5,6,7,8,4,2]},"ticket.organization_id":{"operator":"is","pre_condition":"current_user.organization_id"}},"order":{"by":"created_at","direction":"DESC"},"group_by":null,"group_direction":null,"organization_shared":true,"out_of_office":false,"view":{"d":["title","customer","organization","state","created_at"],"s":["number","title","customer","organization","state","created_at"],"m":["number","title","customer","organization","state","created_at"],"view_mode_default":"s"},"active":true,"updated_by_id":85,"created_by_id":1,"created_at":"2024-03-18T08:38:03.032Z","updated_at":"2024-04-04T07:13:27.056Z"},
    {"id":21,"name":"đź“źMonitoring","link":"monitoring","prio":8,"condition":{"ticket.group_id":{"operator":"is","value":["283"],"value_completion":""},"ticket.organization_id":{"operator":"is","pre_condition":"current_user.organization_id","value":[],"value_completion":""}},"order":{"by":"created_at","direction":"ASC"},"group_by":"organization","group_direction":"ASC","organization_shared":false,"out_of_office":false,"view":{"s":["title","customer","group","created_at"]},"active":true,"updated_by_id":85,"created_by_id":85,"created_at":"2024-04-04T07:12:22.484Z","updated_at":"2024-04-04T07:36:31.306Z"}
]

Steps to reproduce the behavior:

  • Export using rails console

If anyone could point me towards where the link between Roles and Overview is, I will look into how to export/import that consistently

It is e.g. available for roles with RoleGroup.all but I could not find it for the overview so far.

Thanks

Why don’t you just have a basic agent role that every agent has with the basic user preferences as well. This overview can be used to provide the overviews needed (as it doesn’t seem like you have differences there).

Think about maintainability. 430 roles with lets say 15 overviews are not.

Hi!

Thanks for the questions.

The issue is pretty interesting.

There is a public organization with 450 sites.
Single sites have a group and two or more sites can be part of a district and have a common group.
Every site is treated independently as it’s own entity and agents are responsible for around 12 sites each and there is a backup agent which is not always the same for the 12 sites. Which means around 24 mixed sites per agent.

There is a group for every site or district.
There is an organization for every single site.
There is the requirement that every organization only sees their group
To do so, there are 450 agent roles, every role has full control on either a site group or a district group.
This ensure that the web notification (the one with the bird) for new tickets is only received by agents that have the role for the dedicated group.
This way, if the agent changes sites, the assigned roles are changed and the permissions permeate through all the system.
The Customer in this case is assigned a single group using core workflows which is their site or district group. I was able to export/import workflows successfully, which is nice.
A following challenge is that within a district (collection of sites) different agents might be responsible for different sites part of the district, therefore 1 site = 1 group, 1 group access = 1 role in conclusion 450 sites = 450 roles.

The manageability is given by the fact that no manual management is done in Zammad and everything is managed through API calls (or rails console) with JSON or CSV files.

Update a user? Change the CSV file and upload/update user data
Update permissions? Change the CSV file and upload/update roles
and so on

This makes it also possible to track changes (the files are on GIT) and to replicate in case of a disaster (backup gone, all dead? set up systems with ansible, reimport all files from git, done. old tickets are gone, but settings, permissions, groups, users, etc… are all available again)

I would love to simplify the agent thing, but the web notification in Zammad itself is an issue because it is not configurable who receives the notification based on what. A “is part of organization” would solve that, since in that case I could use organization as filter for overviews and workflows as I am doing already for groups assignments.

Best,
Skip