common/Production/ProductionUiCordonel/Model/EOLHandler.cs
2026-04-23 17:50:07 +02:00

327 lines
13 KiB
C#

using System;
using System.Collections.Generic;
using System.Net;
using LaaPackages.Features.Cordonel.Models;
using LaaPackages.Features.Cordonel.Models.Values;
using Newtonsoft.Json;
using Xylem.Common.CommonCore.Configuration;
using Xylem.Common.Logic.SoftwareAccessHelper;
namespace Xylem.Common.Production.ProductionUiCordonel.Model
{
/// <summary>
/// Check all parameters needed as preparation for shipping.
/// </summary>
public static class EOLHandler
{
/// <summary>
/// Prepare EOL progress for new run:
/// - Delete old EOL progress,
/// - Create new EOL progress.
/// </summary>
/// <returns></returns>
/// <param name="pcbId"></param>
/// <param name="eolProgress"></param>
/// <param name="errorMessage">error message on failed access</param>
/// <remarks date="2024-Sep-05" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
public static Boolean GetNewEolProgress(String pcbId, EOLProgressModel eolProgress, out String errorMessage)
{
errorMessage = "";
if (!DeleteEolProgress(pcbId, out errorMessage))
return false;
return GetOrCreateEolProgress(pcbId, eolProgress, out errorMessage);
}
/// <summary>
/// After the POST the Sentinel can be triggered. This will check all executed EOL progress
/// steps and feeds back the result.
/// </summary>
/// <returns></returns>
/// <param name="pcbId"></param>
/// <param name="feedback"></param>
/// <param name="errorMessage">error message on failed access</param>
/// <remarks date="2024-Sep-05" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
public static Boolean TriggerSentinel(String pcbId, out Dictionary<String, String> feedback, out String errorMessage)
{
errorMessage = "";
feedback = null;
try
{
var url = ServiceUrls.EolDataForSentinelServiceUrl() + $"/Check/{pcbId}";
// ReSharper disable once UnusedVariable used for DEBUG purposes
var response = LocalWebRequest.GetRequestWithError(url, out var errorCode, 30000);
// Take the response as additional information even if the check failed
if (errorCode == (Int32)HttpStatusCode.OK)
{
return true;
}
feedback = JsonConvert.DeserializeObject<Dictionary<String, String>>(response);
}
catch (Exception ex)
{
errorMessage = ex.Message;
}
return false;
}
/// <summary>
/// POST EOL progress to DB:
/// - Check if all parameters have been set to avoid posting of failed EOL process.
/// </summary>
/// <returns></returns>
/// <param name="eolProgress"></param>
/// <param name="feedback"></param>
/// <param name="errorMessage">error message on failed access</param>
/// <remarks date="2024-Sep-05" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
public static Boolean PostEolProgress(EOLProgressModel eolProgress, out Dictionary<String, String> feedback,
out String errorMessage)
{
errorMessage = "";
feedback = null;
try
{
var url = ServiceUrls.EolDataForSentinelServiceUrl();
var response = LocalWebRequest.PostRequestAsync(url, 30000, out var statusCode, eolProgress);
if (statusCode == HttpStatusCode.OK)
{
return true;
}
feedback = JsonConvert.DeserializeObject<Dictionary<String, String>>(response);
}
catch (Exception ex)
{
errorMessage = ex.Message;
}
return false;
}
/// <summary>
/// Get the EOL progress information needed for the sentinel
/// </summary>
/// <returns></returns>
/// <param name="pcbId"></param>
/// <param name="eolProgress"></param>
/// <param name="errorMessage">error message on failed access</param>
/// <remarks date="2024-Sep-05" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
private static Boolean GetOrCreateEolProgress(String pcbId, EOLProgressModel eolProgress, out String errorMessage)
{
errorMessage = "";
try
{
var url = ServiceUrls.EolDataForSentinelServiceUrl() + pcbId;
var response = LocalWebRequest.GetRequest(url, 30000);
if (response != null)
{
var result = JsonConvert.DeserializeObject<EOLProgressModel>(response);
//ClassAccess.CopyAllProperties(eolProgress, result);
var type = typeof(EOLProgressModel);
foreach (var prop in type.GetProperties())
{
if (prop.CanWrite)
prop.SetValue(eolProgress, prop.GetValue(result, null), null);
}
return true;
}
errorMessage = "Missing Web response";
}
catch (Exception ex)
{
errorMessage = ex.Message;
}
return false;
}
/// <summary>
/// Delete the EOL progress from a preceding run as a new one is needed if this has been POSTed.
/// After the POST this is locked for further edit. The indication is the <see cref="EOLProgressModel.EOLCompleteDate"/>
/// is set to a value as this is the last step before pushing.
/// </summary>
/// <returns></returns>
/// <param name="pcbId"></param>
/// <param name="errorMessage">error message on failed access</param>
/// <remarks date="2024-Sep-05" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
private static Boolean DeleteEolProgress(String pcbId, out String errorMessage)
{
errorMessage = "";
try
{
var url = ServiceUrls.EolDataForSentinelServiceUrl() + pcbId;
var msg = LocalWebRequest.DeleteRequestWithError(url, out var errorCode, 30000);
if (errorCode == (Int32)HttpStatusCode.OK)
return true;
errorMessage = msg;
}
catch (Exception ex)
{
errorMessage = ex.Message;
}
return false;
}
/// <summary>
/// Check if all EOL progresses are
/// - Executed (!= null),
/// - Succeeded (EOLStatus.OK) or
/// - Skipped (EOLStatus.NA).
/// - Ignore fields set by the sentinel after test!
/// Excluded:
/// - SAPExportDone,
/// - SentinelCompleted,
/// - SentinelCompletedDate,
/// - SpecialRequirementId,
/// - SpecialRequirementVersion.
/// </summary>
/// <returns>false if any process failed or is not executed</returns>
/// <param name="eolProgress"></param>
/// <param name="errorMessage"></param>
/// <remarks date="2024-Sep-05..10" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
/// <remarks date="2024-Dec-18" author="Thomas Wiedebusch">
/// - Accepted null for SpecialId and SpecialVersion.
/// </remarks>
public static Boolean AcknowledgeAllEolProgresses(EOLProgressModel eolProgress, out String errorMessage)
{
errorMessage = "";
var retVal = true;
try
{
var type = typeof(EOLProgressModel);
foreach (var prop in type.GetProperties())
{
// Will be changed by the sentinel
if (prop.Name.Equals("SAPExportDone") ||
prop.Name.Equals("SentinelCompleted") ||
prop.Name.Equals("SentinelCompletedDate") ||
// Set to NULL if standard requirement active
prop.Name.Equals("SpecialRequirementId") ||
prop.Name.Equals("SpecialRequirementVersion"))
continue;
if (prop.GetValue(eolProgress) == null)
{
errorMessage += $"{prop.Name} ";
retVal = false;
}
if (prop.PropertyType == typeof(String) &&
string.IsNullOrEmpty((String)prop.GetValue(eolProgress)))
{
errorMessage += $"{prop.Name} ";
retVal = false;
}
if (prop.PropertyType == typeof(Int32) && (Int32)prop.GetValue(eolProgress) == 0)
{
errorMessage += $"{prop.Name} ";
retVal = false;
}
if (prop.PropertyType == typeof(EOLStatus) &&
(EOLStatus)prop.GetValue(eolProgress) == EOLStatus.FAIL)
{
errorMessage += $"{prop.Name} ";
retVal = false;
}
}
return retVal;
}
catch (Exception ex)
{
errorMessage += $"{ex.Message}";
}
return false;
}
/// <summary>
/// Compare two EOL progresses are equal, ignore fields set by the sentinel after test!
/// Excluded:
/// - SAPExportDone,
/// - SentinelCompleted,
/// - SentinelCompletedDate,
/// - ProductionStatusDrainedBatteryLoad,
/// - ProductionStatusRemainingLifeTime,
/// - EOLSoftwareNameAndVersion.
/// </summary>
/// <returns>false if any process is unequal</returns>
/// <param name="eolProgress1"></param>
/// <param name="eolProgress2"></param>
/// <param name="errorMessage"></param>
/// <remarks date="2024-Dec-09" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
public static Boolean CompareEolProgresses(EOLProgressModel eolProgress1, EOLProgressModel eolProgress2,
out String errorMessage)
{
errorMessage = "";
try
{
var type = typeof(EOLProgressModel);
foreach (var prop in type.GetProperties())
{
// Will be changed by the sentinel
if (prop.Name.Equals("SAPExportDone") ||
prop.Name.Equals("SentinelCompleted") ||
prop.Name.Equals("SentinelCompletedDate") ||
// Cannot be compared
prop.Name.Equals("ProductionStatusDrainedBatteryLoad") ||
prop.Name.Equals("ProductionStatusRemainingLifeTime") ||
prop.Name.Equals("EOLSoftwareNameAndVersion"))
continue;
// If booth values are equal, even if null, this is okay
if (prop.GetValue(eolProgress1) == null && prop.GetValue(eolProgress2) == null)
{
continue;
}
if (prop.PropertyType == typeof(String) &&
string.IsNullOrEmpty((String)prop.GetValue(eolProgress1)) &&
string.IsNullOrEmpty((String)prop.GetValue(eolProgress2)))
{
continue;
}
if ((prop.GetValue(eolProgress1) != null && prop.GetValue(eolProgress2) == null) ||
(prop.GetValue(eolProgress1) == null && prop.GetValue(eolProgress2) != null))
{
return false;
}
if (prop.GetValue(eolProgress1) != null && prop.GetValue(eolProgress2) != null)
{
if (prop.GetValue(eolProgress1).Equals(prop.GetValue(eolProgress2)))
{
continue;
}
return false;
}
}
return true;
}
catch (Exception ex)
{
errorMessage += $"{ex.Message}";
}
return false;
}
}
}