TrinityCore
Loading...
Searching...
No Matches
cs_ticket.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/* ScriptData
19Name: ticket_commandscript
20%Complete: 100
21Comment: All ticket related commands
22Category: commandscripts
23EndScriptData */
24
25#include "ScriptMgr.h"
26#include "AccountMgr.h"
27#include "CharacterCache.h"
28#include "Chat.h"
29#include "ChatCommand.h"
30#include "Language.h"
31#include "ObjectMgr.h"
32#include "Player.h"
33#include "RealmList.h"
34#include "SupportMgr.h"
35#include "World.h"
36#include "WorldSession.h"
37
38#if TRINITY_COMPILER == TRINITY_COMPILER_GNU
39#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
40#endif
41
42using namespace Trinity::ChatCommands;
43
45{
46public:
47 ticket_commandscript() : CommandScript("ticket_commandscript") { }
48
49 template<typename T>
50 static bool HandleTicketAssignToCommand(ChatHandler* handler, char const* args);
51
52 template<typename T>
53 static bool HandleTicketCloseByIdCommand(ChatHandler* handler, char const* args);
54
55 template<typename T>
56 static bool HandleTicketCommentCommand(ChatHandler* handler, char const* args);
57
58 template<typename T>
59 static bool HandleTicketDeleteByIdCommand(ChatHandler* handler, char const* args);
60
61 template<typename T>
62 static bool HandleTicketListCommand(ChatHandler* handler, char const* /*args*/);
63
64 template<typename T>
65 static bool HandleTicketListClosedCommand(ChatHandler* handler, char const* /*args*/);
66
67 template<typename T>
68 static bool HandleTicketResetCommand(ChatHandler* handler, char const* /*args*/);
69
70 template<typename T>
71 static bool HandleTicketUnAssignCommand(ChatHandler* handler, char const* args);
72
73 template<typename T>
74 static bool HandleTicketGetByIdCommand(ChatHandler* handler, char const* args);
75
76 static bool HandleTicketResetAllCommand(ChatHandler* handler, char const* /*args*/)
77 {
78 if (sSupportMgr->GetOpenTicketCount<BugTicket>() || sSupportMgr->GetOpenTicketCount<ComplaintTicket>() || sSupportMgr->GetOpenTicketCount<SuggestionTicket>())
79 {
81 return true;
82 }
83 else
84 {
85 sSupportMgr->ResetTickets<BugTicket>();
86 sSupportMgr->ResetTickets<ComplaintTicket>();
87 sSupportMgr->ResetTickets<SuggestionTicket>();
89 }
90 return true;
91 }
92
93 static bool HandleToggleGMTicketSystem(ChatHandler* handler, char const* /*args*/)
94 {
95 if (!sWorld->getBoolConfig(CONFIG_SUPPORT_TICKETS_ENABLED))
96 {
98 return true;
99 }
100
101 bool status = !sSupportMgr->GetSupportSystemStatus();
102 sSupportMgr->SetSupportSystemStatus(status);
104 return true;
105 }
106
107 std::span<ChatCommandBuilder const> GetCommands() const override;
108};
109
110template<typename T>
112{
113 if (!*args)
114 return false;
115
116 char* ticketIdStr = strtok((char*)args, " ");
117 uint32 ticketId = atoi(ticketIdStr);
118
119 char* targetStr = strtok(nullptr, " ");
120 if (!targetStr)
121 return false;
122
123 std::string target(targetStr);
124 if (!normalizePlayerName(target))
125 return false;
126
127 T* ticket = sSupportMgr->GetTicket<T>(ticketId);
128 if (!ticket || ticket->IsClosed())
129 {
131 return true;
132 }
133
134 ObjectGuid targetGuid = sCharacterCache->GetCharacterGuidByName(target);
135 uint32 accountId = sCharacterCache->GetCharacterAccountIdByGuid(targetGuid);
136 // Target must exist and have administrative rights
137 if (!AccountMgr::HasPermission(accountId, rbac::RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET, sRealmList->GetCurrentRealmId().Realm))
138 {
140 return true;
141 }
142
143 // If already assigned, leave
144 if (ticket->IsAssignedTo(targetGuid))
145 {
146 handler->PSendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_B, ticket->GetId());
147 return true;
148 }
149
150 // If assigned to different player other than current, leave
152 Player* player = handler->GetSession() ? handler->GetSession()->GetPlayer() : nullptr;
153 if (player && ticket->IsAssignedNotTo(player->GetGUID()))
154 {
155 handler->PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->GetId());
156 return true;
157 }
158
159 // Assign ticket
160 ticket->SetAssignedTo(targetGuid);
161
162 ticket->SaveToDB();
163
164 std::string msg = ticket->FormatViewMessageString(*handler, nullptr, target.c_str(), nullptr, nullptr);
165 handler->SendGlobalGMSysMessage(msg.c_str());
166 return true;
167}
168
169template<typename T>
171{
172 if (!*args)
173 return false;
174
175 uint32 ticketId = atoi(args);
176 T* ticket = sSupportMgr->GetTicket<T>(ticketId);
177 if (!ticket || ticket->IsClosed())
178 {
180 return true;
181 }
182
183 // Ticket should be assigned to the player who tries to close it.
184 // Console can override though
185 Player* player = handler->GetSession() ? handler->GetSession()->GetPlayer() : nullptr;
186 if (player && ticket->IsAssignedNotTo(player->GetGUID()))
187 {
188 handler->PSendSysMessage(LANG_COMMAND_TICKETCANNOTCLOSE, ticket->GetId());
189 return true;
190 }
191
192 ObjectGuid closedByGuid;
193 if (player)
194 closedByGuid = player->GetGUID();
195 else
196 closedByGuid.SetRawValue(0, uint64(-1));
197
198 sSupportMgr->CloseTicket<T>(ticket->GetId(), closedByGuid);
199
200 std::string msg = ticket->FormatViewMessageString(*handler, player ? player->GetName().c_str() : "Console", nullptr, nullptr, nullptr);
201 handler->SendGlobalGMSysMessage(msg.c_str());
202
203 return true;
204}
205
206template<typename T>
208{
209 if (!*args)
210 return false;
211
212 char* ticketIdStr = strtok((char*)args, " ");
213 uint32 ticketId = atoi(ticketIdStr);
214
215 char* comment = strtok(nullptr, "\n");
216 if (!comment)
217 return false;
218
219 T* ticket = sSupportMgr->GetTicket<T>(ticketId);
220 if (!ticket || ticket->IsClosed())
221 {
223 return true;
224 }
225
226 // Cannot comment ticket assigned to someone else
228 Player* player = handler->GetSession() ? handler->GetSession()->GetPlayer() : nullptr;
229 if (player && ticket->IsAssignedNotTo(player->GetGUID()))
230 {
231 handler->PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->GetId());
232 return true;
233 }
234
235 ticket->SetComment(comment);
236 ticket->SaveToDB();
237 sSupportMgr->UpdateLastChange();
238
239 std::string msg = ticket->FormatViewMessageString(*handler, nullptr, ticket->GetAssignedToName().c_str(), nullptr, nullptr);
240 msg += handler->PGetParseString(LANG_COMMAND_TICKETLISTADDCOMMENT, player ? player->GetName().c_str() : "Console", comment);
241 handler->SendGlobalGMSysMessage(msg.c_str());
242
243 return true;
244}
245
246template<typename T>
248{
249 sSupportMgr->ShowList<T>(*handler);
250 return true;
251}
252
253template<typename T>
255{
256 sSupportMgr->ShowClosedList<T>(*handler);
257 return true;
258}
259
260template<typename T>
262{
263 if (!*args)
264 return false;
265
266 uint32 ticketId = atoi(args);
267 T* ticket = sSupportMgr->GetTicket<T>(ticketId);
268 if (!ticket)
269 {
271 return true;
272 }
273
274 if (!ticket->IsClosed())
275 {
277 return true;
278 }
279
280 std::string msg = ticket->FormatViewMessageString(*handler, nullptr, nullptr, nullptr, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetName().c_str() : "Console");
281 handler->SendGlobalGMSysMessage(msg.c_str());
282
283 sSupportMgr->RemoveTicket<T>(ticket->GetId());
284
285 return true;
286}
287
288template<typename T>
290{
291 if (sSupportMgr->GetOpenTicketCount<T>())
292 {
294 return true;
295 }
296 else
297 {
298 sSupportMgr->ResetTickets<T>();
300 }
301 return true;
302}
303
304template<typename T>
306{
307 if (!*args)
308 return false;
309
310 uint32 ticketId = atoi(args);
311 T* ticket = sSupportMgr->GetTicket<T>(ticketId);
312 if (!ticket || ticket->IsClosed())
313 {
315 return true;
316 }
317 // Ticket must be assigned
318 if (!ticket->IsAssigned())
319 {
320 handler->PSendSysMessage(LANG_COMMAND_TICKETNOTASSIGNED, ticket->GetId());
321 return true;
322 }
323
324 // Get security level of player, whom this ticket is assigned to
325 uint32 security = SEC_PLAYER;
326 Player* assignedPlayer = ticket->GetAssignedPlayer();
327 if (assignedPlayer)
328 security = assignedPlayer->GetSession()->GetSecurity();
329 else
330 {
331 ObjectGuid guid = ticket->GetAssignedToGUID();
332 uint32 accountId = sCharacterCache->GetCharacterAccountIdByGuid(guid);
333 security = AccountMgr::GetSecurity(accountId, sRealmList->GetCurrentRealmId().Realm);
334 }
335
336 // Check security
338 uint32 mySecurity = handler->GetSession() ? handler->GetSession()->GetSecurity() : SEC_CONSOLE;
339 if (security > mySecurity)
340 {
342 return true;
343 }
344
345 std::string assignedTo = ticket->GetAssignedToName(); // copy assignedto name because we need it after the ticket has been unnassigned
346 ticket->SetUnassigned();
347 ticket->SaveToDB();
348
349 std::string msg = ticket->FormatViewMessageString(*handler, nullptr, assignedTo.c_str(), handler->GetSession() ? handler->GetSession()->GetPlayer()->GetName().c_str() : "Console", nullptr);
350 handler->SendGlobalGMSysMessage(msg.c_str());
351
352 return true;
353}
354
355template<typename T>
357{
358 if (!*args)
359 return false;
360
361 uint32 ticketId = atoi(args);
362 T* ticket = sSupportMgr->GetTicket<T>(ticketId);
363 if (!ticket || ticket->IsClosed())
364 {
366 return true;
367 }
368
369 handler->SendSysMessage(ticket->FormatViewMessageString(*handler, true));
370 return true;
371}
372
373std::span<ChatCommandBuilder const> ticket_commandscript::GetCommands() const
374{
375 static ChatCommandTable ticketBugCommandTable =
376 {
377 { "assign", rbac::RBAC_PERM_COMMAND_TICKET_BUG_ASSIGN, true, &HandleTicketAssignToCommand<BugTicket>, "" },
378 { "close", rbac::RBAC_PERM_COMMAND_TICKET_BUG_CLOSE, true, &HandleTicketCloseByIdCommand<BugTicket>, "" },
379 { "closedlist", rbac::RBAC_PERM_COMMAND_TICKET_BUG_CLOSEDLIST, true, &HandleTicketListClosedCommand<BugTicket>, "" },
380 { "comment", rbac::RBAC_PERM_COMMAND_TICKET_BUG_COMMENT, true, &HandleTicketCommentCommand<BugTicket>, "" },
381 { "delete", rbac::RBAC_PERM_COMMAND_TICKET_BUG_DELETE, true, &HandleTicketDeleteByIdCommand<BugTicket>, "" },
382 { "list", rbac::RBAC_PERM_COMMAND_TICKET_BUG_LIST, true, &HandleTicketListCommand<BugTicket>, "" },
383 { "unassign", rbac::RBAC_PERM_COMMAND_TICKET_BUG_UNASSIGN, true, &HandleTicketUnAssignCommand<BugTicket>, "" },
384 { "view", rbac::RBAC_PERM_COMMAND_TICKET_BUG_VIEW, true, &HandleTicketGetByIdCommand<BugTicket>, "" },
385 };
386 static ChatCommandTable ticketComplaintCommandTable =
387 {
388 { "assign", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT_ASSIGN, true, &HandleTicketAssignToCommand<ComplaintTicket>, "" },
389 { "close", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT_CLOSE, true, &HandleTicketCloseByIdCommand<ComplaintTicket>, "" },
390 { "closedlist", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT_CLOSEDLIST, true, &HandleTicketListClosedCommand<ComplaintTicket>, "" },
391 { "comment", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT_COMMENT, true, &HandleTicketCommentCommand<ComplaintTicket>, "" },
392 { "delete", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT_DELETE, true, &HandleTicketDeleteByIdCommand<ComplaintTicket>, "" },
393 { "list", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT_LIST, true, &HandleTicketListCommand<ComplaintTicket>, "" },
394 { "unassign", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT_UNASSIGN, true, &HandleTicketUnAssignCommand<ComplaintTicket>, "" },
395 { "view", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT_VIEW, true, &HandleTicketGetByIdCommand<ComplaintTicket>, "" },
396 };
397 static ChatCommandTable ticketSuggestionCommandTable =
398 {
399 { "assign", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION_ASSIGN, true, &HandleTicketAssignToCommand<SuggestionTicket>, "" },
400 { "close", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION_CLOSE, true, &HandleTicketCloseByIdCommand<SuggestionTicket>, "" },
401 { "closedlist", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION_CLOSEDLIST, true, &HandleTicketListClosedCommand<SuggestionTicket>, "" },
402 { "comment", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION_COMMENT, true, &HandleTicketCommentCommand<SuggestionTicket>, "" },
403 { "delete", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION_DELETE, true, &HandleTicketDeleteByIdCommand<SuggestionTicket>, "" },
404 { "list", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION_LIST, true, &HandleTicketListCommand<SuggestionTicket>, "" },
405 { "unassign", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION_UNASSIGN, true, &HandleTicketUnAssignCommand<SuggestionTicket>, "" },
406 { "view", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION_VIEW, true, &HandleTicketGetByIdCommand<SuggestionTicket>, "" },
407 };
408 static ChatCommandTable ticketResetCommandTable =
409 {
411 { "bug", rbac::RBAC_PERM_COMMAND_TICKET_RESET_BUG, true, &HandleTicketResetCommand<BugTicket>, "" },
412 { "complaint", rbac::RBAC_PERM_COMMAND_TICKET_RESET_COMPLAINT, true, &HandleTicketResetCommand<ComplaintTicket>, "" },
413 { "suggestion", rbac::RBAC_PERM_COMMAND_TICKET_RESET_SUGGESTION, true, &HandleTicketResetCommand<SuggestionTicket>, "" },
414 };
415 static ChatCommandTable ticketCommandTable =
416 {
417 { "bug", rbac::RBAC_PERM_COMMAND_TICKET_BUG, true, nullptr, "", ticketBugCommandTable },
418 { "complaint", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT, true, nullptr, "", ticketComplaintCommandTable },
419 { "reset", rbac::RBAC_PERM_COMMAND_TICKET_RESET, true, nullptr, "", ticketResetCommandTable },
420 { "suggestion", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION, true, nullptr, "", ticketSuggestionCommandTable },
422 };
423 static ChatCommandTable commandTable =
424 {
425 { "ticket", rbac::RBAC_PERM_COMMAND_TICKET, false, nullptr, "", ticketCommandTable },
426 };
427 return commandTable;
428}
429
#define sCharacterCache
@ SEC_PLAYER
Definition Common.h:43
@ SEC_CONSOLE
Definition Common.h:47
uint64_t uint64
Definition Define.h:153
uint32_t uint32
Definition Define.h:154
@ LANG_COMMAND_TICKETRESET
Definition Language.h:1059
@ LANG_COMMAND_TICKETALREADYASSIGNED
Definition Language.h:1038
@ LANG_ALLOW_TICKETS
Definition Language.h:910
@ LANG_COMMAND_TICKETUNASSIGNSECURITY
Definition Language.h:1046
@ LANG_DISALLOW_TICKETS_CONFIG
Definition Language.h:997
@ LANG_COMMAND_TICKETCANNOTCLOSE
Definition Language.h:1047
@ LANG_COMMAND_TICKETCLOSEFIRST
Definition Language.h:1037
@ LANG_COMMAND_TICKETNOTASSIGNED
Definition Language.h:1045
@ LANG_DISALLOW_TICKETS
Definition Language.h:911
@ LANG_COMMAND_TICKETASSIGNERROR_B
Definition Language.h:1044
@ LANG_COMMAND_TICKETPENDING
Definition Language.h:1058
@ LANG_COMMAND_TICKETLISTADDCOMMENT
Definition Language.h:1055
@ LANG_COMMAND_TICKETASSIGNERROR_A
Definition Language.h:1043
@ LANG_COMMAND_TICKETNOTEXIST
Definition Language.h:1036
bool normalizePlayerName(std::string &name)
#define sRealmList
Definition RealmList.h:93
#define sSupportMgr
Definition SupportMgr.h:327
static uint32 GetSecurity(uint32 accountId, int32 realmId)
static bool HasPermission(uint32 accountId, uint32 permission, uint32 realmId)
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
void SendGlobalGMSysMessage(const char *str)
Definition Chat.cpp:137
WorldSession * GetSession()
Definition Chat.h:42
static std::string PGetParseString(std::string_view fmt, Args &&... args) noexcept
Definition Chat.h:74
void PSendSysMessage(char const *fmt, Args &&... args)
Definition Chat.h:62
virtual void SendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition Chat.cpp:111
void SetRawValue(std::span< uint8 const > rawBytes)
WorldSession * GetSession() const
Definition Player.h:2272
std::string const & GetName() const
Definition Object.h:342
AccountTypes GetSecurity() const
Player * GetPlayer() const
static bool HandleTicketResetAllCommand(ChatHandler *handler, char const *)
Definition cs_ticket.cpp:76
static bool HandleTicketResetCommand(ChatHandler *handler, char const *)
static bool HandleTicketAssignToCommand(ChatHandler *handler, char const *args)
static bool HandleTicketDeleteByIdCommand(ChatHandler *handler, char const *args)
static bool HandleTicketGetByIdCommand(ChatHandler *handler, char const *args)
static bool HandleTicketListClosedCommand(ChatHandler *handler, char const *)
static bool HandleTicketListCommand(ChatHandler *handler, char const *)
static bool HandleTicketCommentCommand(ChatHandler *handler, char const *args)
static bool HandleTicketCloseByIdCommand(ChatHandler *handler, char const *args)
std::span< ChatCommandBuilder const > GetCommands() const override
static bool HandleToggleGMTicketSystem(ChatHandler *handler, char const *)
Definition cs_ticket.cpp:93
static bool HandleTicketUnAssignCommand(ChatHandler *handler, char const *args)
void AddSC_ticket_commandscript()
#define sWorld
Definition World.h:916
@ CONFIG_SUPPORT_TICKETS_ENABLED
Definition World.h:157
ChatCommandBuilder const [] ChatCommandTable
Definition ChatCommand.h:49
@ RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET
Definition RBAC.h:85
@ RBAC_PERM_COMMAND_TICKET_SUGGESTION_DELETE
Definition RBAC.h:697
@ RBAC_PERM_COMMAND_TICKET_COMPLAINT_CLOSEDLIST
Definition RBAC.h:687
@ RBAC_PERM_COMMAND_TICKET_COMPLAINT_ASSIGN
Definition RBAC.h:685
@ RBAC_PERM_COMMAND_TICKET_SUGGESTION_ASSIGN
Definition RBAC.h:693
@ RBAC_PERM_COMMAND_TICKET_COMPLAINT_UNASSIGN
Definition RBAC.h:691
@ RBAC_PERM_COMMAND_TICKET_BUG_UNASSIGN
Definition RBAC.h:683
@ RBAC_PERM_COMMAND_TICKET_BUG_DELETE
Definition RBAC.h:681
@ RBAC_PERM_COMMAND_TICKET_SUGGESTION_CLOSEDLIST
Definition RBAC.h:695
@ RBAC_PERM_COMMAND_TICKET_COMPLAINT_DELETE
Definition RBAC.h:689
@ RBAC_PERM_COMMAND_TICKET_BUG_VIEW
Definition RBAC.h:684
@ RBAC_PERM_COMMAND_TICKET_COMPLAINT
Definition RBAC.h:675
@ RBAC_PERM_COMMAND_TICKET_BUG_CLOSEDLIST
Definition RBAC.h:679
@ RBAC_PERM_COMMAND_TICKET_TOGGLESYSTEM
Definition RBAC.h:629
@ RBAC_PERM_COMMAND_TICKET_BUG
Definition RBAC.h:674
@ RBAC_PERM_COMMAND_TICKET_BUG_CLOSE
Definition RBAC.h:678
@ RBAC_PERM_COMMAND_TICKET_BUG_ASSIGN
Definition RBAC.h:677
@ RBAC_PERM_COMMAND_TICKET_RESET_COMPLAINT
Definition RBAC.h:704
@ RBAC_PERM_COMMAND_TICKET_BUG_LIST
Definition RBAC.h:682
@ RBAC_PERM_COMMAND_TICKET
Definition RBAC.h:614
@ RBAC_PERM_COMMAND_TICKET_RESET_ALL
Definition RBAC.h:701
@ RBAC_PERM_COMMAND_TICKET_COMPLAINT_COMMENT
Definition RBAC.h:688
@ RBAC_PERM_COMMAND_TICKET_COMPLAINT_LIST
Definition RBAC.h:690
@ RBAC_PERM_COMMAND_TICKET_SUGGESTION
Definition RBAC.h:676
@ RBAC_PERM_COMMAND_TICKET_RESET
Definition RBAC.h:625
@ RBAC_PERM_COMMAND_TICKET_SUGGESTION_VIEW
Definition RBAC.h:700
@ RBAC_PERM_COMMAND_TICKET_SUGGESTION_COMMENT
Definition RBAC.h:696
@ RBAC_PERM_COMMAND_TICKET_SUGGESTION_CLOSE
Definition RBAC.h:694
@ RBAC_PERM_COMMAND_TICKET_COMPLAINT_CLOSE
Definition RBAC.h:686
@ RBAC_PERM_COMMAND_TICKET_BUG_COMMENT
Definition RBAC.h:680
@ RBAC_PERM_COMMAND_TICKET_RESET_BUG
Definition RBAC.h:703
@ RBAC_PERM_COMMAND_TICKET_COMPLAINT_VIEW
Definition RBAC.h:692
@ RBAC_PERM_COMMAND_TICKET_SUGGESTION_LIST
Definition RBAC.h:698
@ RBAC_PERM_COMMAND_TICKET_SUGGESTION_UNASSIGN
Definition RBAC.h:699
@ RBAC_PERM_COMMAND_TICKET_RESET_SUGGESTION
Definition RBAC.h:705