using DataPROWin7.DataModel.Classes.Hardware; using DTS.Common.Classes.Groups.ChannelSettings; using DTS.Common.Import.Enums; using DTS.Common.Interface.Channels; using DTS.Common.Interface.Groups.GroupList; using DTS.Common.SharedResource.Strings; using DTS.Common.Storage; using System; using System.Collections.Generic; using System.Linq; namespace DTS.Common.Import.Persist { public class SaveGroups : SaveVariantBase { public bool CanCurrentUserCommitChannelCodes { get; set; } = true; public IChannelSetting DefaultZeroMethod { get; set; } public IChannelSetting DefaultZeroStart { get; set; } public IChannelSetting DefaultZeroEnd { get; set; } public IChannelSetting DefaultInitialOffset { get; set; } public Dictionary OldGroupIdToNewGroupId { get; set; } = new Dictionary(); private readonly SaveHardware _saveHardware; public SaveGroups(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, SaveHardware saveHardware, Func isCancelled = null) : base(importObject, persistCalculator, importNotification, isCancelled) { _saveHardware = saveHardware; } private static void SetGroupId(IGroup group) { var hResult = DbOperations.GroupsGet(null, group.Name, null, null, null, out var dbGroups); if (0 == hResult && null != dbGroups && dbGroups.Any()) { foreach (var groupRecord in dbGroups) { group.Id = groupRecord.Id; } } } /// /// if HardwareStringList is present, go and use that to look up the DASIds, which is what we actually want /// ... I'm not sure why groups has a HardwareListString other than import convenience which seems like a poor reason /// /// private static void FixGroupHardware(IGroup group, IReadOnlyDictionary idToDASId) { var includedDASIds = new List(); foreach (var str in group.IncludedHardwareStringList.Where(str => idToDASId.ContainsKey(str))) { var id = idToDASId[str]; if (!includedDASIds.Contains(id)) { includedDASIds.Add(id); } } //this is just for safety purposes, we want to avoid wiping out IncludedHardware if we have values //for it already foreach (var hid in group.IncludedHardware) { if (!includedDASIds.Contains(hid)) { includedDASIds.Add(hid); } } group.SetIncludedHardware(includedDASIds.ToArray()); } public override void Save() { _importNotification.SetStatus.Invoke(new ImportStatus { ExtraStatus = ImportExtraStatus.ReadingGroups, PossibleStatus = PossibleStatus.Importing }); //build a lookup of old id scheme to new var allHardware = DASHardwareList.GetAllHardware(); var idToDASId = new Dictionary(); foreach (var h in allHardware) { idToDASId[h.GetHardware().SerialNumber] = h.DASId; } var channelDefaults = DbOperations.GetChannelSettingDefaults(); DefaultZeroMethod = (from defaults in channelDefaults where defaults.SettingName == ChannelSettingBase.ZEROMETHOD select defaults).First(); DefaultZeroStart = (from defaults in channelDefaults where defaults.SettingName == ChannelSettingBase.ZEROMETHODSTART select defaults).First(); DefaultZeroEnd = (from defaults in channelDefaults where defaults.SettingName == ChannelSettingBase.ZEROMETHODEND select defaults).First(); DefaultInitialOffset = (from defaults in channelDefaults where defaults.SettingName == ChannelSettingBase.INITIAL_OFFSET select defaults).First(); var missingDASGroupList = new List(); var allSensorsInDb = SensorDB.SensorsCollection.SensorsList.GetAllSensors(true); foreach (var g in _importObject.StaticGroups()) { if (IsCancelled()) { return; } if (!g.Embedded) { foreach (var ch in g.GroupChannelList) { var oldSensorDatabaseIdToNew = _importObject.OldSensorDatabaseIdsToNew(); if (oldSensorDatabaseIdToNew.ContainsKey(ch.SensorId)) { ch.SensorId = oldSensorDatabaseIdToNew[ch.SensorId]; var match = Array.Find(allSensorsInDb, s => s.DatabaseId == ch.SensorId); if (null != match) { ch.SetSensorData(match, null, false); } } if (_saveHardware.OldDASIdToNewDASId.ContainsKey(ch.DASId)) { ch.DASId = _saveHardware.OldDASIdToNewDASId[ch.DASId]; } else { //19045 If a Channel in a Group in an export has a DASId that doesn't //match any DAS in the export, set it as it should have been exported (-1). ch.DASId = -1; if (!missingDASGroupList.Contains(g.DisplayName)) { missingDASGroupList.Add(g.DisplayName); } } //15262 Absolute zero sensors in test setup change to ave over time after import. //zero method may not be populated on older imports //make sure we fix this in the static group before it's commited SaveSensor.FixMissingZeroMethodParameter(ch, DefaultZeroMethod, DefaultZeroStart, DefaultZeroEnd); SaveSensor.FixMissingInitialOffset(ch, DefaultInitialOffset); } //Save off the normalized static Group Id var normalizedStaticGroupId = g.Id; SetGroupId(g); //fix the hardware for the group! FixGroupHardware(g, idToDASId); g.Save(g.GroupChannelList.ToArray(), CanCurrentUserCommitChannelCodes); //Map the normalized static Group Id to the new Id OldGroupIdToNewGroupId[normalizedStaticGroupId] = g.Id; } _persistCalculator.AddDone(); _importNotification.SetProgress(_persistCalculator.ProgressValue); } if (missingDASGroupList.Any()) { _importObject.AddError(new ImportError { Message = $"{StringResources.GroupsHadChannelsAssignedToUnknownDAS} {string.Join(", ", missingDASGroupList.ToArray())}", ContinueImportOnError = true, Severity = ImportSeverityError.Warning }); } } } }