using System.Collections.Generic; using DTS.Common.Interface.Groups.GroupList; using DTS.SensorDB; using DTS.Common.Interface.Sensors; using DTS.Common.Interface.Channels; using System.Linq; using System.Windows; using System.Threading; using System; using DTS.Common.Interface.DataRecorders; using DTS.Common.Storage; using Prism.Ioc; using DTS.Common.ISO; using DTS.Common.Utils; using DTS.Common.Utilities.Logging; using DTS.Common.Enums.DBExport; using System.Text; using Unity; namespace DataPROWin7.DataModel.Classes { public static class ExportTestSetup { public static void PrepareForExport(DataModel.TestTemplate t, Dictionary includedTests, Dictionary includedGroups, Dictionary includedDAS, Dictionary includedSensors, HashSet sensorsAlreadyAdded, Dictionary includedSensorModels, Dictionary includedCalibration, Dictionary includedCustomerDetails, Dictionary includedTestEngineerDetails, Dictionary includedLabDetails, bool savingRunningTest, // ReSharper disable once InconsistentNaming bool savingTTSImport ) { if (!includedTests.ContainsKey(t.Name)) { includedTests[t.Name] = t; } if (!string.IsNullOrWhiteSpace(t.CustomerDetails?.Name)) { includedCustomerDetails[t.CustomerDetails.Name] = t.CustomerDetails.GetISOCustomer(); } if (!string.IsNullOrWhiteSpace(t.TestEngineerDetails?.Name)) { includedTestEngineerDetails[t.TestEngineerDetails.Name] = t.TestEngineerDetails.GetISOTestEngineer(); } if (!string.IsNullOrWhiteSpace(t.LabDetails?.Name)) { includedLabDetails[t.LabDetails.Name] = t.LabDetails.GetIsoLab(); } var groups = new List(t.Groups); var sensorLookup = new Dictionary(); var sensors = SensorsCollection.SensorsList.GetAllSensors(false); foreach (var s in sensors) { sensorLookup[s.DatabaseId] = s; } var hardwareList = GetHardware(); var dasList = DTS.Common.ISO.Hardware.GetAllDAS(); foreach (var embeddedGroup in groups) { //Find the channels in this embedded Group so the Sensors will be included var groupChannelList = new List(); foreach (var groupChannelsList in t.ChannelsForGroup) //make this a linq statement? { if (groupChannelsList.Key == embeddedGroup) { groupChannelList = groupChannelsList.Value.ToList(); } } foreach (var groupChannel in groupChannelList) { if (!string.IsNullOrWhiteSpace(groupChannel.Sensor)) { var sd = SensorsCollection.SensorsList.GetOriginalSensorBySensorDatabaseId( groupChannel.SensorId); var scs = SensorCalibration.GetCalibrationsBySerialNumber(sd); if (null != sd && null != scs && scs.Length > 0) { if (!sensorsAlreadyAdded.Contains(sd.DatabaseId)) { if (!sd.IsTestSpecificDigitalOutput && !sd.IsTestSpecificSquib && !sd.IsTestSpecificDigitalIn) { includedCalibration.Add(sd.SerialNumber, scs); } includedSensors.Add(sd.SerialNumber, sd); sensorsAlreadyAdded.Add(sd.DatabaseId); } } } foreach (var dasId in embeddedGroup.IncludedHardware) { var h = GetDAS(hardwareList, dasId, dasList); if (!includedDAS.ContainsKey(h.SerialNumber)) { includedDAS.Add(h.SerialNumber, new DataModel.DASHardware(h)); } } } //If there's a non-imbedded (static) Group in the db, process it too. IGroup nonEmbeddedGroup = null; if (embeddedGroup.StaticGroupId != null) { if (System.Windows.Application.Current.Dispatcher.CheckAccess()) { nonEmbeddedGroup = GetNonEmbeddedGroup(embeddedGroup.StaticGroupId); } else { ManualResetEvent manualResetEvent = new ManualResetEvent(false); Application.Current.Dispatcher.BeginInvoke(new Action(() => { nonEmbeddedGroup = GetNonEmbeddedGroup(embeddedGroup.StaticGroupId); manualResetEvent.Set(); })); manualResetEvent.WaitOne(); } } if (nonEmbeddedGroup == null || nonEmbeddedGroup.Id != embeddedGroup.StaticGroupId) { //We can get here if the static Group was created from a static Group which was later deleted, //but the embedded Group didn't have its StaticGroupId set to null (also fixed in this patch, //but pre-existing embedded Groups in the database could be pointing to a non-existent record) embeddedGroup.StaticGroupId = null; continue; } var hardwareLookup = new Dictionary(); using (var enumHardware = includedDAS.GetEnumerator()) { while (enumHardware.MoveNext()) { hardwareLookup[enumHardware.Current.Value.DASId] = enumHardware.Current.Value; } } var channelDefaults = DbOperations.GetChannelSettingDefaults(); var groupChannelArray = nonEmbeddedGroup.GetAllChannels(false, sensorLookup, hardwareLookup, channelDefaults); foreach (var groupChannel in groupChannelArray) { nonEmbeddedGroup.GroupChannelList.Add(groupChannel); nonEmbeddedGroup.ChannelCount++; } var channels = t.ChannelsForGroup[embeddedGroup]; foreach (var groupChannel in channels) { if (!string.IsNullOrWhiteSpace(groupChannel.Sensor)) { var sd = SensorsCollection.SensorsList.GetOriginalSensorBySensorDatabaseId(groupChannel.SensorId); var scs = SensorCalibration.GetCalibrationsBySerialNumber(sd); if (null != sd && null != scs && scs.Length > 0) { if (!sensorsAlreadyAdded.Contains(sd.DatabaseId)) { if (!sd.IsTestSpecificSquib && !sd.IsTestSpecificDigitalOutput && !sd.IsTestSpecificDigitalIn) { includedCalibration.Add(sd.SerialNumber, scs); } includedSensors.Add(sd.SerialNumber, sd); sensorsAlreadyAdded.Add(sd.DatabaseId); } } } foreach (var dasId in nonEmbeddedGroup.IncludedHardware) { var h = GetDAS(hardwareList, dasId, dasList); if (!includedDAS.ContainsKey(h.SerialNumber)) { includedDAS.Add(h.SerialNumber, new DataModel.DASHardware(h)); } } } //Only add static Groups to includedGroups if (!includedGroups.ContainsKey(nonEmbeddedGroup.Name)) { includedGroups.Add(nonEmbeddedGroup.Name, nonEmbeddedGroup); } } foreach (var group in t.Groups) { var channels = t.ChannelsForGroup[group]; foreach (var ch in channels) { if (ch.IsBlank()) { continue; } if (ch.SensorId > 0) { var sd = SensorsCollection.SensorsList.GetOriginalSensorBySensorDatabaseId(ch.SensorId); if (!includedSensors.ContainsKey(sd.SerialNumber)) { if (!sensorsAlreadyAdded.Contains(sd.DatabaseId)) { includedSensors.Add(sd.SerialNumber, sd); if (!sd.IsTestSpecificDigitalOutput && !sd.IsTestSpecificSquib && !sd.IsTestSpecificDigitalIn) { var scs = SensorCalibration.GetCalibrationsBySerialNumber(sd); includedCalibration.Add(sd.SerialNumber, scs); var sm = SensorModelCollection.SensorModelList.GetSensorModel(sd.Manufacturer, sd.Model); if (null == sm) { continue; } var key = $"{sm.Manufacturer}x_x{sm.Model}"; if (!includedSensorModels.ContainsKey(key)) { includedSensorModels.Add(key, sm); } } sensorsAlreadyAdded.Add(sd.DatabaseId); } } } } } var hardware = t.GetHardware(); foreach (var h in hardware) { if (!includedDAS.ContainsKey(h.SerialNumber)) { includedDAS.Add(h.SerialNumber, h); } } if (!savingTTSImport) return; var allSensors = SensorsCollection.SensorsList.GetAllSensors(true); foreach (var sd in allSensors) { if (includedSensors.ContainsKey(sd.SerialNumber)) continue; var scs = SensorCalibration.GetCalibrationsBySerialNumber(sd); if (null != scs && scs.Length > 0) { includedCalibration.Add(sd.SerialNumber, scs); includedSensors.Add(sd.SerialNumber, sd); var sm = SensorModelCollection.SensorModelList.GetSensorModel(sd.Manufacturer, sd.Model); if (null == sm) continue; var key = $"{sm.Manufacturer}x_x{sm.Model}"; if (!includedSensorModels.ContainsKey(key)) { includedSensorModels.Add(key, sm); } } else { System.Diagnostics.Trace.WriteLine("calibration record is null"); } } } public static string ExportToFile(Dictionary includedTests, Dictionary includedGroups, Dictionary includedDAS, Dictionary includedSensors, Dictionary includedSensorModels, Dictionary includedCalibration, Dictionary includedCustomerDetails, Dictionary includedTestEngineerDetails, Dictionary includedLabDetails, Dictionary includedUsers, Dictionary includedGlobalSettings, string exportFile, string originalImportFile, bool bUseFirstUseDate = true) { double totalStepsToComplete = includedCalibration.Count + includedDAS.Count + includedGroups.Count + +includedSensorModels.Count + includedSensors.Count + includedTests.Count + includedLabDetails.Count + includedCustomerDetails.Count + includedTestEngineerDetails.Count + includedUsers.Count + includedGlobalSettings.Count; double done = 0; var writer = FileUtils.GetExportWriter(Convert.ToInt32(totalStepsToComplete), FileUtils.CurrentXmlVersion, System.Reflection.Assembly.GetEntryAssembly().GetName().Name, System.Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString(4), APILogger.Log, out var sb); try { writer.WriteAttributeString("OriginalImportFile", originalImportFile); var fields = Enum.GetValues(typeof(TopLevelFields)).Cast().ToArray(); foreach (var f in fields) { switch (f) { case TopLevelFields.Calibrations: if (includedCalibration.Count > 0) { writer.WriteStartElement(f.ToString()); foreach (var c in includedCalibration) { foreach (var sc in c.Value) { writer.Flush(); sc.WriteXML(ref writer); writer.Flush(); } done++; } writer.WriteEndElement(); } break; case TopLevelFields.CustomChannels: break; case TopLevelFields.DASList: if (includedDAS.Count > 0) { writer.WriteStartElement(f.ToString()); foreach (var h in includedDAS) { writer.Flush(); h.Value.WriteXML(ref writer); writer.Flush(); done++; } writer.WriteEndElement(); } break; case TopLevelFields.Groups: if (includedGroups.Count > 0) { writer.WriteStartElement(f.ToString()); foreach (var g in includedGroups) { writer.Flush(); g.Value.WriteXML(ref writer); writer.Flush(); done++; } writer.WriteEndElement(); } break; case TopLevelFields.GroupTemplates: break; case TopLevelFields.SensorModels: if (includedSensorModels.Count > 0) { writer.WriteStartElement(f.ToString()); foreach (var sm in includedSensorModels) { writer.Flush(); sm.Value.WriteXML(ref writer); writer.Flush(); done++; } writer.WriteEndElement(); } break; case TopLevelFields.Sensors: if (includedSensors.Count > 0) { writer.Flush(); writer.WriteStartElement(f.ToString()); foreach (var sd in includedSensors) { writer.Flush(); sd.Value.WriteXML(ref writer, bUseFirstUseDate); writer.Flush(); done++; } writer.WriteEndElement(); } break; case TopLevelFields.TestSetups: if (includedTests.Count > 0) { writer.WriteStartElement(f.ToString()); foreach (var t in includedTests) { writer.Flush(); t.Value.WriteXML(ref writer); writer.Flush(); done++; } writer.WriteEndElement(); } break; case TopLevelFields.CustomerDetails: if (includedCustomerDetails.Count > 0) { writer.WriteStartElement(f.ToString()); foreach (var c in includedCustomerDetails) { writer.Flush(); c.Value.WriteXML(ref writer); writer.Flush(); done++; } writer.WriteEndElement(); } break; case TopLevelFields.Users: if (includedUsers.Count > 0) { writer.WriteStartElement(f.ToString()); foreach (var user in includedUsers) { writer.Flush(); user.Value.WriteXML(ref writer); writer.Flush(); done++; } writer.WriteEndElement(); } break; case TopLevelFields.TestEngineerDetails: if (includedTestEngineerDetails.Count > 0) { writer.WriteStartElement(f.ToString()); foreach (var c in includedTestEngineerDetails) { writer.Flush(); c.Value.WriteXML(ref writer); writer.Flush(); done++; } writer.WriteEndElement(); } break; case TopLevelFields.LabDetails: if (includedLabDetails.Count > 0) { writer.WriteStartElement(f.ToString()); foreach (var ld in includedLabDetails) { writer.Flush(); ld.Value.WriteXML(ref writer); writer.Flush(); done++; } writer.WriteEndElement(); } break; case TopLevelFields.CustomDirections: case TopLevelFields.CustomFilterClasses: case TopLevelFields.CustomFinLoc1s: case TopLevelFields.CustomFinLoc2s: case TopLevelFields.CustomFinLoc3s: case TopLevelFields.CustomMainLocs: case TopLevelFields.CustomTestObjects: case TopLevelFields.CustomPhysicalDimensions: case TopLevelFields.CustomPositions: break; case TopLevelFields.GlobalSettings: { if (includedGlobalSettings.Any()) { writer.WriteStartElement(f.ToString()); foreach (var setting in includedGlobalSettings) { writer.Flush(); WriteGlobalSetting(setting.Key, setting.Value, ref writer); writer.Flush(); } writer.WriteEndElement(); } } break; case TopLevelFields.SensorChangeHistory: break; default: throw new NotSupportedException("ExportTestSetup::ExportFunc unknown element: " + f); } } writer.WriteEndElement();//exportdocument writer.WriteEndDocument(); writer.Flush(); writer.Close(); if (null != exportFile) { System.IO.File.WriteAllText(exportFile, sb.ToString(), Encoding.Unicode); } return sb.ToString(); } catch (Exception ex) { APILogger.Log(ex); return string.Empty; } } private static IGroup GetNonEmbeddedGroup(int? embeddedGroupStaticGroupId) { var unityContainer = ContainerLocator.Container.Resolve(); var vm = unityContainer.Resolve(); var g = vm.GetGroup(embeddedGroupStaticGroupId); return g; } private static List GetHardware() { var hardwareList = new List(); var hResult = DbOperations.DASGet(null, null, out var dbDAS); if (0 == hResult) { foreach (var das in dbDAS) { hardwareList.Add(new DTS.Common.ISO.Hardware(das)); } } return hardwareList; } private static DTS.Common.ISO.Hardware GetDAS(List hardwareList, int hardwareId, DTS.Common.ISO.Hardware[] dasList) { var dasSerialNumber = GetHardwareSerialNumber(hardwareList, hardwareId); foreach (var das in dasList) { if (das.SerialNumber == dasSerialNumber) { return das; } } return null; } private static string GetHardwareSerialNumber(List hardwareList, int hId) { foreach (var hardware in hardwareList) { if (hardware.DASId == hId) { return hardware.SerialNumber; } } return string.Empty; } private static void WriteGlobalSetting(string key, string value, ref System.Xml.XmlWriter writer) { writer.WriteStartElement("Setting"); writer.WriteStartElement("SettingName"); writer.WriteString(key); writer.WriteEndElement(); writer.WriteStartElement("SettingValue"); writer.WriteString(value); writer.WriteEndElement(); writer.WriteEndElement(); } public static void PrepareForExportFields(DataModel.TestTemplate t, Dictionary includedTests, Dictionary includedDAS ) { if (!includedTests.ContainsKey(t.Name)) { includedTests[t.Name] = t; } var groups = new List(t.Groups); var sensorLookup = new Dictionary(); var sensors = SensorsCollection.SensorsList.GetAllSensors(false); foreach (var s in sensors) { sensorLookup[s.DatabaseId] = s; } var hardwareList = GetHardware(); var dasList = DTS.Common.ISO.Hardware.GetAllDAS(); foreach (var embeddedGroup in groups) { //Find the channels in this embedded Group so the Sensors will be included var groupChannelList = new List(); foreach (var groupChannelsList in t.ChannelsForGroup) //make this a linq statement? { if (groupChannelsList.Key == embeddedGroup) { groupChannelList = groupChannelsList.Value.ToList(); } } foreach (var groupChannel in groupChannelList) { foreach (var dasId in embeddedGroup.IncludedHardware) { var h = GetDAS(hardwareList, dasId, dasList); if (!includedDAS.ContainsKey(h.SerialNumber)) { includedDAS.Add(h.SerialNumber, new DataModel.DASHardware(h)); } } } //If there's a non-imbedded (static) Group in the db, process it too. IGroup nonEmbeddedGroup = null; if (embeddedGroup.StaticGroupId != null) { if (Application.Current.Dispatcher.CheckAccess()) { nonEmbeddedGroup = GetNonEmbeddedGroup(embeddedGroup.StaticGroupId); } else { ManualResetEvent manualResetEvent = new ManualResetEvent(false); Application.Current.Dispatcher.BeginInvoke(new Action(() => { nonEmbeddedGroup = GetNonEmbeddedGroup(embeddedGroup.StaticGroupId); manualResetEvent.Set(); })); manualResetEvent.WaitOne(); } } if (nonEmbeddedGroup == null || nonEmbeddedGroup.Id != embeddedGroup.StaticGroupId) { //We can get here if the static Group was created from a static Group which was later deleted, //but the embedded Group didn't have its StaticGroupId set to null (also fixed in this patch, //but pre-existing embedded Groups in the database could be pointing to a non-existent record) embeddedGroup.StaticGroupId = null; continue; } var hardwareLookup = new Dictionary(); using (var enumHardware = includedDAS.GetEnumerator()) { while (enumHardware.MoveNext()) { hardwareLookup[enumHardware.Current.Value.DASId] = enumHardware.Current.Value; } } var channelDefaults = DbOperations.GetChannelSettingDefaults(); var groupChannelArray = nonEmbeddedGroup.GetAllChannels(false, sensorLookup, hardwareLookup, channelDefaults); foreach (var groupChannel in groupChannelArray) { nonEmbeddedGroup.GroupChannelList.Add(groupChannel); nonEmbeddedGroup.ChannelCount++; } var channels = t.ChannelsForGroup[embeddedGroup]; foreach (var groupChannel in channels) { foreach (var dasId in nonEmbeddedGroup.IncludedHardware) { var h = GetDAS(hardwareList, dasId, dasList); if (!includedDAS.ContainsKey(h.SerialNumber)) { includedDAS.Add(h.SerialNumber, new DataModel.DASHardware(h)); } } } } var hardware = t.GetHardware(); foreach (var h in hardware) { if (!includedDAS.ContainsKey(h.SerialNumber)) { includedDAS.Add(h.SerialNumber, h); } } foreach (var h in hardwareList) { if (includedDAS.ContainsKey(h.SerialNumber)) continue; if (t.DASSampleRateList.ContainsKey(h.SerialNumber)) { t.DASSampleRateList.Remove(h.SerialNumber); } } } public static string ExportToFileFields(Dictionary includedTests, Dictionary includedDAS, string originalImportFile) { double totalStepsToComplete = includedDAS.Count + includedTests.Count; double done = 0; var writer = FileUtils.GetExportWriter(Convert.ToInt32(totalStepsToComplete), FileUtils.CurrentXmlVersion, System.Reflection.Assembly.GetEntryAssembly().GetName().Name, System.Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString(4), APILogger.Log, out var sb); try { writer.WriteAttributeString("OriginalImportFile", originalImportFile); var fields = Enum.GetValues(typeof(TopLevelFields)).Cast().ToArray(); foreach (var f in fields) { switch (f) { case TopLevelFields.DASList: if (includedDAS.Count > 0) { writer.WriteStartElement(f.ToString()); foreach (var h in includedDAS) { writer.Flush(); h.Value.WriteXML(ref writer); writer.Flush(); done++; } writer.WriteEndElement(); } break; case TopLevelFields.TestSetups: if (includedTests.Count > 0) { writer.WriteStartElement(f.ToString()); foreach (var t in includedTests) { writer.Flush(); t.Value.WriteXML(ref writer); writer.Flush(); done++; } writer.WriteEndElement(); } break; case TopLevelFields.CustomerDetails: case TopLevelFields.Users: case TopLevelFields.Calibrations: case TopLevelFields.CustomChannels: case TopLevelFields.Groups: case TopLevelFields.GroupTemplates: case TopLevelFields.SensorModels: case TopLevelFields.Sensors: case TopLevelFields.TestEngineerDetails: case TopLevelFields.LabDetails: case TopLevelFields.CustomDirections: case TopLevelFields.CustomFilterClasses: case TopLevelFields.CustomFinLoc1s: case TopLevelFields.CustomFinLoc2s: case TopLevelFields.CustomFinLoc3s: case TopLevelFields.CustomMainLocs: case TopLevelFields.CustomTestObjects: case TopLevelFields.CustomPhysicalDimensions: case TopLevelFields.CustomPositions: case TopLevelFields.GlobalSettings: case TopLevelFields.SensorChangeHistory: break; default: throw new NotSupportedException("ExportTestSetup::ExportFunc unknown element: " + f); } } writer.WriteEndElement();//exportdocument writer.WriteEndDocument(); writer.Flush(); writer.Close(); return sb.ToString(); } catch (Exception ex) { APILogger.Log(ex); return string.Empty; } } } }