Compare commits

...

2 Commits

Author SHA1 Message Date
Meik
26eac54f94 aktueller stand 2026-02-13 09:08:02 +01:00
Meik
134876e45b aktueller Status 2026-02-05 13:49:38 +01:00

View File

@@ -274,7 +274,9 @@ namespace C4IT.F4SD
"IncidentNew",
"IncidentActive",
"IncidentCritical",
"IncidentNewInfo"
"IncidentNewInfo",
"UnassignedTickets",
"UnassignedTicketsCritical"
};
public class TicketOverviewCountsResult
@@ -348,11 +350,25 @@ namespace C4IT.F4SD
}
var entries = await LoadTicketOverviewEntries(sid, useRoleScope, queueoption, queues);
List<TicketOverviewEntry> unassignedEntries = null;
if (!useRoleScope && normalizedKeys.Any(IsUnassignedOverviewKey))
{
unassignedEntries = await LoadTicketOverviewUnassignedEntriesForPersonalScope(sid, queueoption, queues);
}
var counts = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
foreach (var key in normalizedKeys)
{
counts[key] = entries.Count(entry => MatchesTicketOverviewKey(entry, key));
if (!useRoleScope && IsUnassignedOverviewKey(key))
{
counts[key] = (unassignedEntries ?? new List<TicketOverviewEntry>())
.Count(entry => MatchesTicketOverviewKey(entry, key));
}
else
{
counts[key] = entries.Count(entry => MatchesTicketOverviewKey(entry, key));
}
}
return new TicketOverviewCountsResult { Counts = counts };
@@ -447,7 +463,15 @@ namespace C4IT.F4SD
return new List<TicketOverviewRelationDto>();
var useRoleScope = string.Equals(scope, "role", StringComparison.OrdinalIgnoreCase);
var entries = await LoadTicketOverviewEntries(sid, useRoleScope, queueoption, queues);
List<TicketOverviewEntry> entries;
if (!useRoleScope && IsUnassignedOverviewKey(key))
{
entries = await LoadTicketOverviewUnassignedEntriesForPersonalScope(sid, queueoption, queues);
}
else
{
entries = await LoadTicketOverviewEntries(sid, useRoleScope, queueoption, queues);
}
var filtered = entries
.Where(entry => MatchesTicketOverviewKey(entry, key))
@@ -531,6 +555,39 @@ namespace C4IT.F4SD
}
}
private async Task<List<TicketOverviewEntry>> LoadTicketOverviewUnassignedEntriesForPersonalScope(
string sid,
int queueoption,
List<cApiM42TicketQueueInfo> queues)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
await Task.Delay(0);
if (string.IsNullOrWhiteSpace(sid))
return new List<TicketOverviewEntry>();
var roleIds = await ResolveTicketOverviewRoleIdsAsync(sid, null);
var filter = BuildTicketOverviewFilterForRoleIds(roleIds, null, queueoption, queues);
if (string.IsNullOrWhiteSpace(filter))
return new List<TicketOverviewEntry>();
filter += " AND Recipient IS NULL";
return await LoadTicketOverviewEntriesByFilter(filter);
}
catch (Exception E)
{
LogException(E);
return new List<TicketOverviewEntry>();
}
finally
{
LogMethodEnd(CM);
}
}
private async Task<List<TicketOverviewEntry>> LoadTicketOverviewEntriesByRoleIds(
IEnumerable<Guid> roleIds,
int queueoption,
@@ -691,7 +748,8 @@ namespace C4IT.F4SD
if (!useRoleScope)
{
filter += $" AND Initiator.Accounts.T(SPSAccountClassAd).Sid = '{Escape(sid)}'";
var recipientFilter = $"Recipient.Accounts.T(SPSAccountClassAd).Sid = '{Escape(sid)}'";
filter += $" AND ({recipientFilter})";
return filter;
}
@@ -728,6 +786,16 @@ namespace C4IT.F4SD
? BuildTicketOverviewBaseFilter(queueoption, queues)
: baseFilter;
var roleClause = BuildRoleIdInClause(roleIds);
if (string.IsNullOrWhiteSpace(roleClause))
return null;
filter += $" AND {roleClause}";
return filter;
}
private static string BuildRoleIdInClause(IEnumerable<Guid> roleIds)
{
var roleIdList = (roleIds ?? Enumerable.Empty<Guid>())
.Where(id => id != Guid.Empty)
.Distinct()
@@ -737,8 +805,7 @@ namespace C4IT.F4SD
if (roleIdList.Count == 0)
return null;
filter += $" AND RecipientRole.T(SPSSecurityClassRole).ID IN ({string.Join(", ", roleIdList)})";
return filter;
return $"RecipientRole.T(SPSSecurityClassRole).ID IN ({string.Join(", ", roleIdList)})";
}
private string AppendQueueFilter(string filter, int queueoption, List<cApiM42TicketQueueInfo> queues)
@@ -813,13 +880,29 @@ namespace C4IT.F4SD
.ToList();
}
private static bool IsUnassignedOverviewKey(string key)
{
if (string.IsNullOrWhiteSpace(key))
return false;
switch (key.Trim())
{
case "UnassignedTickets":
case "UnassignedTicketsCritical":
return true;
default:
return false;
}
}
private static bool MatchesTicketOverviewKey(TicketOverviewEntry entry, string key)
{
if (entry == null || string.IsNullOrWhiteSpace(key))
return false;
var isTicket = !entry.IsIncident;
var isAssigned = entry.RecipientId != Guid.Empty || entry.RecipientRoleId != Guid.Empty;
var hasPerson = entry.RecipientId != Guid.Empty;
var hasRole = entry.RecipientRoleId != Guid.Empty;
var isCritical = entry.ReactionTimeEscalated || entry.SolutionTimeEscalated;
var isNew = entry.State == 200;
var isActive = entry.State == 201 || entry.State == 202 || entry.State == 203;
@@ -827,21 +910,25 @@ namespace C4IT.F4SD
switch (key.Trim())
{
case "TicketsNew":
return isTicket && isAssigned && isNew;
return isTicket && (entry.State == 200 || entry.State == 201);
case "TicketsActive":
return isTicket && isAssigned && isActive;
return isTicket && isActive;
case "TicketsCritical":
return isTicket && isAssigned && isCritical;
return isTicket && isCritical;
case "TicketsNewInfo":
return isTicket && isAssigned && entry.NewInformationReceived;
return isTicket && entry.NewInformationReceived;
case "IncidentNew":
return entry.IsIncident && isNew;
return entry.IsIncident && (entry.State == 200 || entry.State == 201);
case "IncidentActive":
return entry.IsIncident && isActive;
case "IncidentCritical":
return entry.IsIncident && isCritical;
case "IncidentNewInfo":
return entry.IsIncident && entry.NewInformationReceived;
case "UnassignedTickets":
return !hasPerson && hasRole && isNew;
case "UnassignedTicketsCritical":
return !hasPerson && hasRole && isCritical;
default:
return false;
}