diff --git a/.gitignore b/.gitignore
index 688980b..39a91ef 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,81 +1,14 @@
-# --------------------------------------------------------------------------------------------------
-# Core Visual Studio / .NET build outputs
-# --------------------------------------------------------------------------------------------------
-bin/
-obj/
-[Bb]uild/
-[Dd]ebug*/
-[Rr]elease*/
-x64/
-x86/
-[Aa][Rr][Mm]/
-[Aa][Rr][Mm]64/
-_ReSharper.*/
-*.user
-*.userosscache
-*.suo
-*.cache
-*.pdb
-*.mpdb
-*.opendb
-*.VC.db
-*.vscode/
-
-# --------------------------------------------------------------------------------------------------
-# Package artefacts (NuGet, npm, etc.)
-# --------------------------------------------------------------------------------------------------
-/packages/
-*.nupkg
-*.snupkg
-*.nuspec
-package-lock.json
-packages.config
-npm-debug.log*
-yarn-error.log
-
-# --------------------------------------------------------------------------------------------------
-# TFS / TFVC specific files and folders
-# --------------------------------------------------------------------------------------------------
-$tf/
-*$tf/
-*.tf
-*.tfs
-.tfignore
-
-# --------------------------------------------------------------------------------------------------
-# IDE tooling and workspace settings
-# --------------------------------------------------------------------------------------------------
-.vs/
-.vscode/
-*.swp
-*.sln.docstates
-*.VC.VC.opendb
-.idea/
-.DS_Store
-Thumbs.db
-
-# --------------------------------------------------------------------------------------------------
-# Test results and profiling data
-# --------------------------------------------------------------------------------------------------
-[Tt]est[Rr]esult*/
-[Bb]uild[Ll]og.*
-*.trx
-*.coverage
-*.coveragexml
-*.opencover.xml
-*.dotCover
-BenchmarkDotNet.Artifacts/
-
-# --------------------------------------------------------------------------------------------------
-# Miscellaneous recommended ignores
-# --------------------------------------------------------------------------------------------------
-_UpgradeReport_Files/
-Backup*/
-UpgradeLog*.XML
-*.tmp
-*.temp
-*.log
-*.bak
-*.orig
-*.scc
-
+bin/
+obj/
+.vs/
+*.user
+packages/
+F4SDHelper/packages.config
+F4SDM42WebApi/packages.config
+F4SDM42WebApi/BasePackage/Assemblies/
+F4SDM42WebApi/Root/InstalledPackages/
+F4SDHelper/bin/
+F4SDHelper/obj/
+F4SDM42WebApi/bin/
+F4SDM42WebApi/obj/
+artifacts/
diff --git a/C4IT - F4SD - M42WebApi.sln b/C4IT - F4SD - M42WebApi.sln
index e5e1f32..c0e60c0 100644
--- a/C4IT - F4SD - M42WebApi.sln
+++ b/C4IT - F4SD - M42WebApi.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.5.33424.131
+# Visual Studio Version 18
+VisualStudioVersion = 18.7.11919.86 stable
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "F4SD - M42WebApi", "F4SDM42WebApi\F4SD - M42WebApi.csproj", "{D8CBFFCA-0B43-4ACC-80EA-C944E7420CEE}"
EndProject
@@ -47,25 +47,6 @@ Global
EndGlobalSection
GlobalSection(SharedMSBuildProjectFiles) = preSolution
M42F4SDUUXWorkspace\M42F4SDUUXWorkspace.projitems*{c3d52a04-2461-4f35-8edf-de7226add677}*SharedItemsImports = 13
- M42F4SDUUXWorkspace\M42F4SDUUXWorkspace.projitems*{d8cbffca-0b43-4acc-80ea-c944e7420cee}*SharedItemsImports = 4
- EndGlobalSection
- GlobalSection(TeamFoundationVersionControl) = preSolution
- SccNumberOfProjects = 5
- SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- SccTeamFoundationServer = https://consulting4it.visualstudio.com/
- SccLocalPath0 = .
- SccProjectUniqueName1 = F4SDHelper\\F4SD\u0020-\u0020Helper.csproj
- SccProjectName1 = F4SDHelper
- SccLocalPath1 = F4SDHelper
- SccProjectUniqueName2 = F4SDM42WebApi\\F4SD\u0020-\u0020M42WebApi.csproj
- SccProjectName2 = F4SDM42WebApi
- SccLocalPath2 = F4SDM42WebApi
- SccProjectUniqueName3 = M42F4SDUUXWorkspace\\F4SD\u0020-\u0020M42\u0020UUX\u0020Workspace.shproj
- SccProjectName3 = M42F4SDUUXWorkspace
- SccLocalPath3 = M42F4SDUUXWorkspace
- SccProjectUniqueName4 = M42F4SDUUXWorkspace\\M42F4SDUUXWorkspace.projitems
- SccProjectTopLevelParentUniqueName4 = M42F4SDUUXWorkspace\\F4SD\u0020-\u0020M42\u0020UUX\u0020Workspace.shproj
- SccProjectName4 = M42F4SDUUXWorkspace
- SccLocalPath4 = M42F4SDUUXWorkspace
+ M42F4SDUUXWorkspace\M42F4SDUUXWorkspace.projitems*{d8cbffca-0b43-4acc-80ea-c944e7420cee}*SharedItemsImports = 5
EndGlobalSection
EndGlobal
diff --git a/F4SDHelper/F4SD - Helper.csproj b/F4SDHelper/F4SD - Helper.csproj
index 5e47625..1939174 100644
--- a/F4SDHelper/F4SD - Helper.csproj
+++ b/F4SDHelper/F4SD - Helper.csproj
@@ -1,75 +1,34 @@
-
-
-
+
- Debug
- AnyCPU
- {EB95E1FB-7A9E-4894-BD28-2D0BE2715EBE}
+ net8.0
Library
- Properties
C4IT.F4SDM
C4ITF4SDM42WebApiHelper
- v4.7.2
- 512
- true
-
- SAK
- SAK
- SAK
- SAK
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
- bin\Release_and_copy\
- TRACE
- true
- pdbonly
- AnyCPU
- 7.3
- prompt
+ disable
+ disable
+ latestmajor
+ false
+ false
+
-
- ..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll
+
+ ..\F4SDM42WebApi\M42Libraries\26.1\Newtonsoft.Json.dll
+ false
-
-
-
-
-
-
-
-
+
+
Common\C4IT.Logging.LogManager.cs
+
+ Common\C4IT.F4SD.Base.Ticket.cs
+
Properties\SharedAssemblyInfo.cs
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
diff --git a/F4SDM42WebApi/BuildM42Package.ps1 b/F4SDM42WebApi/BuildM42Package.ps1
new file mode 100644
index 0000000..dab584d
--- /dev/null
+++ b/F4SDM42WebApi/BuildM42Package.ps1
@@ -0,0 +1,73 @@
+param(
+ [Parameter(Mandatory = $true)]
+ [string]$TemplateDir,
+
+ [Parameter(Mandatory = $true)]
+ [string]$AssembliesDir,
+
+ [Parameter(Mandatory = $true)]
+ [string]$OutputRoot,
+
+ [Parameter(Mandatory = $true)]
+ [string]$PackageName,
+
+ [Parameter(Mandatory = $true)]
+ [string]$PackageVersion
+)
+
+$ErrorActionPreference = 'Stop'
+
+function Normalize-FullPath {
+ param([string]$Path)
+ return [System.IO.Path]::GetFullPath($Path)
+}
+
+function Normalize-TextFileLineEndings {
+ param([string]$Path)
+
+ $content = [System.IO.File]::ReadAllText($Path)
+ $content = [regex]::Replace($content, '(?
+
+
+
+
+
+
diff --git a/F4SDM42WebApi/F4SD - M42WebApi.csproj b/F4SDM42WebApi/F4SD - M42WebApi.csproj
index 4aa97e3..68192c0 100644
--- a/F4SDM42WebApi/F4SD - M42WebApi.csproj
+++ b/F4SDM42WebApi/F4SD - M42WebApi.csproj
@@ -1,143 +1,99 @@
-
-
-
+
- Debug
- AnyCPU
- {D8CBFFCA-0B43-4ACC-80EA-C944E7420CEE}
+ net8.0
Library
- Properties
C4IT.F4SDM
C4ITF4SDM42WebApi
- v4.7.2
- 512
- true
-
- SAK
- SAK
- SAK
- SAK
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
- true
- bin\Debug_and_copy\
- DEBUG;TRACE
- full
- AnyCPU
- 7.3
- prompt
-
-
- bin\Release_and_copy\
- TRACE
- true
- pdbonly
- AnyCPU
- 7.3
- prompt
+ win-x64;linux-x64
+ true
+ disable
+ disable
+ latestmajor
+ false
+ false
+ 6673a25d-33d6-4072-91d9-abed4be1a966
+ C4ITF4SD*.*
+ 1.4.0.14
+ true
+
-
- False
- M42Libraries\Matrix42.Common.dll
+
+ M42Libraries\26.1\Matrix42.Common.dll
+ false
-
- False
- M42Libraries\Matrix42.Contracts.Common.dll
+
+ M42Libraries\26.1\Matrix42.Contracts.Common.dll
+ false
-
- False
- M42Libraries\Matrix42.Contracts.Platform.dll
+
+ M42Libraries\26.1\Matrix42.Contracts.Platform.dll
+ false
-
- False
- M42Libraries\Matrix42.Contracts.ServiceManagement.dll
+
+ M42Libraries\26.1\Matrix42.Contracts.ServiceManagement.dll
+ false
-
- False
- M42Libraries\Matrix42.Pandora.Contracts.dll
+
+ M42Libraries\26.1\Matrix42.Hosting.Contracts.dll
+ false
-
- False
- M42Libraries\Matrix42.Services.Description.Contracts.dll
+
+ M42Libraries\26.1\Matrix42.Configuration.Global.dll
+ false
-
- False
+
+ M42Libraries\26.1\Matrix42.Pandora.Contracts.dll
+ false
-
- ..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll
+
+ M42Libraries\26.1\Matrix42.Persistence.Contracts.dll
+ false
-
-
-
-
-
- False
- M42Libraries\System.Web.Http.dll
+
+ M42Libraries\26.1\Matrix42.Services.Description.Contracts.dll
+ false
-
- False
- M42Libraries\System.Web.OData.dll
+
+ M42Libraries\26.1\Matrix42.WebApi.Contracts.dll
+ false
-
-
-
-
-
-
-
- False
- M42Libraries\update4u.SPS.DataLayer.dll
+
+ M42Libraries\26.1\Newtonsoft.Json.dll
+ false
-
- False
- M42Libraries\update4u.SPS.Utility.dll
+
+ M42Libraries\26.1\System.Net.Http.Formatting.dll
+ false
+
+
+ M42Libraries\26.1\update4u.SPS.DataLayer.dll
+ false
+
+
+ M42Libraries\26.1\update4u.SPS.Utility.dll
+ false
+
+
+
+
+
-
- Properties\SharedAssemblyInfo.cs
-
+
+ Properties\SharedAssemblyInfo.cs
+
+
-
- {eb95e1fb-7a9e-4894-bd28-2d0be2715ebe}
- F4SD - Helper
- True
-
-
-
-
-
-
-
+
+
-
-
- @echo powershell -ExecutionPolicy Unrestricted $(ProjectDir)deploy.ps1 -ProjectDir $(ProjectDir) -SolutionDir $(SolutionDir) -OutDir $(OutDir) -ConfigurationName $(ConfigurationName)
-
-
\ No newline at end of file
+
+
diff --git a/F4SDM42WebApi/F4SDHelperService.cs b/F4SDM42WebApi/F4SDHelperService.cs
index 7345429..a68fa60 100644
--- a/F4SDM42WebApi/F4SDHelperService.cs
+++ b/F4SDM42WebApi/F4SDHelperService.cs
@@ -1,2168 +1,2761 @@
-using C4IT.F4SDM;
-using C4IT.FASD.Base;
-using C4IT.Logging;
-using Matrix42.Common;
-using Newtonsoft.Json;
-using System;
-using System.Collections.Generic;
-using System.Data;
-using System.Data.SqlClient;
-using System.Dynamic;
-using System.Globalization;
-using System.IO;
-using System.IO.Compression;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Net.Http.Headers;
-using System.Reflection;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-using System.Web;
-using update4u.SPS.DataLayer;
-using update4u.SPS.DataLayer.Transaction;
-using static C4IT.FASD.Base.cF4SDTicket;
-using static C4IT.Logging.cLogManager;
-
-namespace C4IT.F4SD
-{
- public class F4SDHelperService
- {
- private static Guid SPSUserClassBaseID = SPSDataEngineSchemaReader.ClassGetIDFromName("SPSUserClassBase");
- private static Guid SPSAccountClassBaseID = SPSDataEngineSchemaReader.ClassGetIDFromName("SPSAccountClassBase");
- private static Guid SPSCommonClassBaseID = SPSDataEngineSchemaReader.ClassGetIDFromName("SPSCommonClassBase");
- private static Guid SPSAccountClassADID = SPSDataEngineSchemaReader.ClassGetIDFromName("SPSAccountClassAD");
- private static Guid SPSActivityClassBaseID = SPSDataEngineSchemaReader.ClassGetIDFromName("SPSActivityClassBase");
- private static Guid SPSActivityClassIncidentID = SPSDataEngineSchemaReader.ClassGetIDFromName("SPSActivityClassIncident");
- private static Guid SPSActivityClassUnitOfWorkID = SPSDataEngineSchemaReader.ClassGetIDFromName("SPSActivityClassUnitOfWork");
- private static Guid SPSScCategoryClassBaseID = SPSDataEngineSchemaReader.ClassGetIDFromName("SPSScCategoryClassBase");
- private static Guid SPSAssetClassBaseID = SPSDataEngineSchemaReader.ClassGetIDFromName("SPSAssetClassBase");
- private static Guid SPSSecurityClassRole = SPSDataEngineSchemaReader.ClassGetIDFromName("SPSSecurityClassRole");
-
- public static readonly Guid Administrators = new Guid("{A5D7B682-B211-4D94-A96D-8C57EEDAFDEA}");
-
- private const string TicketCloseActionId = "51bb3283-7bd1-e511-9a82-60e327035d31";
- private const string TicketDirectLinkCreateTemplate = @"{0}/wm/app-ServiceDesk/notSet/create-object/{1}?view-options=%7B%22embedded%22:false%7D&presetParams={2}";
- private const string IncidentDirectLinkCloseTemplate = @"{0}/wm/app-ServiceDesk/notSet/preview-object/SPSActivityTypeIncident/{1}/0/?view-options={2}";
- private const string TicketDirectLinkPreviewTemplate = @"{0}/wm/app-ServiceDesk/notSet/preview-object/{1}/{2}/0/";
- private const string TicketDirectLinkEditTemplate = @"{0}/wm/app-ServiceDesk/notSet/edit-object/{1}/{2}";
-
- private const string placeHolderSubject = "PARAM_SUBJECT";
- private const string placeHolderDescription = "PARAM_DESCRIPTION";
- private const string c4itf4sdmonLinkBase = "f4sdsend://localhost";
-
- private const string F4SDTicketTableName = "M42WPM-TICKETS-INFOS";
- private const string F4SDTicketStatusColumnName = "STATUS";
-
-
- public static IEnumerable ReadLines(Func streamProvider,
- Encoding encoding)
- {
- using (var stream = streamProvider())
- using (var reader = new StreamReader(stream, encoding))
- {
- string line;
- while ((line = reader.ReadLine()) != null)
- {
- yield return line;
- }
- }
- }
-
- internal async Task getDirectLinkF4SD(Guid EOID, string type)
- {
- var CM = MethodBase.GetCurrentMethod();
- LogMethodBegin(CM);
- try
- {
- LogEntry($"Generating F4SD URI for type: '{type}', GUID: '{EOID}'", LogLevels.Debug);
- var builder = new UriBuilder(c4itf4sdmonLinkBase);
- var queryString = HttpUtility.ParseQueryString(builder.Query);
-
- switch (type.ToLowerInvariant().Split('.').Last())
- {
- case "person":
- case "user":
- var user = getUsersByAsql($"[Expression-ObjectId]='{EOID}'")?.FirstOrDefault();
- string Sids = string.Empty;
-
- if (user != null)
- {
- var accounts = getAccountsByAsql($"Owner='{user.Id}'");
- Sids = string.Join(",", accounts?.Where(x => !string.IsNullOrEmpty(x.Sid)).Select(x => x.Sid) ?? Array.Empty());
- }
-
- if (!string.IsNullOrEmpty(user?.Name))
- {
- queryString.Add("command", "UserSidSearch");
- queryString.Add("name", user.Name);
- queryString.Add("sids", Sids);
- }
- break;
-
- case "asset":
- var asset = getAssetsByAsql($"UsedInTypeSPSComputerType is not null AND [Expression-ObjectId]='{EOID}'")?.FirstOrDefault();
- if (asset != null)
- {
- queryString.Add("command", "ComputerDomainSearch");
- queryString.Add("name", asset.Name);
- queryString.Add("domain", asset.DomainName);
- }
- break;
-
- case "incident":
- case "servicerequest":
- case "ticket":
- var ticket = (await getTicketDetails(new List { EOID }))?.FirstOrDefault();
- if (ticket != null)
- {
- queryString.Add("command", "TicketSearch");
- queryString.Add("tname", ticket.Name);
- queryString.Add("tid", ticket.TicketObjectId.ToString());
-
- if (ticket.AffectedUserId != Guid.Empty)
- {
- var initiator = getUsersByAsql($"ID = '{ticket.AffectedUserId}'")?.FirstOrDefault();
- string userName = initiator?.Name;
- Sids = string.Join(",", getAccountsByAsql($"Owner='{ticket.AffectedUserId}'")?.Where(x => !string.IsNullOrEmpty(x.Sid)).Select(x => x.Sid) ?? Array.Empty());
-
- queryString.Add("uname", userName);
- queryString.Add("sids", Sids);
- }
- }
- break;
-
- default:
- break;
- }
-
- builder.Query = queryString.ToString();
- return string.IsNullOrEmpty(builder.Query) ? null : builder.ToString();
- }
- catch (Exception E)
- {
- LogException(E);
- return null;
- }
- finally
- {
- LogMethodEnd(CM);
- }
- }
-
-
- internal async Task> getTicketListByUser(string userSid, int hours, int queueoption, List queues)
- {
- var CM = MethodBase.GetCurrentMethod();
- LogMethodBegin(CM);
- try
- {
- LogEntry($"Generating ticket list for userSid: '{userSid}', {hours} hours", LogLevels.Debug);
- await Task.Delay(0);
-
- var tickets = new List();
- var activityFilter = GetActivityFilter(userSid, hours, ticketAndServiceRequestEnabled(), queueoption, queues);
- LogEntry($"ASql Filter: {activityFilter}");
-
- var activityTable = FragmentRequestBase.SimpleLoad(SPSActivityClassBaseID,
- string.Format("[Expression-ObjectID] as EOID, TicketNumber, Subject, Service.ID as ServiceId, Service.Name as ServiceName, SUBQUERY(BasicSchemaObjectType as bso, bso.Name, bso.id = base.T(SPSCommonClassBase).TypeID) as ActivityType" +
- ", COALESCE(T(SPSActivityClassIncident).Asset.T(SPSComputerClassBase).Name, T(SPSActivityClassIncident).Asset.T(SPSAssetClassSIMCard).PhoneNumber, T(SPSActivityClassIncident).Asset.Name, T(SPSActivityClassIncident).Asset.objectid) as AssetName" +
- ", SUBQUERY(BasicSchemaObjectType AS t, t.Name, t.ID=base.T(SPSActivityClassIncident).Asset.T(SPSCommonClassBase).TypeID) as AssetCIName" +
- ", CASE WHEN Initiator.PrimaryAccount.T(SPSAccountClassAd).Sid = '{0}' THEN 1 ELSE 0 END AS IsPrimaryAccount",
- userSid),
- activityFilter);
-
- if (activityTable?.Rows == null || activityTable.Rows.Count == 0)
- {
- LogEntry($"No activity entries found for userSid: '{userSid}'", LogLevels.Warning);
- return null;
- }
-
- for (int i = 0; i < activityTable.Rows.Count; i++)
- {
- DataRow entry = activityTable.Rows[i];
- var activityEOId = getGuidFromObject(entry["EOID"]);
- var ticketNumber = getStringFromObject(entry["TicketNumber"]);
- var activityType = getStringFromObject(entry["ActivityType"]);
- var assetName = getStringFromObject(entry["AssetName"]);
- var ServiceName = getStringFromObject(entry["ServiceName"]);
- var assetCIName = getStringFromObject(entry["AssetCIName"]);
- var subject = getStringFromObject(entry["Subject"]);
-
- var stateData = GetActivityState(activityEOId);
- var state = stateData.Item1;
- var stateDisp = stateData.Item2;
-
- LogEntry($"Activity found {i + 1}/{activityTable.Rows.Count}: ObjectID={activityEOId}, TicketNumber={ticketNumber}, Subject={subject}, State={state}", LogLevels.Debug);
-
- if (string.IsNullOrEmpty(ticketNumber))
- {
- LogEntry($"No TicketNumber found for activity entry", LogLevels.Warning);
- continue;
- }
-
- if (string.IsNullOrEmpty(assetName))
- {
- LogEntry($"No AssetName found for activity entry", LogLevels.Debug);
- }
-
- if (string.IsNullOrEmpty(assetCIName))
- {
- LogEntry($"No AssetCIName found for activity entry", LogLevels.Debug);
- }
- var ServiceId = getGuidFromObject(entry["ServiceId"]);
- if (ServiceId == Guid.Empty)
- {
- LogEntry($"no ServiceId found for activity entry", LogLevels.Debug);
- }
- var AssetCIName = getStringFromObject(entry["AssetCIName"]);
- if (AssetCIName == string.Empty)
- {
- LogEntry($"no AssetCIName found for activity entry", LogLevels.Debug);
- }
- var Subject = getStringFromObject(entry["Subject"]);
- if (Subject == string.Empty)
- {
- LogEntry($"no Subject found for activity entry", LogLevels.Warning);
- continue;
- }
- var IsPrimaryAccount = getIntFromObject(entry["IsPrimaryAccount"]);
-
- if (string.IsNullOrEmpty(subject))
- {
- LogEntry($"No Subject found for activity entry", LogLevels.Warning);
- continue;
- }
-
- tickets.Add(new cF4SDTicketSummary()
- {
- TicketObjectId = activityEOId,
- Name = ticketNumber,
- ActivityType = activityType,
- AssetCIName = assetCIName,
- AssetName = assetName,
- ServiceId = ServiceId,
- ServiceName = ServiceName,
- StatusId = state,
- Status = stateDisp,
- Summary = subject,
- IsPrimaryAccount = IsPrimaryAccount == 1
- });
- }
-
- tickets = tickets.OrderByDescending(x => x.Name).ToList();
- return tickets;
- }
- catch (Exception E)
- {
- LogException(E);
- return null;
- }
- finally
- {
- LogMethodEnd(CM);
- }
- }
-
- private static readonly string[] TicketOverviewKeys = new[]
- {
- "TicketsNew",
- "TicketsActive",
- "TicketsCritical",
- "TicketsNewInfo",
- "IncidentNew",
- "IncidentActive",
- "IncidentCritical",
- "IncidentNewInfo",
- "UnassignedTickets",
- "UnassignedTicketsCritical"
- };
-
- public class TicketOverviewCountsResult
- {
- [JsonProperty("counts")]
- public Dictionary Counts { get; set; } = new Dictionary(StringComparer.OrdinalIgnoreCase);
- }
-
- public class TicketOverviewCountsByRoleResult
- {
- [JsonProperty("generatedAtUtc")]
- public DateTime GeneratedAtUtc { get; set; } = DateTime.UtcNow;
-
- [JsonProperty("countsByRole")]
- public Dictionary> CountsByRole { get; set; }
- = new Dictionary>(StringComparer.OrdinalIgnoreCase);
- }
-
- public class TicketOverviewRelationDto
- {
- public enumF4sdSearchResultClass Type { get; set; }
- public string Name { get; set; }
- public string DisplayName { get; set; }
- public Guid id { get; set; }
- public enumF4sdSearchResultStatus Status { get; set; } = enumF4sdSearchResultStatus.Unknown;
- public Dictionary Infos { get; set; } = null;
- public List Identities { get; set; } = null;
- }
-
- private sealed class TicketOverviewEntry
- {
- public Guid TicketId { get; set; }
- public string TicketNumber { get; set; }
- public string Summary { get; set; }
- public Guid InitiatorId { get; set; }
- public string InitiatorDisplayName { get; set; }
- public string InitiatorAccount { get; set; }
- public string InitiatorDomain { get; set; }
- public string InitiatorSid { get; set; }
- public Guid RecipientId { get; set; }
- public Guid RecipientRoleId { get; set; }
- public int State { get; set; }
- public DateTime CreatedDate { get; set; }
- public bool NewInformationReceived { get; set; }
- public bool ReactionTimeEscalated { get; set; }
- public bool SolutionTimeEscalated { get; set; }
- public bool IsIncident { get; set; }
- public string ActivityType { get; set; }
- }
-
- internal async Task getTicketOverviewCounts(
- string sid,
- string scope,
- IEnumerable keys,
- int queueoption,
- List queues)
- {
- var CM = MethodBase.GetCurrentMethod();
- LogMethodBegin(CM);
- try
- {
- var useRoleScope = string.Equals(scope, "role", StringComparison.OrdinalIgnoreCase);
- var normalizedKeys = (keys ?? Array.Empty())
- .Where(k => !string.IsNullOrWhiteSpace(k))
- .Distinct(StringComparer.OrdinalIgnoreCase)
- .ToList();
-
- if (normalizedKeys.Count == 0)
- {
- normalizedKeys.AddRange(TicketOverviewKeys);
- }
-
- var entries = await LoadTicketOverviewEntries(sid, useRoleScope, queueoption, queues);
- List unassignedEntries = null;
- if (!useRoleScope && normalizedKeys.Any(IsUnassignedOverviewKey))
- {
- unassignedEntries = await LoadTicketOverviewUnassignedEntriesForPersonalScope(sid, queueoption, queues);
- }
-
- var counts = new Dictionary(StringComparer.OrdinalIgnoreCase);
-
- foreach (var key in normalizedKeys)
- {
- if (!useRoleScope && IsUnassignedOverviewKey(key))
- {
- counts[key] = (unassignedEntries ?? new List())
- .Count(entry => MatchesTicketOverviewKey(entry, key));
- }
- else
- {
- counts[key] = entries.Count(entry => MatchesTicketOverviewKey(entry, key));
- }
- }
-
- return new TicketOverviewCountsResult { Counts = counts };
- }
- catch (Exception E)
- {
- LogException(E);
- return new TicketOverviewCountsResult();
- }
- finally
- {
- LogMethodEnd(CM);
- }
- }
-
- internal async Task getTicketOverviewCountsByRoles(
- string sid,
- IEnumerable roleGuids,
- IEnumerable keys,
- int queueoption,
- List queues)
- {
- var CM = MethodBase.GetCurrentMethod();
- LogMethodBegin(CM);
- try
- {
- var normalizedKeys = (keys ?? Array.Empty())
- .Where(k => !string.IsNullOrWhiteSpace(k))
- .Distinct(StringComparer.OrdinalIgnoreCase)
- .ToList();
-
- if (normalizedKeys.Count == 0)
- {
- normalizedKeys.AddRange(TicketOverviewKeys);
- }
-
- var roleIds = await ResolveTicketOverviewRoleIdsAsync(sid, roleGuids);
- if (roleIds.Count == 0)
- return new TicketOverviewCountsByRoleResult();
-
- var entries = await LoadTicketOverviewEntriesByRoleIds(roleIds, queueoption, queues);
- var entriesByRole = entries
- .GroupBy(entry => entry.RecipientRoleId)
- .ToDictionary(group => group.Key, group => group.ToList());
-
- var countsByRole = new Dictionary>(StringComparer.OrdinalIgnoreCase);
- foreach (var roleId in roleIds)
- {
- var roleEntries = entriesByRole.TryGetValue(roleId, out var list)
- ? list
- : new List();
-
- var counts = new Dictionary(StringComparer.OrdinalIgnoreCase);
- foreach (var key in normalizedKeys)
- {
- counts[key] = roleEntries.Count(entry => MatchesTicketOverviewKey(entry, key));
- }
-
- countsByRole[roleId.ToString()] = counts;
- }
-
- return new TicketOverviewCountsByRoleResult
- {
- GeneratedAtUtc = DateTime.UtcNow,
- CountsByRole = countsByRole
- };
- }
- catch (Exception E)
- {
- LogException(E);
- return new TicketOverviewCountsByRoleResult();
- }
- finally
- {
- LogMethodEnd(CM);
- }
- }
-
- internal async Task> getTicketOverviewRelations(
- string sid,
- string scope,
- string key,
- int count,
- int queueoption,
- List queues)
- {
- var CM = MethodBase.GetCurrentMethod();
- LogMethodBegin(CM);
- try
- {
- if (string.IsNullOrWhiteSpace(key))
- return new List();
-
- var useRoleScope = string.Equals(scope, "role", StringComparison.OrdinalIgnoreCase);
- List 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))
- .OrderByDescending(entry => entry.CreatedDate)
- .ToList();
-
- if (count > 0)
- filtered = filtered.Take(count).ToList();
-
- var relations = new List(filtered.Count);
- foreach (var entry in filtered)
- {
- var relation = new TicketOverviewRelationDto
- {
- Type = enumF4sdSearchResultClass.Ticket,
- DisplayName = entry.TicketNumber ?? string.Empty,
- Name = entry.TicketNumber ?? string.Empty,
- id = entry.TicketId,
- Status = enumF4sdSearchResultStatus.Active,
- Infos = new Dictionary
- {
- ["Summary"] = entry.Summary ?? string.Empty,
- ["StatusId"] = ConvertM42State(entry.State),
- ["ActivityType"] = entry.ActivityType ?? string.Empty,
- ["UserDisplayName"] = entry.InitiatorDisplayName ?? string.Empty,
- ["UserAccount"] = entry.InitiatorAccount ?? string.Empty,
- ["UserDomain"] = entry.InitiatorDomain ?? string.Empty,
- ["UserSid"] = entry.InitiatorSid ?? string.Empty,
- ["Sids"] = entry.InitiatorSid ?? string.Empty,
- ["UserId"] = entry.InitiatorId != Guid.Empty ? entry.InitiatorId.ToString() : string.Empty,
- ["UserGuid"] = entry.InitiatorId != Guid.Empty ? entry.InitiatorId.ToString() : string.Empty
- },
- Identities = new List
- {
- new cF4sdIdentityEntry { Class = enumFasdInformationClass.Ticket, Id = entry.TicketId },
- new cF4sdIdentityEntry { Class = enumFasdInformationClass.User, Id = entry.InitiatorId }
- }
- };
- relations.Add(relation);
- }
-
- return relations;
- }
- catch (Exception E)
- {
- LogException(E);
- return new List();
- }
- finally
- {
- LogMethodEnd(CM);
- }
- }
-
- private async Task> LoadTicketOverviewEntries(
- string sid,
- bool useRoleScope,
- int queueoption,
- List queues)
- {
- var CM = MethodBase.GetCurrentMethod();
- LogMethodBegin(CM);
- try
- {
- await Task.Delay(0);
-
- if (string.IsNullOrWhiteSpace(sid))
- return new List();
-
- var filter = await BuildTicketOverviewFilterAsync(sid, useRoleScope, queueoption, queues);
- return await LoadTicketOverviewEntriesByFilter(filter);
- }
- catch (Exception E)
- {
- LogException(E);
- return new List();
- }
- finally
- {
- LogMethodEnd(CM);
- }
- }
-
- private async Task> LoadTicketOverviewUnassignedEntriesForPersonalScope(
- string sid,
- int queueoption,
- List queues)
- {
- var CM = MethodBase.GetCurrentMethod();
- LogMethodBegin(CM);
- try
- {
- await Task.Delay(0);
-
- if (string.IsNullOrWhiteSpace(sid))
- return new List();
-
- var roleIds = await ResolveTicketOverviewRoleIdsAsync(sid, null);
- var filter = BuildTicketOverviewFilterForRoleIds(roleIds, null, queueoption, queues);
- if (string.IsNullOrWhiteSpace(filter))
- return new List();
-
- filter += " AND Recipient IS NULL";
- return await LoadTicketOverviewEntriesByFilter(filter);
- }
- catch (Exception E)
- {
- LogException(E);
- return new List();
- }
- finally
- {
- LogMethodEnd(CM);
- }
- }
-
- private async Task> LoadTicketOverviewEntriesByRoleIds(
- IEnumerable roleIds,
- int queueoption,
- List queues)
- {
- var CM = MethodBase.GetCurrentMethod();
- LogMethodBegin(CM);
- try
- {
- await Task.Delay(0);
-
- var filter = BuildTicketOverviewFilterForRoleIds(roleIds, null, queueoption, queues);
- return await LoadTicketOverviewEntriesByFilter(filter);
- }
- catch (Exception E)
- {
- LogException(E);
- return new List();
- }
- finally
- {
- LogMethodEnd(CM);
- }
- }
-
- private async Task> LoadTicketOverviewEntriesByFilter(string filter)
- {
- var CM = MethodBase.GetCurrentMethod();
- LogMethodBegin(CM);
- try
- {
- await Task.Delay(0);
-
- if (string.IsNullOrWhiteSpace(filter))
- return new List();
-
- var tbl = FragmentRequestBase.SimpleLoad(SPSActivityClassBaseID,
- "[Expression-ObjectID] as EOID" +
- ", TicketNumber" +
- ", Subject" +
- ", Initiator as InitiatorId" +
- ", Initiator.LastName + ISNULL(', ' + Initiator.FirstName, '') as Initiator" +
- ", Initiator.PrimaryAccount.T(SPSAccountClassAD).NBAccountName as InitiatorAccount" +
- ", Initiator.PrimaryAccount.T(SPSAccountClassAD).Domain.NT4Name as InitiatorDomain" +
- ", Initiator.PrimaryAccount.T(SPSAccountClassAD).Sid as InitiatorSid" +
- ", Recipient as RecipientId" +
- ", RecipientRole.T(SPSSecurityClassRole).ID as RecipientRoleId" +
- ", T(SPSCommonClassBase).State as State" +
- ", CreatedDate" +
- ", NewInformationReceived" +
- ", ReactionTimeEscalated" +
- ", SolutionTimeEscalated" +
- ", UsedInTypeSPSActivityTypeTicket as TicketEoid" +
- ", UsedInTypeSPSActivityTypeIncident as IncidentEoid" +
- ", UsedInTypeSPSActivityTypeAlert as AlertEoid" +
- ", UsedInTypeSPSActivityTypeGroupTicket as ProblemEoid" +
- ", UsedInTypeSPSActivityTypeServiceRequest as ServiceRequestEoid" +
- ", UsedInTypeSPSActivityTypeBase as TaskEoid" +
- ", UsedInTypeSVMChangeRequestType as ChangeEoid",
- filter);
-
- if (tbl?.Rows == null || tbl.Rows.Count == 0)
- return new List();
-
- var entries = new List(tbl.Rows.Count);
- foreach (DataRow row in tbl.Rows)
- {
- var ticketId = getGuidFromObject(row["EOID"]);
- if (ticketId == Guid.Empty)
- continue;
-
- var ticketEoid = getGuidFromObject(row["TicketEoid"]);
- var incidentEoid = getGuidFromObject(row["IncidentEoid"]);
- var alertEoid = getGuidFromObject(row["AlertEoid"]);
- var problemEoid = getGuidFromObject(row["ProblemEoid"]);
- var serviceRequestEoid = getGuidFromObject(row["ServiceRequestEoid"]);
- var taskEoid = getGuidFromObject(row["TaskEoid"]);
- var changeEoid = getGuidFromObject(row["ChangeEoid"]);
- var isIncident = incidentEoid != Guid.Empty;
- var activityType = ResolveTicketOverviewActivityType(
- ticketEoid,
- incidentEoid,
- alertEoid,
- problemEoid,
- serviceRequestEoid,
- taskEoid,
- changeEoid);
-
- entries.Add(new TicketOverviewEntry
- {
- TicketId = ticketId,
- TicketNumber = getStringFromObject(row["TicketNumber"]),
- Summary = getStringFromObject(row["Subject"]),
- InitiatorId = getGuidFromObject(row["InitiatorId"]),
- InitiatorDisplayName = getStringFromObject(row["Initiator"]),
- InitiatorAccount = getStringFromObject(row["InitiatorAccount"]),
- InitiatorDomain = getStringFromObject(row["InitiatorDomain"]),
- InitiatorSid = getStringFromObject(row["InitiatorSid"]),
- RecipientId = getGuidFromObject(row["RecipientId"]),
- RecipientRoleId = getGuidFromObject(row["RecipientRoleId"]),
- State = getIntFromObject(row["State"]),
- CreatedDate = getDateTimeFromObject(row["CreatedDate"]),
- NewInformationReceived = GetBoolValue(row["NewInformationReceived"]),
- ReactionTimeEscalated = GetBoolValue(row["ReactionTimeEscalated"]),
- SolutionTimeEscalated = GetBoolValue(row["SolutionTimeEscalated"]),
- IsIncident = isIncident,
- ActivityType = activityType
- });
- }
-
- return entries;
- }
- catch (Exception E)
- {
- LogException(E);
- return new List();
- }
- finally
- {
- LogMethodEnd(CM);
- }
- }
-
- private static string ResolveTicketOverviewActivityType(
- Guid ticketEoid,
- Guid incidentEoid,
- Guid alertEoid,
- Guid problemEoid,
- Guid serviceRequestEoid,
- Guid taskEoid,
- Guid changeEoid)
- {
- if (incidentEoid != Guid.Empty)
- return "SPSActivityTypeIncident";
- if (ticketEoid != Guid.Empty)
- return "SPSActivityTypeTicket";
- if (alertEoid != Guid.Empty)
- return "SPSActivityTypeAlert";
- if (problemEoid != Guid.Empty)
- return "SPSActivityTypeGroupTicket";
- if (serviceRequestEoid != Guid.Empty)
- return "SPSActivityTypeServiceRequest";
- if (taskEoid != Guid.Empty)
- return "SPSActivityTypeBase";
- if (changeEoid != Guid.Empty)
- return "SVMChangeRequestType";
-
- return null;
- }
-
- private async Task BuildTicketOverviewFilterAsync(
- string sid,
- bool useRoleScope,
- int queueoption,
- List queues)
- {
- var filter = BuildTicketOverviewBaseFilter(queueoption, queues);
-
- if (!useRoleScope)
- {
- var recipientFilter = $"Recipient.Accounts.T(SPSAccountClassAd).Sid = '{Escape(sid)}'";
- filter += $" AND ({recipientFilter})";
- return filter;
- }
-
- var roleIds = await ResolveTicketOverviewRoleIdsAsync(sid, null);
- return BuildTicketOverviewFilterForRoleIds(roleIds, filter);
- }
-
- private string BuildTicketOverviewBaseFilter(int queueoption, List queues)
- {
- var filter = "T(SPSCommonClassBase).State <> 204";
-
- if (ticketAndServiceRequestEnabled())
- {
- filter += " AND (UsedInTypeSPSActivityTypeIncident IS NOT NULL" +
- " OR UsedInTypeSPSActivityTypeTicket IS NOT NULL" +
- " OR UsedInTypeSPSActivityTypeServiceRequest IS NOT NULL)";
- }
- else
- {
- filter += " AND (UsedInTypeSPSActivityTypeIncident IS NOT NULL)";
- }
-
- filter = AppendQueueFilter(filter, queueoption, queues);
- return filter;
- }
-
- private string BuildTicketOverviewFilterForRoleIds(
- IEnumerable roleIds,
- string baseFilter = null,
- int queueoption = 0,
- List queues = null)
- {
- var filter = string.IsNullOrWhiteSpace(baseFilter)
- ? BuildTicketOverviewBaseFilter(queueoption, queues)
- : baseFilter;
-
- var roleClause = BuildRoleIdInClause(roleIds);
- if (string.IsNullOrWhiteSpace(roleClause))
- return null;
-
- filter += $" AND {roleClause}";
- return filter;
- }
-
- private static string BuildRoleIdInClause(IEnumerable roleIds)
- {
- var roleIdList = (roleIds ?? Enumerable.Empty())
- .Where(id => id != Guid.Empty)
- .Distinct()
- .Select(id => $"'{id}'")
- .ToList();
-
- if (roleIdList.Count == 0)
- return null;
-
- return $"RecipientRole.T(SPSSecurityClassRole).ID IN ({string.Join(", ", roleIdList)})";
- }
-
- private string AppendQueueFilter(string filter, int queueoption, List queues)
- {
- if (queues != null && queues.Count > 0)
- {
- var escapedNames = queues
- .Select(q => $"'{Escape(q.QueueName)}'")
- .ToList();
- var escapedIds = queues
- .Select(q => $"'{Escape(q.QueueID.ToString())}'")
- .ToList();
-
- string nameList = string.Join(", ", escapedNames);
- string idList = string.Join(", ", escapedIds);
-
- switch (queueoption)
- {
- case 1:
- filter +=
- $" AND (" +
- "Queue IS NULL" +
- $" OR Queue.Name IN ({nameList})" +
- $" OR Queue.ID IN ({idList})" +
- ")";
- break;
- case 2:
- filter +=
- $" AND (" +
- "Queue IS NOT NULL" +
- $" AND (Queue.Name IN ({nameList})" +
- $" OR Queue.ID IN ({idList}))" +
- ")";
- break;
- case 3:
- filter += " AND Queue IS NULL";
- break;
- default:
- break;
- }
- }
- else if (queueoption == 3)
- {
- filter += " AND Queue IS NULL";
- }
-
- return filter;
- }
-
- private async Task> ResolveTicketOverviewRoleIdsAsync(string sid, IEnumerable roleGuids)
- {
- var roleIds = (roleGuids ?? Enumerable.Empty())
- .Where(id => id != Guid.Empty)
- .Distinct()
- .ToList();
-
- if (roleIds.Count > 0)
- return roleIds;
-
- if (string.IsNullOrWhiteSpace(sid))
- return new List();
-
- var userId = getUserBySid(sid);
- if (userId == Guid.Empty)
- return new List();
-
- var roles = await getRoleMembershipById(userId) ?? new List();
- return roles
- .Where(role => role != null && role.Id != Guid.Empty)
- .Select(role => role.Id)
- .Distinct()
- .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 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;
-
- switch (key.Trim())
- {
- case "TicketsNew":
- return isTicket && (entry.State == 200 || entry.State == 201);
- case "TicketsActive":
- return isTicket && isActive;
- case "TicketsCritical":
- return isTicket && isCritical;
- case "TicketsNewInfo":
- return isTicket && entry.NewInformationReceived;
- case "IncidentNew":
- 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;
- }
- }
-
- private static bool GetBoolValue(object value)
- {
- if (value == null || value is DBNull)
- return false;
- if (value is bool boolValue)
- return boolValue;
- if (value is int intValue)
- return intValue != 0;
- if (value is long longValue)
- return longValue != 0;
-
- if (bool.TryParse(value.ToString(), out var parsedBool))
- return parsedBool;
- if (int.TryParse(value.ToString(), out var parsedInt))
- return parsedInt != 0;
-
- return false;
- }
-
- private static string ConvertM42State(int state)
- {
- switch (state)
- {
- case 200:
- return "New";
- case 201:
- case 202:
- return "InProgress";
- case 203:
- return "OnHold";
- case 204:
- return "Closed";
- default:
- return "Unknown";
- }
- }
- private (int, string) GetActivityState(Guid activityEOId)
- {
- var tbl3 = FragmentRequestBase.SimpleLoad(SPSCommonClassBaseID,
- "State.Value as State, State.DisplayString as StateDisp", $"[Expression-ObjectID] = '{activityEOId}'");
- if (tbl3?.Rows == null || tbl3.Rows.Count <= 0)
- {
- LogEntry($"SPSCommonClassBase fragment not found: ClassId={SPSCommonClassBaseID}, ObjectId={activityEOId}", LogLevels.Debug);
- return (0, "");
- }
- var state = getIntFromObject(tbl3.Rows[0]["State"]);
- var stateDisp = getStringFromObject(tbl3.Rows[0]["StateDisp"]);
- return (state, stateDisp);
- }
- private string Escape(string input)
- {
- return input?.Replace("'", "''");
- }
- private string GetActivityFilter(
- string userSid,
- int hours,
- bool ticketAndServiceRequestEnabled,
- int queueoption,
- List queues
- )
- {
- // Baseline-Filter auf User und Datum
- var filter = $"Initiator.Accounts.T(SPSAccountClassAd).Sid = '{Escape(userSid)}'";
-
- string fStartDate = AsqlHelper.PrepareDateTime(DateTime.UtcNow.AddHours(-hours), true);
- string fEndDate = AsqlHelper.PrepareDateTime(DateTime.UtcNow, true);
-
- // Incident vs. Ticket/ServiceRequest
- if (ticketAndServiceRequestEnabled)
- {
- filter +=
- " AND (UsedInTypeSPSActivityTypeIncident IS NOT NULL" +
- " OR UsedInTypeSPSActivityTypeTicket IS NOT NULL" +
- " OR UsedInTypeSPSActivityTypeServiceRequest IS NOT NULL)";
- }
- else
- {
- filter += " AND (UsedInTypeSPSActivityTypeIncident IS NOT NULL)";
- }
-
- // Offene bzw. kürzlich geschlossene Objekte
- filter +=
- " AND (T(SPSCommonClassBase).State <> 204" +
- $" OR (ClosedDate > {fStartDate} AND ClosedDate < {fEndDate}))";
-
- // Queue-Filter nur, wenn tatsächlich Queues übergeben wurden
- if (queues != null && queues.Count > 0)
- {
- // URL-escaping für Name und ID
- var escapedNames = queues
- .Select(q => $"'{Escape(q.QueueName)}'")
- .ToList();
- var escapedIds = queues
- .Select(q => $"'{Escape(q.QueueID.ToString())}'")
- .ToList();
-
- string nameList = string.Join(", ", escapedNames);
- string idList = string.Join(", ", escapedIds);
-
- switch (queueoption)
- {
- // 1 = entweder keine Queue oder eine der übergebenen Queues (Name oder ID)
- case 1:
- filter +=
- $" AND (" +
- "Queue IS NULL" +
- $" OR Queue.Name IN ({nameList})" +
- $" OR Queue.ID IN ({idList})" +
- ")";
- break;
-
- // 2 = nur die übergebenen Queues (Name oder ID)
- case 2:
- filter +=
- $" AND (" +
- "Queue IS NOT NULL" +
- $" AND (Queue.Name IN ({nameList})" +
- $" OR Queue.ID IN ({idList}))" +
- ")";
- break;
-
- // 3 = nur Objekte ohne Queue
- case 3:
- filter += " AND Queue IS NULL";
- break;
-
- // 0 oder andere = keine zusätzliche Einschränkung
- default:
- break;
- }
- }
- else if (queueoption == 3)
- {
- // Ausnahme: wenn keine Queues übergeben, aber Option 3 = nur ohne Queue
- filter += " AND Queue IS NULL";
- }
-
- return filter;
- }
-
-
- internal async Task getDirectLinkCreateTicket(string sid, string assetname)
- {
- var CM = MethodBase.GetCurrentMethod();
- LogMethodBegin(CM);
- try
- {
- await Task.Delay(0);
-
- // get global settings
- bool TicketAndServiceRequestEnabled = ticketAndServiceRequestEnabled();
-
- var user = getUserBySid(sid);
- var asset = getAssetByName(assetname);
- dynamic presetParamsDyn = new ExpandoObject();
-
- presetParamsDyn.SPSActivityClassBase = new ExpandoObject();
- presetParamsDyn.SPSActivityClassBase.Subject = placeHolderSubject;
- presetParamsDyn.SPSActivityClassBase.DescriptionHTML = placeHolderDescription;
- if (user != Guid.Empty)
- presetParamsDyn.SPSActivityClassBase.Initiator = user;
- if (asset != null)
- {
- presetParamsDyn.SPSActivityClassIncident = new ExpandoObject();
- presetParamsDyn.SPSActivityClassIncident.Asset = asset.Id;
- }
- var type = TicketAndServiceRequestEnabled ? "SPSActivityTypeTicket" : "SPSActivityTypeIncident";
- var presetParams = HttpUtility.UrlEncode(JsonConvert.SerializeObject(presetParamsDyn));
- var directLink = string.Format(TicketDirectLinkCreateTemplate, F4SDM42WebApiController.defaultInstance.BaseUrl, type, presetParams);
- return new DirectLink()
- {
- Link = directLink,
- DescriptionParameter = placeHolderDescription,
- SubjectParameter = placeHolderSubject
- };
- }
- catch (Exception E)
- {
- LogException(E);
- return null;
- }
- finally
- {
- LogMethodEnd(CM);
- }
- }
-
- private static bool ticketAndServiceRequestEnabled()
- {
- var configProvider = F4SDM42WebApiController.defaultInstance._globalConfigurationProvider;
-
- // using reflection because signature of "ReloadSettings" changed in ESM v12
- var method = configProvider.GetType().GetMethod("ReloadSettings");
-
- if (method != null)
- {
- var defaultParameters = method.GetParameters().Select(p => p.HasDefaultValue ? p.DefaultValue : null).ToArray();
- method.Invoke(configProvider, defaultParameters);
- }
-
- return configProvider.ServiceDeskConfiguration.TicketAndServiceRequestEnabled;
- }
-
- internal async Task> getTicketDetails(List ticketObjectIds)
- {
- var CM = MethodBase.GetCurrentMethod();
- LogMethodBegin(CM);
- try
- {
- await Task.Delay(0);
-
- var Filter = AsqlHelper.BuildInCondition("[Expression-ObjectId]", ticketObjectIds);
- LogEntry($"ASql Filter: {Filter}");
-
- var tbl = FragmentRequestBase.SimpleLoad(SPSActivityClassBaseID,
- "[Expression-ObjectId] as EOID" +
- ", TicketNumber" +
- ", Subject" +
- ", Category.Name as Category" +
- ", Category as CategoryId" +
- ", CreatedDate, ClosedDate" +
- ", Initiator as InitiatorId" +
- ", Initiator.LastName + ISNULL(', ' + Initiator.FirstName, '') as Initiator" +
- ", DescriptionHTML" +
- ", Impact" +
- ", Impact.DisplayString as ImpactDisp" +
- ", Urgency" +
- ", Urgency.DisplayString as UrgencyDisp" +
- ", Priority" +
- ", Priority.Description as PrioDisp" +
- ", SolutionHTML", Filter);
-
- if (tbl == null || tbl.Rows == null)
- {
- LogEntry($"No activity entry list found with [Expression-ObjectId]='{string.Join(", ", ticketObjectIds)}'", LogLevels.Warning);
- return null;
- }
-
- var tickets = new List();
-
- foreach (DataRow Entry in tbl.Rows)
- {
- var ActivityEOID = getGuidFromObject(Entry["EOID"]);
- if (ActivityEOID == Guid.Empty)
- {
- LogEntry($"No expression object id found for activity entry", LogLevels.Warning);
- continue;
- }
-
- var InitiatorId = getGuidFromObject(Entry["InitiatorId"]);
- var Initiator = getStringFromObject(Entry["Initiator"]);
- if (InitiatorId == Guid.Empty)
- {
- LogEntry($"No Initiator id found for activity entry", LogLevels.Warning);
- }
-
- var TicketNumber = getStringFromObject(Entry["TicketNumber"]);
- if (string.IsNullOrEmpty(TicketNumber))
- {
- LogEntry($"No TicketNumber found for activity entry", LogLevels.Warning);
- continue;
- }
-
- var CategoryId = getGuidFromObject(Entry["CategoryId"]);
- if (CategoryId == Guid.Empty)
- {
- LogEntry($"No Initiator object id found for activity entry", LogLevels.Warning);
- continue;
- }
-
- var Category = getStringFromObject(Entry["Category"]);
- if (string.IsNullOrEmpty(Category))
- {
- LogEntry($"No Category found for activity entry", LogLevels.Warning);
- continue;
- }
-
- var CreatedDate = getDateTimeFromObject(Entry["CreatedDate"]);
- if (CreatedDate == DateTime.MinValue)
- {
- LogEntry($"No CreationDate found for activity entry", LogLevels.Warning);
- continue;
- }
-
- var ClosedDate = getDateTimeFromObject(Entry["ClosedDate"]);
- var DescriptionHtml = getStringFromObject(Entry["DescriptionHTML"]);
- var Description = DescriptionHtml != string.Empty ? Matrix42.Common.Html.HtmlConverter.ConvertHtmlToPlainText(DescriptionHtml) : string.Empty;
-
- var SolutionHtml = getStringFromObject(Entry["SolutionHTML"]);
- var Solution = SolutionHtml != string.Empty ? Matrix42.Common.Html.HtmlConverter.ConvertHtmlToPlainText(SolutionHtml) : string.Empty;
-
- var Subject = getStringFromObject(Entry["Subject"]);
- if (string.IsNullOrEmpty(Subject))
- {
- LogEntry($"No Subject found for activity entry", LogLevels.Warning);
- continue;
- }
-
- var PriorityId = getIntFromObject(Entry["Priority"]);
- var Priority = getStringFromObject(Entry["PrioDisp"]);
-
- var UrgencyId = getIntFromObject(Entry["Urgency"]);
- var Urgency = getStringFromObject(Entry["UrgencyDisp"]);
-
- var ImpactId = getIntFromObject(Entry["Impact"]);
- var Impact = getStringFromObject(Entry["ImpactDisp"]);
-
- LogEntry($"get category information: {Filter}");
- Filter = string.Format("Recursive(Children).T(SPSScCategoryClassBase).Id='{0}'", CategoryId);
- var tbl1 = FragmentRequestBase.SimpleLoad(SPSScCategoryClassBaseID, "Name", Filter);
- if (tbl1?.Rows == null || tbl1.Rows.Count <= 0)
- {
- LogEntry($"No Category entry list found with Initiator='{CategoryId}'", LogLevels.Warning);
- return null;
- }
-
- var CategoryHierarchical = string.Join(" > ", tbl1.Rows.Cast().Reverse().Select(row => getStringFromObject(row["Name"])));
-
- var tbl2 = FragmentRequestBase.SimpleLoad(SPSActivityClassIncidentID, "EntryBy as EntryBy, EntryBy.DisplayString as EntryByDisp, COALESCE(AssetAffected, Asset) as Asset, COALESCE(AssetAffected.T(SPSComputerClassAD).Domain.NT4Name, Asset.T(SPSComputerClassAD).Domain.NT4Name) as AssetDomain, COALESCE(COALESCE(AssetAffected.T(SPSComputerClassBase).Name, AssetAffected.T(SPSAssetClassSIMCard).PhoneNumber, AssetAffected.Name, AssetAffected.objectid), COALESCE(Asset.T(SPSComputerClassBase).Name, Asset.T(SPSAssetClassSIMCard).PhoneNumber, Asset.Name, Asset.objectid)) as AssetName", $"[Expression-ObjectID] = '{ActivityEOID}'");
-
- if (tbl2?.Rows == null || tbl2.Rows.Count <= 0)
- {
- LogEntry($"SPSActivityClassIncident fragment not found: ClassId={SPSActivityClassIncidentID}, ObjectId={ActivityEOID}", LogLevels.Debug);
- continue;
- }
-
- var AssetId = getGuidFromObject(tbl2.Rows[0]["Asset"]);
- var Asset = getStringFromObject(tbl2.Rows[0]["AssetName"]);
- var AssetDomain = getStringFromObject(tbl2.Rows[0]["AssetDomain"]);
- var EntryBy = getIntFromObject(tbl2.Rows[0]["EntryBy"]);
- var EntryByDisp = getStringFromObject(tbl2.Rows[0]["EntryByDisp"]);
-
- M42Asset AssetObject = null;
- if (AssetId != Guid.Empty)
- AssetObject = getAssetsByAsql($"ID = '{AssetId}'").FirstOrDefault();
-
- var tbl3 = FragmentRequestBase.SimpleLoad(SPSCommonClassBaseID, "State, State.DisplayString as StateDisp, SUBQUERY(BasicSchemaObjectType AS t, t.Name, t.ID=base.TypeID) as CIName", $"[Expression-ObjectID] = '{ActivityEOID}'");
- if (tbl3?.Rows == null || tbl3.Rows.Count <= 0)
- {
- LogEntry($"SPSCommonClassBase fragment not found: ClassId={SPSCommonClassBaseID}, ObjectId={ActivityEOID}", LogLevels.Debug);
- continue;
- }
-
- var State = getIntFromObject(tbl3.Rows[0]["State"]);
- var StateDisp = getStringFromObject(tbl3.Rows[0]["StateDisp"]);
- var CIName = getStringFromObject(tbl3.Rows[0]["CIName"]);
-
- dynamic viewOptionsDyn = new ExpandoObject();
- viewOptionsDyn.objectId = ActivityEOID;
- viewOptionsDyn.type = CIName;
- viewOptionsDyn.viewType = "action";
- viewOptionsDyn.actionId = TicketCloseActionId;
- var viewOptions = HttpUtility.UrlEncode(JsonConvert.SerializeObject(viewOptionsDyn));
-
- var ticketDirectLinkPreview = string.Format(TicketDirectLinkPreviewTemplate, F4SDM42WebApiController.defaultInstance.BaseUrl, CIName, ActivityEOID);
- var ticketDirectLinkEdit = string.Format(TicketDirectLinkEditTemplate, F4SDM42WebApiController.defaultInstance.BaseUrl, CIName, ActivityEOID);
- var ticketDirectLinkClose = string.Format(IncidentDirectLinkCloseTemplate, F4SDM42WebApiController.defaultInstance.BaseUrl, ActivityEOID, viewOptions);
-
- LogEntry($"Activity found: ObjectID={ActivityEOID}, TicketNumber={TicketNumber}, Subject={Subject}, State={State}", LogLevels.Debug);
- var ticket = new cF4SDTicket()
- {
- TicketObjectId = ActivityEOID,
- Name = TicketNumber,
- CIName = CIName,
- StatusId = State,
- Status = StateDisp,
- Summary = Subject,
- AffectedUserId = InitiatorId,
- AffectedUser = Initiator,
- CreationDate = CreatedDate,
- ClosingDate = ClosedDate,
- DescriptionHtml = DescriptionHtml,
- Description = Description,
- SolutionHtml = SolutionHtml,
- Solution = Solution,
- Priority = Priority,
- PriorityId = PriorityId,
- CreationSourceId = EntryBy,
- CreationSource = EntryByDisp,
- CategoryHierarchical = CategoryHierarchical,
- CategoryId = CategoryId,
- Category = Category,
- DirectLinkPreview = ticketDirectLinkPreview,
- Urgency = Urgency,
- UrgencyId = UrgencyId,
- Impact = Impact,
- ImpactId = ImpactId
- //JournalItems = GetJournalEntriesByEOID(ActivityEOID)
- };
-
- if (AssetObject != null)
- {
- ticket.AssetId = AssetId;
- ticket.AssetName = Asset;
- ticket.AssetDomain = AssetDomain;
- ticket.AssetCIId = AssetObject.CIId;
- ticket.AssetCIName = AssetObject.CIName;
- ticket.AssetSKUAssetGroupId = AssetObject.SKUAssetGroupId;
- ticket.AssetSKUAssetGroup = AssetObject.SKUAssetGroup;
- ticket.AssetSKUTypeId = AssetObject.SKUTypeId;
- ticket.AssetSKUType = AssetObject.SKUType;
- }
-
- if (ticket.StatusId != 204)
- ticket.DirectLinkEdit = ticketDirectLinkEdit;
-
- if ((CIName.ToUpper() == "SPSACTIVITYTYPEINCIDENT" || CIName.ToUpper() == "SPSACTIVITYTYPESERVICEREQUEST") && ticket.StatusId != 204)
- ticket.DirectLinkClose = ticketDirectLinkClose;
-
- tickets.Add(ticket);
- }
-
- tickets = tickets.OrderBy(x => x.CreationDate).ToList();
- tickets.Reverse();
- return tickets;
- }
- catch (Exception E)
- {
- LogException(E);
- return null;
- }
- finally
- {
- LogMethodEnd(CM);
- }
- }
-
- internal async Task> GetJournalEntries(Guid activityEOID)
- {
- var CM = MethodBase.GetCurrentMethod();
- LogMethodBegin(CM);
- try
- {
- await Task.Delay(0);
- List journalEntries = new List();
- var entries = F4SDM42WebApiController.defaultInstance._journalService.GetJournalList(activityEOID, false, 0, 50, "{2}", 120);
- LogEntry($"{entries.Length} Journal entries found for ObjectID={activityEOID}", LogLevels.Debug);
- for (int i = 0; i < entries.Length; i++)
- {
- Matrix42.Contracts.Platform.Data.JournalEntryInfo item = entries[i];
- LogEntry($"Journal entry {i + 1}/{entries.Length}: ID={item.Id}, CreatedDate={item.CreatedDate}, CreatedBy={item.Creator}, Header={item.Header}", LogLevels.Debug);
- journalEntries.Add(new cTicketJournalItem()
- {
- JournalId = item.Id,
- ActivityObjectId = activityEOID,
- CreatedBy = item.Creator,
- CreationDate = (DateTime)item.CreatedDate,
- DescriptionHtml = item.Text,
- Description = Matrix42.Common.Html.HtmlConverter.ConvertHtmlToPlainText(item.Text),
- Header = item.Header,
- IsVisibleForUser = item.VisibleInPortal
- });
- }
- return journalEntries;
- }
- catch (Exception E)
- {
- LogException(E);
- return null;
- }
- finally
- {
- LogMethodEnd(CM);
- }
- }
-
- internal async Task updateActivitySolution(Guid objectId, string solutionHtml)
- {
-
- var CM = MethodBase.GetCurrentMethod();
- LogMethodBegin(CM);
- try
- {
- await Task.Delay(0);
- if (objectId == Guid.Empty)
- return false;
-
- var tbl = FragmentRequestBase.SimpleLoad(SPSActivityClassBaseID, "ID", $"[Expression-ObjectID] = '{objectId}'");
- if (tbl?.Rows == null || tbl.Rows.Count <= 0)
- {
- LogEntry($"SPSActivityClassBase fragment not found: ClassId={SPSActivityClassBaseID}, ObjectId={objectId}", LogLevels.Debug);
- return false;
- }
-
- var fragmentId = getGuidFromObject(tbl.Rows[0]["ID"]);
- SPSFragment activityFragment = ObjectBroker.GetFragment(SPSActivityClassBaseID, fragmentId);
- activityFragment["SolutionHTML"] = solutionHtml;
- ObjectBroker.UpdateFragment(SPSActivityClassBaseID, activityFragment);
- return true;
- }
- catch (Exception E)
- {
- LogException(E);
- return false;
- }
- finally
- {
- LogMethodEnd(CM);
- }
- }
-
- private List getAssetsByAsql(string Filter)
- {
- var CM = MethodBase.GetCurrentMethod();
- LogMethodBegin(CM);
- try
- {
- // get SPSAssetClassBase
- if (string.IsNullOrEmpty(Filter))
- return null;
- List assets = new List();
- LogEntry($"ASql Filter: {Filter}");
- var tbl = FragmentRequestBase.SimpleLoad(SPSAssetClassBaseID
- , "Id" +
- ", COALESCE(T(SPSComputerClassBase).Name, T(SPSAssetClassSIMCard).PhoneNumber, Name) as AssetName" +
- ", SUBQUERY(BasicSchemaObjectType AS t, t.Name, t.ID=base.T(SPSCommonClassBase).TypeID) as CIName" +
- ", SUBQUERY(BasicSchemaObjectType AS t, t.Id, t.ID=base.T(SPSCommonClassBase).TypeID) as CIId" +
- ", SKU.Type as SKUTypeId" +
- ", SKU.Type.DisplayString as SKUType" +
- ", SKU.Type.AssetGroup as SKUAssetGroupId" +
- ", SUBQUERY(SPSAssetPickupTypeCategory AS ag, ag.DisplayString, ag.Value=base.SKU.Type.AssetGroup) as SKUAssetGroup" +
- ", T(SPSComputerClassAD).Domain.NT4Name as DomainName" +
- ", T(SPSComputerClassAD).Sid as Sid"
- , Filter);
- if (tbl?.Rows == null || tbl.Rows.Count <= 0)
- {
- LogEntry($"SPSAssetClassBase fragment not found: ClassId={SPSActivityClassIncidentID}, Filter={Filter}", LogLevels.Debug);
- return null;
- }
- else
- {
- foreach (DataRow row in tbl.Rows)
- {
- var asset = new M42Asset()
- {
- Id = getGuidFromObject(row["Id"]),
- Name = getStringFromObject(row["AssetName"]),
- CIName = getStringFromObject(row["CIName"]),
- CIId = getGuidFromObject(row["CIId"]),
- SKUTypeId = getIntFromObject(row["SKUTypeId"]),
- SKUType = getStringFromObject(row["SKUType"]),
- SKUAssetGroupId = getIntFromObject(row["SKUAssetGroupId"]),
- SKUAssetGroup = getStringFromObject(row["SKUAssetGroup"]),
- DomainName = getStringFromObject(row["DomainName"]),
- Sid = getStringFromObject(row["Sid"]),
- };
- assets.Add(asset);
- LogEntry($"Asset found: Id={asset.Id}, Name={asset.Name}, CIName={asset.CIName}", LogLevels.Debug);
- }
- }
- return assets;
- }
- catch (Exception E)
- {
- LogException(E);
- return null;
- }
- finally
- {
- LogMethodEnd(CM);
- }
- }
-
- private M42Asset getAssetByName(string assetname)
- {
- var CM = MethodBase.GetCurrentMethod();
- LogMethodBegin(CM);
- try
- {
- // get SPSAssetClassBase
- if (string.IsNullOrEmpty(assetname))
- return null;
- var Filter = string.Format("T(SPSComputerClassBase).Name = '{0}' OR T(SPSAssetClassSIMCard).PhoneNumber = '{0}' OR Name = '{0}'", assetname);
- return getAssetsByAsql(Filter)?.First();
- }
- catch (Exception E)
- {
- LogException(E);
- return null;
- }
- finally
- {
- LogMethodEnd(CM);
- }
- }
- private Guid getUserBySid(string sid)
- {
- var CM = MethodBase.GetCurrentMethod();
- LogMethodBegin(CM);
- try
- {
- string sidPattern = @"^S-\d-\d+-(\d+-){1,14}\d+$";
- if (string.IsNullOrEmpty(sid) || !Regex.IsMatch(sid, sidPattern))
- {
- LogEntry($"Invalid or empty SID: '{sid}'", LogLevels.Warning);
- return Guid.Empty;
- }
-
- var users = getUsersByAsql(string.Format("Accounts.T(SPSAccountClassAD).Sid = '{0}' OR PrimaryAccount.T(SPSAccountClassAD).Sid = '{0}'", sid));
- return users != null ? users.First().Id : Guid.Empty;
- }
- catch (Exception E)
- {
- LogException(E);
- return Guid.Empty;
- }
- finally
- {
- LogMethodEnd(CM);
- }
- }
-
-
- private List getUsersByAsql(string asqlFilter)
- {
- var CM = MethodBase.GetCurrentMethod();
- LogMethodBegin(CM);
- try
- {
- var Persons = new List();
-
-
- LogEntry($"ASql Filter: {asqlFilter}");
-
- var tbl = FragmentRequestBase.SimpleLoad(SPSUserClassBaseID,
- "Id as Id" +
- ", [Expression-ObjectID] as UserEOID" +
- ", T(SPSCommonClassBase).State as State" +
- ", LastName + ISNULL(', ' + FirstName,'') as Name" +
- ", PreferredMailCulture.Locale as Locale" +
- ", T(SPSCommonClassBase).State.DisplayString as StateDisp",
- asqlFilter);
- if (tbl?.Rows == null || tbl.Rows.Count <= 0)
- {
- LogEntry($"no user entry list found with asql='{asqlFilter}'", LogLevels.Warning);
- return null;
- }
- foreach (DataRow Entry in tbl.Rows)
- {
- // get the id
- var UserId = getGuidFromObject(Entry["ID"]);
- if (UserId == Guid.Empty)
- {
- LogEntry($"no id found for user entry", LogLevels.Warning);
- continue;
- }
- var UserEOID = getGuidFromObject(Entry["UserEOID"]);
- if (UserEOID == Guid.Empty)
- {
- LogEntry($"no expression object id found for user entry", LogLevels.Warning);
- continue;
- }
- var Name = getStringFromObject(Entry["Name"]);
- if (string.IsNullOrEmpty(Name))
- {
- LogEntry($"no Name found for entry", LogLevels.Debug);
- }
- var Locale = getStringFromObject(Entry["Locale"]);
- if (string.IsNullOrEmpty(Locale))
- {
- LogEntry($"no locale found for entry", LogLevels.Debug);
- }
- var StateDisp = getStringFromObject(Entry["StateDisp"]);
- if (string.IsNullOrEmpty(StateDisp))
- {
- LogEntry($"no statedisp found for entry", LogLevels.Debug);
- }
-
-
-
- var State = getIntFromObject(Entry["State"]);
- LogEntry($"User found: ID={UserId}, ObjectID={UserEOID}, State={State}", LogLevels.Debug);
- if (State != 2023)
- LogEntry($"User is not active", LogLevels.Debug);
- Persons.Add(new M42User()
- {
- Id = UserId,
- ObjectId = UserEOID,
- Name = Name,
- State = State,
- Locale = Locale,
- LanguageId = new CultureInfo(Locale).LCID % 1024,
- StateDisp = StateDisp
- });
- }
- return Persons;
- }
- catch (Exception E)
- {
- LogException(E);
- return null;
- }
- finally
- {
- LogMethodEnd(CM);
- }
- }
- private List getAccountsByAsql(string asqlFilter)
- {
- var CM = MethodBase.GetCurrentMethod();
- LogMethodBegin(CM);
- try
- {
- var result = new List();
-
-
- LogEntry($"ASql Filter: {asqlFilter}");
-
- var tbl = FragmentRequestBase.SimpleLoad(SPSAccountClassBaseID,
- "Id as Id" +
- ", [Expression-ObjectID] as EOID" +
- ", T(SPSCommonClassBase).State as State" +
- ", T(SPSAccountClassAD).Sid as Sid" +
- ", T(SPSAccountClassAD).UserPrincipalName as UserPrincipalName" +
- ", Owner ",
- asqlFilter);
- if (tbl?.Rows == null || tbl.Rows.Count <= 0)
- {
- LogEntry($"no account entry list found with asql='{asqlFilter}'", LogLevels.Warning);
- return null;
- }
- foreach (DataRow Entry in tbl.Rows)
- {
- // get the id
- var Id = getGuidFromObject(Entry["ID"]);
- if (Id == Guid.Empty)
- {
- LogEntry($"no id found for entry", LogLevels.Warning);
- continue;
- }
- var EOID = getGuidFromObject(Entry["EOID"]);
- if (EOID == Guid.Empty)
- {
- LogEntry($"no expression object id found for entry", LogLevels.Warning);
- continue;
- }
- var Owner = getGuidFromObject(Entry["Owner"]);
- if (Owner == Guid.Empty)
- {
- LogEntry($"no owner found for entry", LogLevels.Warning);
- }
- var Sid = getStringFromObject(Entry["Sid"]);
- if (string.IsNullOrEmpty(Sid))
- {
- LogEntry($"no Sid found for entry", LogLevels.Debug);
- }
- var UserPrincipalName = getStringFromObject(Entry["UserPrincipalName"]);
- if (string.IsNullOrEmpty(UserPrincipalName))
- {
- LogEntry($"no UserPrincipalName found for entry", LogLevels.Debug);
- }
-
-
- var State = getIntFromObject(Entry["State"]);
- LogEntry($"Account found: ID={Id}, ObjectID={EOID}, State={State}", LogLevels.Debug);
- result.Add(new M42Account()
- {
- Id = Id,
- EOID = EOID,
- State = State,
- UserPrincipalName = UserPrincipalName,
- Sid = Sid,
- Owner = Owner
- });
- }
- return result;
- }
- catch (Exception E)
- {
- LogException(E);
- return null;
- }
- finally
- {
- LogMethodEnd(CM);
- }
- }
- internal HttpResponseMessage privGetLog(string download, int maxLines, HttpRequestMessage request, string filter)
- {
- var response = new HttpResponseMessage();
-
-
-
- if (download == "1")
- {
- var CM = MethodBase.GetCurrentMethod();
- LogMethodBegin(CM);
- try
- {
- var logger = (DefaultLogger.Manager as cLogManagerFile);
- var logFileName = logger.GetLogFileName();
- MemoryStream memoryStream = new MemoryStream();
-
- ZipArchive zipArchive = new ZipArchive(memoryStream, ZipArchiveMode.Create, leaveOpen: true);
- string[] files = Directory.GetFiles(Path.GetDirectoryName(logFileName), $"*.log");
- foreach (string fileName in files)
- {
- using (var tmpInStream = new FileStream(logFileName, FileMode.Open,
- FileAccess.Read, FileShare.ReadWrite))
- {
- ZipArchiveEntry zipArchiveEntry = zipArchive.CreateEntry(Path.GetFileName(fileName));
- using (Stream destination = zipArchiveEntry.Open())
- {
- tmpInStream.CopyTo(destination);
- }
- }
- }
- zipArchive.Dispose();
- memoryStream.Position = 0L;
- HttpResponseMessage httpResponseMessage = request.CreateResponse(HttpStatusCode.OK);
- httpResponseMessage.Content = new StreamContent(memoryStream);
- httpResponseMessage.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
- {
- FileName = Path.GetFileNameWithoutExtension(logFileName) + ".zip"
- };
- httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
-
- return httpResponseMessage;
- }
- catch (Exception E)
- {
- LogException(E);
- return null;
- }
- finally
- {
- LogMethodEnd(CM);
- }
-
- }
- else
- {
- var logger = (DefaultLogger.Manager as cLogManagerFile);
- var logFileName = logger.GetLogFileName();
- using (var inStream = new FileStream(logFileName, FileMode.Open,
- FileAccess.Read, FileShare.ReadWrite))
- {
- var lines = ReadLines(() => inStream,
- Encoding.UTF8)
- .ToList();
- var sb = new StringBuilder();
- sb.AppendLine("");
- var htmlLines = new List();
- foreach (var line in lines)
- {
- var lineSplit = line.Split('\t');
- if (string.IsNullOrEmpty(filter) || !string.IsNullOrEmpty(filter) && lineSplit.Length > 4 && filter.ToLowerInvariant().Split(',').Contains(lineSplit[3].ToLowerInvariant()))
- htmlLines.Add("| " + string.Join(" | ", lineSplit) + " |
");
- }
- if (maxLines > 0)
- htmlLines = htmlLines.Skip(Math.Max(0, htmlLines.Count() - maxLines)).ToList();
- foreach (var line in htmlLines)
- {
- sb.AppendLine(line);
- }
- sb.AppendLine("
");
-
- response.Content = new StringContent(sb.ToString());
- response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html")
- {
- CharSet = Encoding.UTF8.HeaderName
- };
- response.Content.Headers.Add("CodePage", Encoding.UTF8.CodePage.ToString());
- return response;
- }
- }
- }
-
- internal List privGetLog2()
- {
- var response = new HttpResponseMessage();
- {
- var logger = (DefaultLogger.Manager as cLogManagerFile);
- var logFileName = logger.GetLogFileName();
- using (var inStream = new FileStream(logFileName, FileMode.Open,
- FileAccess.Read, FileShare.ReadWrite))
- {
- var lines = ReadLines(() => inStream,
- Encoding.UTF8)
- .ToList();
-
- var entries = new List();
- DateTime dateValue;
- for (int i = 0; i < lines.Count; i++)
- {
- string line = lines[i];
- try
- {
- var lineSplit = line.Split('\t');
- if (lineSplit.Length >= 5)
- {
- if (string.IsNullOrEmpty(lineSplit[0]))
- {
- entries.Last().Message += Environment.NewLine + lineSplit[4];
- continue;
- }
- DateTime.TryParseExact(lineSplit[0], "yyyy-MM-dd HH:mm:ss:fffff", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateValue);
- entries.Add(new cM42LogEntry()
- {
- LineNumber = i + 1,
- date = dateValue,
- ProcessId = lineSplit[1],
- logLvl = lineSplit[3],
- Theme = lineSplit[2],
- Message = lineSplit[4],
- });
- }
- }
- catch (Exception)
- {
-
- }
- }
- return entries;
- }
- }
- }
-
- private int getIntFromObject(object o, int Default = 0)
- {
- try
- {
- if (o == null)
- return Default;
- if (o is DBNull)
- return Default;
- if (o is int @int)
- return @int;
- if (o is long int1)
- return (int)int1;
- if (int.TryParse(o.ToString(), out var r))
- return r;
- }
- catch { }
- return Default;
- }
-
- private DateTime getDateTimeFromObject(object o)
- {
- try
- {
- if (o == null)
- return DateTime.MinValue;
- if (o is DBNull)
- return DateTime.MinValue;
- if (o is DateTime @dateTime)
- return @dateTime;
- if (o is string dstr && DateTime.TryParse(o.ToString(), out var r))
- return r;
- }
- catch { }
- return DateTime.MinValue;
- }
-
- private string getStringFromObject(object o, string Default = "")
- {
- try
- {
- if (o == null)
- return Default;
- if (o is DBNull)
- return Default;
- return o.ToString();
- }
- catch { }
- return Default;
- }
-
- private Guid getGuidFromObject(object o)
- {
- try
- {
- if (o == null)
- return Guid.Empty;
- if (o is DBNull)
- return Guid.Empty;
- if (o is Guid G)
- return G;
- if (Guid.TryParse(o.ToString(), out var r))
- return r;
- }
- catch { }
- return Guid.Empty;
- }
-
- internal cM42LogEntry privGetLog2(int id)
- {
- return privGetLog2().Find(x => x.LineNumber == id);
- }
-
- internal async Task> getRoleMembershipById(Guid UserId)
- {
- var CM = MethodBase.GetCurrentMethod();
- LogMethodBegin(CM);
- var RoleMemberships = new List();
- try
- {
- await Task.Delay(0);
- var asqlFilter = string.Format("Members.Id = '{0}'", UserId.ToString());
- LogEntry($"ASql Filter: {asqlFilter}");
-
- FragmentRequestBase fragmentRequestBase = new FragmentRequestBase(SPSSecurityClassRole, ColumnSelectOption.List, "Id as Id" +
- ", Name as Name");
- fragmentRequestBase.Where = asqlFilter;
- var langExt = new FragmentRequestExtensionLanguage();
- langExt.AddCultureRequest(new CultureInfo("en"));
- fragmentRequestBase.AddExtension(langExt);
-
- using (SPSTransactionScope sPSTransactionScope = new SPSTransactionScope(SPSTransactionScopeOption.Required, new SPSTransactionOptions(IsolationLevel.ReadUncommitted)))
- {
- fragmentRequestBase.Load();
- sPSTransactionScope.Complete();
- }
-
- // if requested language is already "en" use the english table
- var tbl = fragmentRequestBase.DataSet.Tables[1];
- if (tbl?.Rows == null || tbl.Rows.Count <= 0)
- tbl = fragmentRequestBase.DataSet.Tables[0];
- if (tbl?.Rows == null || tbl.Rows.Count <= 0)
- {
- LogEntry($"no role membership found with asql='{asqlFilter}'", LogLevels.Debug);
- return RoleMemberships;
- }
- foreach (DataRow Entry in tbl.Rows)
- {
- if (Entry.Table.Columns.Contains("LCID") && (int)Entry["LCID"] != 9)
- continue;
- // get the id
- var IDColumn = Entry.Table.Columns.Contains("Owner") ? "Owner" : "ID";
- var RoleId = getGuidFromObject(Entry[IDColumn]);
- if (RoleId == Guid.Empty)
- {
- LogEntry($"no id found for role entry", LogLevels.Warning);
- continue;
- }
- var Name = getStringFromObject(Entry["Name"]);
- if (string.IsNullOrEmpty(Name))
- {
- LogEntry($"no Name found for entry", LogLevels.Debug);
- }
- LogEntry($"Role Membership found: ID={RoleId}, Name={Name}", LogLevels.Debug);
- RoleMemberships.Add(new M42Role() { Id = RoleId, Name = Name });
- }
- return RoleMemberships;
- }
- catch (Exception E)
- {
- LogException(E);
- return null;
- }
- finally
- {
- LogMethodEnd(CM);
- }
- }
-
- /*
- internal async Task> getRoleMembershipById(Guid UserId)
- {
- var CM = MethodBase.GetCurrentMethod();
- LogMethodBegin(CM);
- var RoleMemberships = new List();
- try
- {
- await Task.Delay(0);
- var asqlFilter = string.Format("Members.Id = '{0}'", UserId.ToString());
- LogEntry($"ASql Filter: {asqlFilter}");
- var tbl = FragmentRequestBase.SimpleLoad(SPSSecurityClassRole,
- "Id as Id" +
- ", Name as Name",
- asqlFilter);
- if (tbl?.Rows == null || tbl.Rows.Count <= 0)
- {
- LogEntry($"no role membership found with asql='{asqlFilter}'", LogLevels.Debug);
- return RoleMemberships;
- }
- foreach (DataRow Entry in tbl.Rows)
- {
- // get the id
- var RoleId = getGuidFromObject(Entry["ID"]);
- if (RoleId == Guid.Empty)
- {
- LogEntry($"no id found for role entry", LogLevels.Warning);
- continue;
- }
- var Name = getStringFromObject(Entry["Name"]);
- if (string.IsNullOrEmpty(Name))
- {
- LogEntry($"no Name found for entry", LogLevels.Debug);
- }
- LogEntry($"Role Membership found: ID={RoleId}, Name={Name}", LogLevels.Debug);
- RoleMemberships.Add(new M42Role() { Id = RoleId, Name = Name });
- }
- return RoleMemberships;
- }
- catch (Exception E)
- {
- LogException(E);
- return null;
- }
- finally
- {
- LogMethodEnd(CM);
- }
- }
- */
- internal async Task