diff --git a/ENI2/App.xaml.cs b/ENI2/App.xaml.cs index c64a3b6e..b2ca4b37 100644 --- a/ENI2/App.xaml.cs +++ b/ENI2/App.xaml.cs @@ -82,6 +82,9 @@ namespace ENI2 LADG.CargoCodesNST = LocalizedLookup.getCargoCodesNST(); LADG.CargoCodesNST3 = LocalizedLookup.getCargoCodesNST3(); + // Load import value mappings + ValueMapping.LoadDicts(); + // Preload validation fields List vFields = bsmd.database.ValidationRule.ValidationFields; RuleEngine.RegisterLocodeChecker(Util.GlobalStructures.IsValidLocode); diff --git a/ENI2/Controls/ValueMappingsControl.xaml.cs b/ENI2/Controls/ValueMappingsControl.xaml.cs index 7d657f9f..aadb69f1 100644 --- a/ENI2/Controls/ValueMappingsControl.xaml.cs +++ b/ENI2/Controls/ValueMappingsControl.xaml.cs @@ -48,7 +48,7 @@ namespace ENI2.Controls MenuItem delItem = new MenuItem { - Header = Properties.Resources.textAdd, + Header = Properties.Resources.textDelete, Icon = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/Resources/delete.png")) } }; diff --git a/ENI2/Excel/ExcelUtil.cs b/ENI2/Excel/ExcelUtil.cs index a64f6895..6f8d88b0 100644 --- a/ENI2/Excel/ExcelUtil.cs +++ b/ENI2/Excel/ExcelUtil.cs @@ -15,17 +15,18 @@ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; +using System.Threading.Tasks; namespace ENI2.Excel { public static class ExcelUtil { + + #region fields + private static readonly ILog _log = LogManager.GetLogger(typeof(ExcelUtil)); - private static readonly Dictionary _countryImportDict = new Dictionary(); - private static readonly Dictionary _genderImportDict = new Dictionary(); - private static readonly Dictionary _documentTypeImportDict = new Dictionary(); - private static readonly Dictionary _locodeImportDict = new Dictionary(); + #endregion #region Process Sheet (normal BSMD sheet import) @@ -1340,8 +1341,7 @@ namespace ENI2.Excel wr.WasteCode.Equals("204") || wr.WasteCode.Equals("510") || wr.WasteCode.Equals("511")) wr.WasteDescription = "-"; } - wr.AmountWasteReceived_MTQ = reader.ReadNumber(wAmount); - if (!wr.AmountWasteReceived_MTQ.HasValue) wr.AmountWasteReceived_MTQ = 0; // Default ist 0, nicht nix ;-) + wr.AmountWasteReceived_MTQ = reader.ReadNumber(wAmount) ?? (double?)0; // Default ist 0, nicht nix ;-) } // only add message when an identification number was given @@ -2226,9 +2226,7 @@ namespace ENI2.Excel if (canceled) return true; if (crewd.CrewMemberIdentityDocumentIssuingState.IsNullOrEmpty()) crewd.CrewMemberIdentityDocumentIssuingState = "XX"; - crewd.CrewMemberIdentityDocumentExpiryDate = reader.ReadCellAsDateTime(sheetTitle, string.Format("N{0}", i + 18)); - if (!crewd.CrewMemberIdentityDocumentExpiryDate.HasValue) - crewd.CrewMemberIdentityDocumentExpiryDate = new DateTime(2100, 12, 31); + crewd.CrewMemberIdentityDocumentExpiryDate = reader.ReadCellAsDateTime(sheetTitle, string.Format("N{0}", i + 18)) ?? (DateTime?)new DateTime(2100, 12, 31); crewd.Effects = reader.ReadCellAsText("2. PORT", string.Format("C{0}", i + 142)); @@ -2333,7 +2331,7 @@ namespace ENI2.Excel pas.PassengerInTransit = reader.ReadCellAsBool(sheetTitle, string.Format("H{0}", i + 17)); pas.PassengerPlaceOfBirth = reader.ReadCellAsText(sheetTitle, string.Format("J{0}", i + 17)); - pas.PassengerCountryOfBirth = reader.ReadCellAsText(sheetTitle, string.Format("K{0}", i + 17)); + pas.PassengerCountryOfBirth = ReadNationality(reader.ReadCellAsText(sheetTitle, string.Format("K{0}", i + 17)), out canceled); if (canceled) return true; DateTime? dateOfBirth = reader.ReadCellAsDateTime(sheetTitle, string.Format("L{0}", i + 17)); @@ -2343,9 +2341,7 @@ namespace ENI2.Excel if (canceled) return true; pas.PassengerIdentityDocumentId = reader.ReadCellAsText(sheetTitle, string.Format("N{0}", i + 17)); - pas.PassengerIdentityDocumentExpiryDate = reader.ReadCellAsDateTime(sheetTitle, string.Format("P{0}", i + 17)); - if (!pas.PassengerIdentityDocumentExpiryDate.HasValue) - pas.PassengerIdentityDocumentExpiryDate = new DateTime(2100, 12, 31); + pas.PassengerIdentityDocumentExpiryDate = reader.ReadCellAsDateTime(sheetTitle, string.Format("P{0}", i + 17)) ?? (DateTime?)new DateTime(2100, 12, 31); pas.PassengerVisaNumber = reader.ReadCellAsText(sheetTitle, string.Format("Q{0}", i + 17)); pas.EmergencyCare = reader.ReadCellAsText(sheetTitle, string.Format("R{0}", i + 17)); @@ -2475,9 +2471,7 @@ namespace ENI2.Excel pas.PassengerIdentityDocumentId = reader.ReadText(pasIdentDocId); pas.PassengerVisaNumber = reader.ReadText(pasVisaNo); pas.PassengerIdentityDocumentIssuingState = reader.ReadNationality(pasIssuing); - pas.PassengerIdentityDocumentExpiryDate = reader.ReadDate(pasExpiryDate); - if (!pas.PassengerIdentityDocumentExpiryDate.HasValue) - pas.PassengerIdentityDocumentExpiryDate = new DateTime(2100, 12, 31); + pas.PassengerIdentityDocumentExpiryDate = reader.ReadDate(pasExpiryDate) ?? (DateTime?)new DateTime(2100, 12, 31); pas.PassengerCountryOfBirth = reader.ReadNationality(pasCountryOfBirth); pas.EmergencyCare = reader.ReadText(pasEmergencyCare); pas.EmergencyContactNumber = reader.ReadText(pasEmergencyContact); @@ -2590,8 +2584,6 @@ namespace ENI2.Excel #endregion LookupMessageCore - - #region GetMessageWithType private static Message GetMessageWithType(List messages, MessageCore core, Message.NotificationClass type) @@ -2623,9 +2615,9 @@ namespace ENI2.Excel if (!gender.IsNullOrEmpty() && !result.HasValue) { // special treatment / callback - if (_genderImportDict.ContainsKey(gender)) + if (ValueMapping.Dicts[ValueMapping.MappingType.GENDER].ContainsKey(gender)) { - result = byte.Parse(_genderImportDict[gender]); // we have mapped this before + result = byte.Parse(ValueMapping.Dicts[ValueMapping.MappingType.GENDER][gender].Value); // we have mapped this before } else { @@ -2637,8 +2629,14 @@ namespace ENI2.Excel { if (!fid.SelectedValue.IsNullOrEmpty()) { - _genderImportDict[gender] = fid.SelectedValue; - result = byte.Parse(_genderImportDict[gender]); + if (!ValueMapping.InvalidKeys[ValueMapping.MappingType.GENDER].Contains(gender)) + { + string selectedValue = fid.SelectedValue; + Task createResult = Task.Run(async () => await ValueMapping.Create(ValueMapping.MappingType.GENDER, gender, selectedValue)); + if (!createResult.Result) + _log.WarnFormat("Error saving gender value mapping {0} -> {1}", gender, selectedValue); + } + result = byte.Parse(fid.SelectedValue); } } else @@ -2669,9 +2667,9 @@ namespace ENI2.Excel else { // special treatment / callback - if (_documentTypeImportDict.ContainsKey(documentType)) + if (ValueMapping.Dicts[ValueMapping.MappingType.DOCUMENT_TYPE].ContainsKey(documentType)) { - result = byte.Parse(_documentTypeImportDict[documentType]); // we have mapped this before + result = byte.Parse(ValueMapping.Dicts[ValueMapping.MappingType.DOCUMENT_TYPE][documentType].Value); // we have mapped this before } else { @@ -2683,8 +2681,14 @@ namespace ENI2.Excel { if (!fid.SelectedValue.IsNullOrEmpty()) { - _documentTypeImportDict[documentType] = fid.SelectedValue; - result = byte.Parse(_documentTypeImportDict[documentType]); + if(!ValueMapping.InvalidKeys[ValueMapping.MappingType.DOCUMENT_TYPE].Contains(documentType)) + { + string selectedValue = fid.SelectedValue; + Task createResult = Task.Run(async () => await ValueMapping.Create(ValueMapping.MappingType.DOCUMENT_TYPE, documentType, selectedValue)); + if (!createResult.Result) + _log.WarnFormat("Error saving document type value mapping {0} -> {1}", documentType, selectedValue); + } + result = byte.Parse(fid.SelectedValue); } } else @@ -2715,9 +2719,9 @@ namespace ENI2.Excel { result = CREW.NationalityDict.FirstOrDefault(x => x.Value.Substring(3).Equals(nationality, StringComparison.OrdinalIgnoreCase)).Key; } - else if (_countryImportDict.ContainsKey(nationality)) + else if (ValueMapping.Dicts[ValueMapping.MappingType.COUNTRY].ContainsKey(nationality)) { - result = _countryImportDict[nationality]; + result = ValueMapping.Dicts[ValueMapping.MappingType.COUNTRY][nationality].Value; } else // we cannot find whatever this is.. { @@ -2729,7 +2733,13 @@ namespace ENI2.Excel { if (!fid.SelectedValue.IsNullOrEmpty()) { - _countryImportDict[nationality] = fid.SelectedValue; + if(!ValueMapping.InvalidKeys[ValueMapping.MappingType.COUNTRY].Contains(nationality)) + { + string selectedValue = fid.SelectedValue; + Task createResult = Task.Run(async () => await ValueMapping.Create(ValueMapping.MappingType.COUNTRY, nationality, selectedValue)); + if(!createResult.Result) + _log.WarnFormat("Error saving nationality value mapping {0} -> {1}", nationality, selectedValue); + } result = fid.SelectedValue.Substring(0, 2); // attention manual entry } } @@ -2762,7 +2772,7 @@ namespace ENI2.Excel if (possibleLocodes.Count > 1) { - if (!_locodeImportDict.ContainsKey(val)) + if (!ValueMapping.Dicts[ValueMapping.MappingType.LOCODE].ContainsKey(val)) { FixImportDialog fid = new FixImportDialog(); fid.Value = val; @@ -2773,15 +2783,20 @@ namespace ENI2.Excel fid.SelectionValues = ld; if (fid.ShowDialog() ?? false) { - _locodeImportDict[val] = fid.SelectedValue; + string selectedValue = fid.SelectedValue; + if (!ValueMapping.InvalidKeys[ValueMapping.MappingType.LOCODE].Contains(selectedValue)) { + Task createResult = Task.Run(async () => await ValueMapping.Create(ValueMapping.MappingType.LOCODE, val, selectedValue)); + if (!createResult.Result) + _log.WarnFormat("Error saving locode value mapping {0} -> {1}", val, selectedValue); + } } else { canceled = true; } } - if (_locodeImportDict.ContainsKey(val)) - result = _locodeImportDict[val]; + if (ValueMapping.Dicts[ValueMapping.MappingType.LOCODE].ContainsKey(val)) + result = ValueMapping.Dicts[ValueMapping.MappingType.LOCODE][val].Value; } else if (possibleLocodes.Count == 1) { @@ -2789,7 +2804,7 @@ namespace ENI2.Excel } else { - if (!_locodeImportDict.ContainsKey(val)) + if (!ValueMapping.Dicts[ValueMapping.MappingType.LOCODE].ContainsKey(val)) { // nothing found, let the user pick a locode by himself FixImportDialog fid = new FixImportDialog(); @@ -2798,11 +2813,17 @@ namespace ENI2.Excel fid.LocodeMode = true; if (fid.ShowDialog() ?? false) { - _locodeImportDict[val] = fid.SelectedValue; + if (!ValueMapping.InvalidKeys[ValueMapping.MappingType.LOCODE].Contains(fid.SelectedValue)) + { + string selectedValue = fid.SelectedValue; + Task createResult = Task.Run(async () => await ValueMapping.Create(ValueMapping.MappingType.LOCODE, val, selectedValue)); + if (!createResult.Result) + _log.WarnFormat("Error saving locode value mapping {0} -> {1}", val, selectedValue); + } } } - if (_locodeImportDict.ContainsKey(val)) - result = _locodeImportDict[val]; + if (ValueMapping.Dicts[ValueMapping.MappingType.LOCODE].ContainsKey(val)) + result = ValueMapping.Dicts[ValueMapping.MappingType.LOCODE][val].Value; } return result; diff --git a/bsmd.database/ValueMapping.cs b/bsmd.database/ValueMapping.cs index 486945b1..1edd2a27 100644 --- a/bsmd.database/ValueMapping.cs +++ b/bsmd.database/ValueMapping.cs @@ -37,8 +37,8 @@ namespace bsmd.database #region Fields - private static readonly Dictionary> _dicts = new Dictionary>(); - private static Dictionary> _invalidKeys = null; + private static Dictionary> _dicts; + private static Dictionary> _invalidKeys; #endregion @@ -46,7 +46,16 @@ namespace bsmd.database public static Dictionary> Dicts { - get { return _dicts; } + get + { + if (_dicts == null) + { + _dicts = new Dictionary>(); + foreach (MappingType type in Enum.GetValues(typeof(MappingType))) + _dicts[type] = new Dictionary(); + } + return _dicts; + } } public static Dictionary> InvalidKeys @@ -59,7 +68,7 @@ namespace bsmd.database // get the keys initialized that cannot be assigned foreach (MappingType type in Enum.GetValues(typeof(MappingType))) _invalidKeys[type] = new List(); - _invalidKeys[MappingType.COUNTRY].Add("UK"); + _invalidKeys[MappingType.COUNTRY].Add("UK"); // can be mapped to GB and to UA .. we don't know what they want } return _invalidKeys; } @@ -85,10 +94,7 @@ namespace bsmd.database /// true if entry was actually created, false if already present public static async Task Create(MappingType type, string key, string value) { - if (!_dicts.ContainsKey(type)) - _dicts[type] = new Dictionary(); - - if (!_dicts[type].ContainsKey(key)) + if (!Dicts[type].ContainsKey(key)) { ValueMapping vm = new ValueMapping() { @@ -96,7 +102,7 @@ namespace bsmd.database Key = key, Value = value }; - _dicts[type][key] = vm; + Dicts[type][key] = vm; return await DBManagerAsync.SaveAsync(vm) == 1; } return false; @@ -108,10 +114,10 @@ namespace bsmd.database /// true if successful, false if value was not found public static async Task Delete(MappingType type, string key) { - if (!_dicts.ContainsKey(type)) return false; - if (!_dicts[type].ContainsKey(key)) return false; - ValueMapping vm = _dicts[type][key]; - _dicts[type].Remove(key); + if (!Dicts.ContainsKey(type)) return false; + if (!Dicts[type].ContainsKey(key)) return false; + ValueMapping vm = Dicts[type][key]; + Dicts[type].Remove(key); return await DBManagerAsync.DeleteAsync(vm) == 1; } @@ -125,6 +131,20 @@ namespace bsmd.database return await DBManagerAsync.SaveAsync(this) == 1; } + /// + /// (re-)loads all value mapping dictionaries + /// + public static async void LoadDicts() + { + foreach(MappingType type in Enum.GetValues(typeof(MappingType))) + { + Dicts[type].Clear(); + List mappings = await DBManagerAsync.LoadValuesForType(type); + foreach (ValueMapping mapping in mappings) + Dicts[type][mapping.Key] = mapping; + } + } + #endregion #region DatabaseEntity implementation diff --git a/bsmd.database/WasteDisposalServiceProvider.cs b/bsmd.database/WasteDisposalServiceProvider.cs index 9aa3386b..adb1f9ff 100644 --- a/bsmd.database/WasteDisposalServiceProvider.cs +++ b/bsmd.database/WasteDisposalServiceProvider.cs @@ -96,7 +96,7 @@ namespace bsmd.database wdsp.id = reader.GetGuid(0); if (!reader.IsDBNull(1)) wdsp.WasteDisposalServiceProviderName = reader.GetString(1); - if (!reader.IsDBNull(3)) wdsp.Identifier = reader.GetString(2); + if (!reader.IsDBNull(2)) wdsp.Identifier = reader.GetString(2); result.Add(wdsp); } reader.Close();