From 1acf7ad560ffc9fc485d622ecea8801aa180b60b Mon Sep 17 00:00:00 2001 From: Stoyan Zlatev Date: Thu, 6 Mar 2025 13:09:40 +0100 Subject: [PATCH] latest changes --- Common/CommonConsole/CommonConsole.csproj | 12 +- Common/CommonConsole/Program.cs | 51 ++++++ Common/PendingEmails/Program.cs | 30 ++-- .../CordonelDbContext.cs | 2 +- .../Interfaces/IRepository[T].cs | 2 - .../Interfaces/IRequirementsRepository[T].cs | 2 + .../ISpecialRequirementsRepository[T].cs | 2 + .../IStandardRequirementRepository[T].cs | 2 + .../Repositories/RequirementsRepository.cs | 151 +++++++++++++++++- .../SpecialRequirementsRepository.cs | 41 +++++ .../StandardRequirementsRepository.cs | 35 +++- .../API/Cordonel/RequirementsController.cs | 7 +- LaaProductionWeb/LaaProductionWeb/web.config | 4 + 13 files changed, 318 insertions(+), 23 deletions(-) diff --git a/Common/CommonConsole/CommonConsole.csproj b/Common/CommonConsole/CommonConsole.csproj index b754bbe4..55fbe779 100644 --- a/Common/CommonConsole/CommonConsole.csproj +++ b/Common/CommonConsole/CommonConsole.csproj @@ -60,6 +60,14 @@ + + {8de8e742-ee0a-4004-aa49-3d08d748e5ac} + Common.Hardware.SIRT + + + {4e8bb839-d40a-488c-88ce-f21811f1f476} + Common.Hardware.WaterMeter.eRegister + {f013a56b-7be6-4852-9cd8-b971cd1add0c} GenesisConfig @@ -72,10 +80,6 @@ {f4aaf7e6-7333-4284-b735-e32deb076c64} Registers - - {8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB} - LaaPackages.Features.Cordonel - {F69A79FA-548D-4E21-887E-01FABDAD9E73} Stichproben diff --git a/Common/CommonConsole/Program.cs b/Common/CommonConsole/Program.cs index 5cb6671b..27c4f327 100644 --- a/Common/CommonConsole/Program.cs +++ b/Common/CommonConsole/Program.cs @@ -1,10 +1,61 @@ namespace CommonConsole { + using Common.Hardware.SIRT; + using Common.Hardware.SIRT.Parameters; + using Common.Hardware.WaterMeter.eRegister.Features; + + using System; + public static class Program { public static void Main() { + var sirtBroadcaster = new SIRTBroadcaster("COM8"); + sirtBroadcaster.Logging += Console.WriteLine; + sirtBroadcaster.Activated += () => + { + sirtBroadcaster.EnqueueTask(new SIRTTask(868) + { + RequestAddress = 4291709253, + P1 = new P811 + { + DelPamSemi = true, + }, + Cmd = SIRTMessage.W_PAM, + Data = new OpticalTelegram + { + Minutes = 0 + } + .Append(new ProvidePin + { + AuthLevel = AuthLevel.III + }) + .ToByteArray() + }); + sirtBroadcaster.EnqueueTask(new SIRTTask(868) + { + RequestAddress = 4291762210, + P1 = new P811 + { + DelPamSemi = true, + }, + Cmd = SIRTMessage.W_PAM, + Data = new OpticalTelegram + { + Minutes = 0 + } + .Append(new ProvidePin + { + AuthLevel = AuthLevel.III + }) + .ToByteArray() + }); + }; + sirtBroadcaster.Open(); + Console.ReadKey(); + + sirtBroadcaster.Close(); } } } \ No newline at end of file diff --git a/Common/PendingEmails/Program.cs b/Common/PendingEmails/Program.cs index dd22f25e..f935bd2c 100644 --- a/Common/PendingEmails/Program.cs +++ b/Common/PendingEmails/Program.cs @@ -107,7 +107,7 @@ LogToFile($"Inserted: {command.ExecuteNonQuery()}"); } - var updated = new HashSet(); + var updated = new Dictionary(); var countAll = 0; using (var command = connection.CreateCommand()) @@ -127,6 +127,8 @@ { while (reader.Read()) { + var messageId = reader.GetValue(5); + try { var email = new MailMessage(); @@ -147,16 +149,16 @@ .ToList() .ForEach(email.CC.Add); - var messageId = reader.GetValue(5); - if (SendEmail(email)) { - updated.Add(messageId); + updated[messageId] = "Sent"; } } catch (Exception e) { LogToFile(e); + + updated[messageId] = e.ToString(); } countAll++; @@ -172,14 +174,22 @@ { LogToFile($"updating: {string.Join(", ", updated)}"); - using (var command = connection.CreateCommand()) + foreach (var kvp in updated) { - command.CommandText = $@" - UPDATE [Messages] - SET [OutDate] = GETDATE() - WHERE [Id] IN ({string.Join(", ", updated)})"; + using (var command = connection.CreateCommand()) + { + command.CommandText = $@" + UPDATE [Messages] + SET [OutDate] = GETDATE() + , [State] = ISNULL([State], '') + ISNULL(@{nameof(kvp.Value)}, '') + WHERE [Id] = @{nameof(kvp.Key)}"; + command.Parameters.Add(new SqlParameter(nameof(kvp.Key), kvp.Key)); + command.Parameters.Add(new SqlParameter(nameof(kvp.Value), kvp.Value)); + command.ExecuteNonQuery(); + command.Parameters.Clear(); + } - command.ExecuteNonQuery(); + updatedCount++; } Console.WriteLine($"{updatedCount}/{countAll} email{(updatedCount == 1 ? null : "s")} sent."); diff --git a/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/CordonelDbContext.cs b/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/CordonelDbContext.cs index 0f680402..2ca39451 100644 --- a/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/CordonelDbContext.cs +++ b/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/CordonelDbContext.cs @@ -166,7 +166,7 @@ => this.EOLProgress.Read(pcbId); internal virtual CordonelRequirements GetRequirements(int pcbId) - => this.Requirements.FindByPcbId(pcbId.ToString()); + => this.Requirements.FindByPcbIdFull(pcbId.ToString(), out _); internal virtual IEnumerable GetLatestRegistersWithValues(int pcbId) => this.SqlConnection diff --git a/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Interfaces/IRepository[T].cs b/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Interfaces/IRepository[T].cs index 0657e881..01c6504b 100644 --- a/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Interfaces/IRepository[T].cs +++ b/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Interfaces/IRepository[T].cs @@ -1,7 +1,5 @@ namespace LaaProduction.Data.Cordonel.Interfaces { - using System; - public interface IRepository : IRepositoryEnumerable { T Add(T model); diff --git a/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Interfaces/IRequirementsRepository[T].cs b/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Interfaces/IRequirementsRepository[T].cs index 71e6922e..700636e3 100644 --- a/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Interfaces/IRequirementsRepository[T].cs +++ b/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Interfaces/IRequirementsRepository[T].cs @@ -6,6 +6,8 @@ { T FindByPcbId(string pcbid); + T FindByPcbIdFull(string pcbid, out string error); + T FindByPoNo(string pono); } } diff --git a/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Interfaces/ISpecialRequirementsRepository[T].cs b/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Interfaces/ISpecialRequirementsRepository[T].cs index fb9b9d1f..a0f261a9 100644 --- a/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Interfaces/ISpecialRequirementsRepository[T].cs +++ b/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Interfaces/ISpecialRequirementsRepository[T].cs @@ -16,6 +16,8 @@ T FirstOrDefaultByPO(string ponr); + T FindFirstOrDefault(int standardId, int pono, int? pcbId); + void Unapprove(int id); } } diff --git a/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Interfaces/IStandardRequirementRepository[T].cs b/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Interfaces/IStandardRequirementRepository[T].cs index 70bb7112..8e95e3f1 100644 --- a/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Interfaces/IStandardRequirementRepository[T].cs +++ b/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Interfaces/IStandardRequirementRepository[T].cs @@ -12,6 +12,8 @@ IEnumerable Filter(StandardRequiremetnsFilter filter); + T FirstOrDefaultByKey(string key); + T FirstOrDefaultByPO(string ponr); void Unapprove(int id); diff --git a/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Repositories/RequirementsRepository.cs b/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Repositories/RequirementsRepository.cs index acb9328f..332acb5e 100644 --- a/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Repositories/RequirementsRepository.cs +++ b/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Repositories/RequirementsRepository.cs @@ -56,17 +56,158 @@ FROM Cordonel_Requirements AS cr JOIN AlleAuftragPositionen AS aap ON cr.IdentNr = aap.IdentNr - AND (cr.PoNr = aap.FertigungsauftragNr OR cr.PoNr IS NULL) JOIN AuftragPositionSerienNr AS aps ON aap.AuftragNr = aps.AuftragNr AND aap.PositionNr = aps.PositionNr JOIN MapPcbIdToSerialNumber AS map ON aps.SerienNr = map.MapPcbIdToSerialNumber_SerialNumber + WHERE map.MapPcbIdToSerialNumber_PcbId = @{nameof(pcbid)} + AND (cr.PoNr = aap.FertigungsauftragNr OR cr.PoNr IS NULL) AND (cr.PcbId = map.MapPcbIdToSerialNumber_PcbId OR cr.PcbId IS NULL) - WHERE map.MapPcbIdToSerialNumber_PcbId = @{nameof(pcbid)}") + ORDER BY cr.StandardId DESC + , cr.SpecialId DESC") .SetParameter(nameof(pcbid), pcbid) .FirstOrDefault(this.ParseCordonelRequirements); + public CordonelRequirements FindByPcbIdFull(string pcbid, out string error) + { + error = default(string); + + var requirements = default(CordonelRequirements); + var pono = default(int?); + var pcb = default(int?); + + this.sqlConnection + .CreateCommand($@" + SELECT DISTINCT + cap.CordonelAssignedPicking_FertigungsAuftragsNr + , map.MapPcbIdToSerialNumber_PcbId + FROM Cordonel_AssignedPicking AS cap + JOIN MapPcbIdToSerialNumber AS map + ON cap.CordonelAssignedPicking_PcbId = map.MapPcbIdToSerialNumber_PcbId + WHERE cap.CordonelAssignedPicking_PcbId = @{nameof(pcbid)}") + .SetParameter(nameof(pcbid), pcbid) + .FirstOrDefault(x => + { + pono = x.GetValue(0); + pcb = x.GetValue(1); + }); + + if (pono is null) + { + error = $"Fertigungsauftragnr nicht gefunden für pcbId: {pcbid}"; + } + else if (pcb is null) + { + error = $"PcbId: {pcbid} nicht gefunden"; + } + + var identnr = default(int?); + var menge = default(int?); + var key = default(string); + + this.sqlConnection + .CreateCommand($@" + SELECT aap.IdentNr + , aap.Menge + , SUBSTRING(idn.VakoCode, 4, 2) + FROM AlleAuftragPositionen AS aap + JOIN Identnr AS idn + ON aap.IdentNr = idn.IdentNr + WHERE aap.FertigungsauftragNr = @{nameof(pono)}") + .SetParameter(nameof(pono), pono) + .FirstOrDefault(x => + { + identnr = x.GetValue(0); + menge = x.GetValue(1); + key = x.GetValue(2); + }); + + if (identnr is null) + { + error = $"Identnr nicht gefunden für Fertigungsauftragnr: {pono}"; + + return requirements; + } + else if (menge is null) + { + error = $"Menge ist ungültig für Fertigungsauftragnr: {pono}"; + + return requirements; + } + else if (key is null) + { + error = $"Region-Size key ist ungültig für Fertigungsauftragnr: {pono}"; + + return requirements; + } + + var standardRequirement = this.dbContext.StandardRequirements.FirstOrDefaultByKey(key); + + if (standardRequirement is null) + { + error = $"Standardvreigabe für Size-Region: {key} nicht gefunden"; + + return requirements; + } + else if (!standardRequirement.IsActive) + { + error = $"Standardvreigabe {standardRequirement.Id}.{standardRequirement.Version} nicht active"; + + return requirements; + } + else if (standardRequirement.ApprovedDate is null) + { + error = $"Standardvreigabe {standardRequirement.Id}.{standardRequirement.Version} nicht genehmigt"; + + return requirements; + } + + var specialRequirement = this.dbContext.SpecialRequirements.FindFirstOrDefault(standardRequirement.Id, pono.Value, pcb); + + if (specialRequirement?.ApprovedDate is null) + { + specialRequirement = default(CordonelSpecialRequirement); + } + + requirements = new CordonelRequirements + { + ApprovalComment = specialRequirement?.Comment ?? standardRequirement?.Comment, + ApprovalName = specialRequirement?.ApprovedBy ?? standardRequirement?.ApprovedBy, + EstimatedProductionBatteryLoadPercent = specialRequirement?.EstimatedProductionBatteryLoadPercent ?? standardRequirement?.EstimatedProductionBatteryLoadPercent, + FwVersion = specialRequirement?.FwVersion ?? standardRequirement?.FwVersion, + IsSpecialApproved = specialRequirement?.ApprovedDate != null, + IsSpecialActive = specialRequirement?.IsActive ?? default(bool?), + IsStandardActive = standardRequirement?.IsActive, + IsStandardApproved = standardRequirement?.ApprovedDate != null, + LutCrc = specialRequirement?.LutCrc ?? standardRequirement?.LutCrc, + MaxDrainedBatteryLoadPercentAssembly = specialRequirement?.MaxDrainedBatteryLoadPercentAssembly ?? standardRequirement?.MaxDrainedBatteryLoadPercentAssembly, + MaxDrainedBatteryLoadPercentShipping = specialRequirement?.MaxDrainedBatteryLoadPercentShipping ?? standardRequirement?.MaxDrainedBatteryLoadPercentShipping, + MaxStorageMonths = menge < 5 + ? specialRequirement?.MaxStorageMonths ?? standardRequirement?.MaxStorageMonths + : specialRequirement?.MaxStorageMonthsBigOrders ?? standardRequirement?.MaxStorageMonthsBigOrders, + MeterSize = specialRequirement?.MeterSize ?? standardRequirement?.MeterSize, + OuterPcbId = pcb, + OuterProductionOrderNr = pono, + PcbId = specialRequirement?.PcbId, + ProductionOrderNr = specialRequirement?.ProductionOrderNr, + QuiescentCurrent_uA = specialRequirement?.QuiescentCurrent_uA ?? standardRequirement?.QuiescentCurrent_uA, + Region = specialRequirement?.Region ?? standardRequirement?.Region, + RegionSizeKey = key, + RequiredLifeTimeYearsAssembly = specialRequirement?.RequiredLifeTimeYearsAssembly ?? standardRequirement?.RequiredLifeTimeYearsAssembly, + RequiredLifeTimeYearsShipping = specialRequirement?.RequiredLifeTimeYearsShipping ?? standardRequirement?.RequiredLifeTimeYearsShipping, + RequirementTimestamp = specialRequirement?.Timestamp ?? standardRequirement?.Timestamp, + SkipCalibration = specialRequirement?.SkipCalibration ?? standardRequirement?.SkipCalibration ?? false, + SkipRadioCheck = specialRequirement?.SkipRadioCheck ?? standardRequirement?.SkipRadioCheck ?? false, + SpecialId = specialRequirement?.Id, + SpecialVersion = specialRequirement?.Version, + StandardId = standardRequirement?.Id, + StandardVersion = standardRequirement?.Version, + }; + + return requirements; + } + public CordonelRequirements FindByPoNo(string pono) => this.sqlConnection .CreateCommand($@" @@ -106,14 +247,16 @@ FROM Cordonel_Requirements AS cr JOIN AlleAuftragPositionen AS aap ON cr.IdentNr = aap.IdentNr - AND (cr.PoNr = aap.FertigungsauftragNr OR cr.PoNr IS NULL) JOIN AuftragPositionSerienNr AS aps ON aap.AuftragNr = aps.AuftragNr AND aap.PositionNr = aps.PositionNr JOIN MapPcbIdToSerialNumber AS map ON aps.SerienNr = map.MapPcbIdToSerialNumber_SerialNumber + WHERE aap.FertigungsauftragNr = @{nameof(pono)} + AND (cr.PoNr = aap.FertigungsauftragNr OR cr.PoNr IS NULL) AND (cr.PcbId = map.MapPcbIdToSerialNumber_PcbId OR cr.PcbId IS NULL) - WHERE aap.FertigungsauftragNr = @{nameof(pono)}") + ORDER BY cr.StandardId DESC + , cr.SpecialId DESC") .SetParameter(nameof(pono), pono) .FirstOrDefault(this.ParseCordonelRequirements); diff --git a/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Repositories/SpecialRequirementsRepository.cs b/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Repositories/SpecialRequirementsRepository.cs index 48387cf4..412d05af 100644 --- a/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Repositories/SpecialRequirementsRepository.cs +++ b/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Repositories/SpecialRequirementsRepository.cs @@ -402,6 +402,47 @@ return requirement; } + public CordonelSpecialRequirement FindFirstOrDefault(int standardId, int pono, int? pcbId) + => this.sqlConnection + .CreateCommand($@" + SELECT [Special].[Id] + , [Special].[Version] + , [Special].[StandardId] + , [Special].[StandardVersion] + , NULL + , NULL + , NULL + , [Special].[ProductionOrderNo] + , [Special].[PcbId] + , [Special].[FwVersion] + , [Special].[LutCrc] + , [Special].[SkipCalibration] + , [Special].[SkipRadioCheck] + , [Special].[RequiredLifeTimeYearsAssembly] + , [Special].[RequiredLifeTimeYearsShipping] + , [Special].[MaxDrainedBatteryLoadPercentAssembly] + , [Special].[MaxDrainedBatteryLoadPercentShipping] + , [Special].[MaxStorageMonths] + , [Special].[MaxStorageMonthsBigOrders] + , [Special].[QuiescentCurrent_uA] + , [Special].[EstimatedProductionBatteryLoadPercent] + , [Special].[Timestamp] + , [Special].[CreatedBy] + , [Special].[ApprovedBy] + , [Special].[ApprovedDate] + , [Special].[Comment] + , [Special].[IsActive] + , NULL + FROM [Cordonel_Special_Requirements] AS [Special] + WHERE [Special].[StandardId] = @{nameof(standardId)} + AND [Special].[ProductionOrderNo] = @{nameof(pono)} + AND ([Special].[PcbId] = @{nameof(pcbId)} OR [Special].[PcbId] IS NULL) + ORDER BY [Special].[Version] DESC") + .SetParameter(nameof(standardId), standardId) + .SetParameter(nameof(pono), pono) + .SetParameter(nameof(pcbId), pcbId) + .FirstOrDefault(this.ParseSpecialRequirement); + public CordonelSpecialRequirement FirstOrDefaultByPO(string ponr) { var id = default(int?); diff --git a/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Repositories/StandardRequirementsRepository.cs b/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Repositories/StandardRequirementsRepository.cs index 3357c43b..4b8bcc07 100644 --- a/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Repositories/StandardRequirementsRepository.cs +++ b/LaaProductionWeb/Data/LaaProduction.Data.Cordonel/Repositories/StandardRequirementsRepository.cs @@ -8,7 +8,6 @@ using System.Collections; using System.Collections.Generic; using System.IO; - using System.Linq; using System.Xml.Serialization; public class StandardRequirementsRepository : IStandardRequirementRepository @@ -428,5 +427,39 @@ .CreateCommand(query) .ExecuteReader(this.ParseStandardRequirement); } + + public CordonelStandardRequirement FirstOrDefaultByKey(string key) + => this.sqlConnection + .CreateCommand($@" + SELECT TOP 1 + [STD].[Id] + , [STD].[Version] + , [STD].[Key] + , [STD].[Region] + , [STD].[ProductGroup] + , [STD].[MeterSize] + , [STD].[FwVersion] + , [STD].[LutCrc] + , [STD].[SkipCalibration] + , [STD].[SkipRadioCheck] + , [STD].[RequiredLifeTimeYearsAssembly] + , [STD].[RequiredLifeTimeYearsShipping] + , [STD].[MaxDrainedBatteryLoadPercentAssembly] + , [STD].[MaxDrainedBatteryLoadPercentShipping] + , [STD].[MaxStorageMonths] + , [STD].[MaxStorageMonthsBigOrders] + , [STD].[QuiescentCurrent_uA] + , [STD].[EstimatedProductionBatteryLoadPercent] + , [STD].[Timestamp] + , [STD].[CreatedBy] + , [STD].[ApprovedBy] + , [STD].[ApprovedDate] + , [STD].[Comment] + , [STD].[IsActive] + FROM [Cordonel_Standard_Requirements] AS [STD] + WHERE [STD].[Key] = @{nameof(key)} + ORDER BY [STD].[Version] DESC") + .SetParameter(nameof(key), key) + .FirstOrDefault(this.ParseStandardRequirement); } } diff --git a/LaaProductionWeb/LaaProductionWeb/API/Cordonel/RequirementsController.cs b/LaaProductionWeb/LaaProductionWeb/API/Cordonel/RequirementsController.cs index d115a48e..b07e77c9 100644 --- a/LaaProductionWeb/LaaProductionWeb/API/Cordonel/RequirementsController.cs +++ b/LaaProductionWeb/LaaProductionWeb/API/Cordonel/RequirementsController.cs @@ -21,7 +21,12 @@ [Route("pcbid/{pcbid}")] public IHttpActionResult PCBID(string pcbid) { - var requirement = this.cordonels.Requirements.FindByPcbId(pcbid); + var requirement = this.cordonels.Requirements.FindByPcbIdFull(pcbid, out string error); + + if (!string.IsNullOrWhiteSpace(error)) + { + return this.BadRequest(error); + } return this.Json(requirement, new JsonSerializerSettings { diff --git a/LaaProductionWeb/LaaProductionWeb/web.config b/LaaProductionWeb/LaaProductionWeb/web.config index f61b323b..445643d8 100644 --- a/LaaProductionWeb/LaaProductionWeb/web.config +++ b/LaaProductionWeb/LaaProductionWeb/web.config @@ -2,7 +2,11 @@ + + + +