diff --git a/ENI2/Controls/LADG_NST2007Control.xaml b/ENI2/Controls/LADG_NST2007Control.xaml
new file mode 100644
index 00000000..d6033b57
--- /dev/null
+++ b/ENI2/Controls/LADG_NST2007Control.xaml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ENI2/Controls/LADG_NST2007Control.xaml.cs b/ENI2/Controls/LADG_NST2007Control.xaml.cs
new file mode 100644
index 00000000..e46360be
--- /dev/null
+++ b/ENI2/Controls/LADG_NST2007Control.xaml.cs
@@ -0,0 +1,143 @@
+using bsmd.database;
+using ENI2.Excel;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+
+namespace ENI2.Controls
+{
+ ///
+ /// Interaction logic for LADG_NST2007Control.xaml
+ ///
+ public partial class LADG_NST2007Control : UserControl
+ {
+ private readonly ObservableCollection _items = new ObservableCollection();
+
+ public LADG_NST2007Control()
+ {
+ InitializeComponent();
+ this.dataGridLADGNST2007.ItemsSource = _items;
+
+ var view = CollectionViewSource.GetDefaultView(_items);
+ view.SortDescriptions.Add(new SortDescription(nameof(LADG_NST2007.NST2007), ListSortDirection.Ascending));
+
+ _ = LoadItemsAsync();
+
+ this.dataGridLADGNST2007.ContextMenu = new ContextMenu();
+ MenuItem addItem = new MenuItem
+ {
+ Header = Properties.Resources.textAdd,
+ Icon = new System.Windows.Controls.Image { Source = new System.Windows.Media.Imaging.BitmapImage(new Uri("pack://application:,,,/Resources/add.png")) }
+ };
+ addItem.Click += AddItem_Click;
+ this.dataGridLADGNST2007.ContextMenu.Items.Add(addItem);
+
+ MenuItem delItem = new MenuItem
+ {
+ Header = Properties.Resources.textDelete,
+ Icon = new System.Windows.Controls.Image { Source = new System.Windows.Media.Imaging.BitmapImage(new Uri("pack://application:,,,/Resources/delete.png")) }
+ };
+ delItem.Click += DelItem_Click;
+ this.dataGridLADGNST2007.ContextMenu.Items.Add(delItem);
+ }
+
+ private async Task LoadItemsAsync()
+ {
+ List items = await DBManagerAsync.LoadLADGNST2007Async(true);
+ foreach (LADG_NST2007 item in items)
+ {
+ _items.Add(item);
+ }
+ }
+
+ private void buttonSave_Click(object sender, RoutedEventArgs e)
+ {
+ _ = SaveItemsAsync();
+ }
+
+ private void buttonAdd_Click(object sender, RoutedEventArgs e)
+ {
+ AddNewItem();
+ }
+
+ private void buttonImport_Click(object sender, RoutedEventArgs e)
+ {
+ var imported = ExcelLocalImportHelper.ImportLADGNST2007();
+ foreach (var item in imported)
+ {
+ _items.Add(item);
+ }
+ }
+
+ private void dataGridLADGNST2007_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
+ {
+ if (e.Row?.Item is LADG_NST2007 item)
+ {
+ item.IsDirty = true;
+ }
+ }
+
+ private void AddItem_Click(object sender, RoutedEventArgs e)
+ {
+ AddNewItem();
+ }
+
+ private async void DelItem_Click(object sender, RoutedEventArgs e)
+ {
+ if (this.dataGridLADGNST2007.SelectedItems.Count > 0)
+ {
+ if (MessageBox.Show("Are you sure to delete the selected values?", Properties.Resources.textConfirmation, MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) ==
+ MessageBoxResult.Yes)
+ {
+ var selectedItems = new List();
+ foreach (LADG_NST2007 item in this.dataGridLADGNST2007.SelectedItems)
+ selectedItems.Add(item);
+
+ foreach (LADG_NST2007 item in selectedItems)
+ {
+ int result = await DBManagerAsync.DeleteAsync(item);
+ if (result == 1 || item.IsNew)
+ {
+ _items.Remove(item);
+ }
+ }
+ }
+ }
+ }
+
+ private void AddNewItem()
+ {
+ var item = new LADG_NST2007
+ {
+ IsDirty = true
+ };
+ _items.Add(item);
+ this.dataGridLADGNST2007.SelectedItem = item;
+ this.dataGridLADGNST2007.ScrollIntoView(item);
+ }
+
+ private async Task SaveItemsAsync()
+ {
+ int totalSaves = 0;
+ foreach (LADG_NST2007 item in _items)
+ {
+ if (item.IsNew || item.IsDirty)
+ {
+ if (item.NST2007.IsNullOrEmpty())
+ continue;
+ totalSaves += await DBManagerAsync.SaveAsync(item);
+ }
+ }
+
+ if (totalSaves > 0)
+ {
+ MessageBox.Show($"{totalSaves} LADG NST2007 rows saved", "Success", MessageBoxButton.OK, MessageBoxImage.Information);
+ }
+ }
+ }
+}
diff --git a/ENI2/ENI2.csproj b/ENI2/ENI2.csproj
index 86619b62..be0d906e 100644
--- a/ENI2/ENI2.csproj
+++ b/ENI2/ENI2.csproj
@@ -337,6 +337,9 @@
PortAreaControl.xaml
+
+ LADG_NST2007Control.xaml
+
WASExemptionsControl.xaml
@@ -667,6 +670,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
diff --git a/ENI2/Excel/ExcelLocalImportHelper.cs b/ENI2/Excel/ExcelLocalImportHelper.cs
index 2344f984..8480490d 100644
--- a/ENI2/Excel/ExcelLocalImportHelper.cs
+++ b/ENI2/Excel/ExcelLocalImportHelper.cs
@@ -577,6 +577,61 @@ namespace ENI2.Excel
#endregion
+ #region LADG NST2007 Import from Excel
+
+ public static List ImportLADGNST2007()
+ {
+ OpenFileDialog ofd = new OpenFileDialog
+ {
+ Filter = "Excel Files|*.xls;*.xlsx"
+ };
+
+ if (ofd.ShowDialog() ?? false)
+ {
+ try
+ {
+ using (var stream = new FileStream(ofd.FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
+ using (var workbook = new XLWorkbook(stream))
+ {
+ var worksheet = workbook.Worksheet(1);
+ var range = worksheet.RangeUsed();
+ var rows = range.RowsUsed().Skip(1); // header row
+
+ List items = new List();
+
+ foreach (var row in rows)
+ {
+ if (row.Cell(1).IsEmpty() && row.Cell(2).IsEmpty())
+ continue;
+
+ LADG_NST2007 item = new LADG_NST2007
+ {
+ IsDirty = true
+ };
+
+ if (!row.Cell(1).IsEmpty())
+ item.NST2007 = Truncate(row.Cell(1).GetString().Trim(), 3);
+ if (!row.Cell(2).IsEmpty())
+ item.Description = Truncate(row.Cell(2).GetString().Trim(), 100);
+
+ items.Add(item);
+ }
+
+ return items;
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show("Error reading Excel: " + ex.Message, Properties.Resources.textCaptionError,
+ MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ }
+
+ return new List();
+ }
+
+ #endregion
+
private static string Truncate(string value, int maxLength)
{
if (value == null)
diff --git a/ENI2/MainWindow.xaml b/ENI2/MainWindow.xaml
index f00ac30c..8da28058 100644
--- a/ENI2/MainWindow.xaml
+++ b/ENI2/MainWindow.xaml
@@ -113,6 +113,11 @@
+
diff --git a/ENI2/MainWindow.xaml.cs b/ENI2/MainWindow.xaml.cs
index 0b476605..d49484fb 100644
--- a/ENI2/MainWindow.xaml.cs
+++ b/ENI2/MainWindow.xaml.cs
@@ -43,6 +43,7 @@ namespace ENI2
private WASExemptionsControl wasExemptionsControl;
private HazardMaterialControl hazardMaterialControl;
private PortAreaControl portAreaControl;
+ private LADG_NST2007Control ladgNst2007Control;
private bool dbConnected;
private readonly ScaleTransform _transform = new ScaleTransform(1.0, 1.0);
@@ -360,6 +361,14 @@ namespace ENI2
}
this.rootContainer.Children.Add(this.portAreaControl);
}
+ else if (sender == this.menuItemLADGNST2007)
+ {
+ if (this.ladgNst2007Control == null)
+ {
+ this.ladgNst2007Control = new LADG_NST2007Control();
+ }
+ this.rootContainer.Children.Add(this.ladgNst2007Control);
+ }
}
private void buttonCompareSheets_Click(object sender, RoutedEventArgs ev)
diff --git a/SQL/Update_To_7.2.15.sql b/SQL/Update_To_7.2.15.sql
index b11bd0de..cca3148f 100644
--- a/SQL/Update_To_7.2.15.sql
+++ b/SQL/Update_To_7.2.15.sql
@@ -49,21 +49,16 @@ BEGIN
END
GO
-PRINT N'Creating [dbo].[PortAreaHelper] if missing...';
+PRINT N'Creating [dbo].[LADG_NST2007] if missing...';
GO
-IF OBJECT_ID(N'dbo.PortAreaHelper', N'U') IS NULL
+IF OBJECT_ID(N'dbo.LADG_NST2007', N'U') IS NULL
BEGIN
- CREATE TABLE [dbo].[PortAreaHelper] (
+ CREATE TABLE [dbo].[LADG_NST2007] (
[Id] UNIQUEIDENTIFIER NOT NULL,
- [Locode] NCHAR (5) NOT NULL,
- [Agency] NVARCHAR (100) NULL,
- [Ships] NVARCHAR (100) NULL,
- [Berth] NVARCHAR (100) NULL,
- [PortArea] NVARCHAR (100) NULL,
- [PortArea_Code] NVARCHAR (10) NULL,
- [Remarks] NVARCHAR (255) NULL,
+ [Description] NVARCHAR (100) NULL,
+ [NST2007] NCHAR (3) NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
- PRINT N'Table [dbo].[PortAreaHelper] created.';
+ PRINT N'Table [dbo].[LADG_NST2007] created.';
END
GO
\ No newline at end of file
diff --git a/bsmd.database/DBManager.cs b/bsmd.database/DBManager.cs
index 3e498192..37d02e35 100644
--- a/bsmd.database/DBManager.cs
+++ b/bsmd.database/DBManager.cs
@@ -439,10 +439,15 @@ namespace bsmd.database
return result;
}
- public Dictionary GetPortAreaDict()
- {
- return DBManagerAsync.GetPortAreaDict();
- }
+ public Dictionary GetPortAreaDict()
+ {
+ return DBManagerAsync.GetPortAreaDict();
+ }
+
+ public Dictionary GetLADGNST2007Dict()
+ {
+ return DBManagerAsync.GetLADGNST2007Dict();
+ }
public DatabaseEntity GetMessageById(Guid id)
{
@@ -634,10 +639,12 @@ namespace bsmd.database
SqlCommand cmd = new SqlCommand();
entity.PrepareSave(cmd);
int queryResult = this.PerformNonQuery(cmd);
- this.LogNonQueryResult(cmd.CommandText, queryResult);
- this.CreateEntityHistoryEntry(entity);
- if (entity is PortArea)
- DBManagerAsync.InvalidatePortAreaCache();
+ this.LogNonQueryResult(cmd.CommandText, queryResult);
+ this.CreateEntityHistoryEntry(entity);
+ if (entity is PortArea)
+ DBManagerAsync.InvalidatePortAreaCache();
+ if (entity is LADG_NST2007)
+ DBManagerAsync.InvalidateLADGNST2007Cache();
if (this._closeConnectionAfterUse) this.Disconnect();
}
@@ -652,11 +659,13 @@ namespace bsmd.database
int queryResult = this.PerformNonQuery(cmd);
this.LogNonQueryResult(cmd.CommandText, queryResult);
}
- }
- if (entity is PortArea)
- DBManagerAsync.InvalidatePortAreaCache();
- if (this._closeConnectionAfterUse) this.Disconnect();
- }
+ }
+ if (entity is PortArea)
+ DBManagerAsync.InvalidatePortAreaCache();
+ if (entity is LADG_NST2007)
+ DBManagerAsync.InvalidateLADGNST2007Cache();
+ if (this._closeConnectionAfterUse) this.Disconnect();
+ }
public void DeleteMessageErrors(Message message)
{
diff --git a/bsmd.database/DBManagerAsync.cs b/bsmd.database/DBManagerAsync.cs
index 1fabb1a1..ae23cbc3 100644
--- a/bsmd.database/DBManagerAsync.cs
+++ b/bsmd.database/DBManagerAsync.cs
@@ -17,8 +17,11 @@ namespace bsmd.database
private static readonly ILog _log = LogManager.GetLogger(typeof(DBManagerAsync));
private static readonly SemaphoreSlim _portAreaLoadLock = new SemaphoreSlim(1, 1);
+ private static readonly SemaphoreSlim _ladgNst2007LoadLock = new SemaphoreSlim(1, 1);
private static List _allPortAreaRows;
private static Dictionary _allPortAreasByCode;
+ private static List _allLADGNST2007Rows;
+ private static Dictionary _allLADGNST2007ByCode;
#endregion
@@ -38,6 +41,8 @@ namespace bsmd.database
if (result == 1) entity.IsDirty = false;
if ((result == 1) && (entity is PortArea))
InvalidatePortAreaCache();
+ if ((result == 1) && (entity is LADG_NST2007))
+ InvalidateLADGNST2007Cache();
return result;
}
@@ -51,6 +56,8 @@ namespace bsmd.database
int result = await PerformNonQueryAsync(cmd);
if ((result == 1) && (entity is PortArea))
InvalidatePortAreaCache();
+ if ((result == 1) && (entity is LADG_NST2007))
+ InvalidateLADGNST2007Cache();
return result;
}
}
@@ -152,6 +159,29 @@ namespace bsmd.database
_allPortAreasByCode = null;
}
+ public static async Task> LoadLADGNST2007Async(bool forceReload = false)
+ {
+ await EnsureLADGNST2007LoadedAsync(forceReload);
+ return new List(_allLADGNST2007Rows);
+ }
+
+ public static async Task> GetLADGNST2007DictAsync(bool forceReload = false)
+ {
+ await EnsureLADGNST2007LoadedAsync(forceReload);
+ return _allLADGNST2007ByCode;
+ }
+
+ public static Dictionary GetLADGNST2007Dict(bool forceReload = false)
+ {
+ return Task.Run(() => GetLADGNST2007DictAsync(forceReload)).GetAwaiter().GetResult();
+ }
+
+ public static void InvalidateLADGNST2007Cache()
+ {
+ _allLADGNST2007Rows = null;
+ _allLADGNST2007ByCode = null;
+ }
+
public static async Task> GetAGNTTemplatesAsync()
{
SqlCommand cmd = new SqlCommand();
@@ -231,6 +261,51 @@ namespace bsmd.database
}
}
+ private static async Task EnsureLADGNST2007LoadedAsync(bool forceReload)
+ {
+ if (forceReload)
+ InvalidateLADGNST2007Cache();
+
+ if ((_allLADGNST2007Rows != null) && (_allLADGNST2007ByCode != null))
+ return;
+
+ await _ladgNst2007LoadLock.WaitAsync();
+ try
+ {
+ if ((_allLADGNST2007Rows != null) && (_allLADGNST2007ByCode != null))
+ return;
+
+ SqlCommand cmd = new SqlCommand();
+ LADG_NST2007 item = new LADG_NST2007();
+ item.PrepareLoadCommand(cmd, Message.LoadFilter.ALL);
+ SqlDataReader reader = await PerformCommandAsync(cmd);
+
+ List rows = new List();
+ if (reader != null)
+ {
+ foreach (DatabaseEntity entity in item.LoadList(reader))
+ {
+ if (entity is LADG_NST2007 nst)
+ rows.Add(nst);
+ }
+ }
+
+ Dictionary byCode = new Dictionary(StringComparer.OrdinalIgnoreCase);
+ foreach (LADG_NST2007 nst in rows)
+ {
+ if (!nst.NST2007.IsNullOrEmpty())
+ byCode[nst.NST2007] = nst;
+ }
+
+ _allLADGNST2007Rows = rows;
+ _allLADGNST2007ByCode = byCode;
+ }
+ finally
+ {
+ _ladgNst2007LoadLock.Release();
+ }
+ }
+
#endregion
#region async DB access methods
diff --git a/bsmd.database/LADG_NST2007.cs b/bsmd.database/LADG_NST2007.cs
new file mode 100644
index 00000000..f82a7a74
--- /dev/null
+++ b/bsmd.database/LADG_NST2007.cs
@@ -0,0 +1,114 @@
+// Copyright (c) 2026 schick Informatik
+// Description: DB entity for LADG NST2007 lookup
+
+using System.Collections.Generic;
+using System.Data;
+using System.Data.SqlClient;
+
+namespace bsmd.database
+{
+ public class LADG_NST2007 : DatabaseEntity
+ {
+ public LADG_NST2007()
+ {
+ this.tablename = "[dbo].[LADG_NST2007]";
+ }
+
+ #region Properties
+
+ [MaxLength(100)]
+ [ENI2Validation]
+ public string Description { get; set; }
+
+ [MaxLength(3)]
+ [ENI2Validation]
+ public string NST2007 { get; set; }
+
+ #endregion
+
+ #region public static methods
+
+ public static bool NST2007Exists(string nst2007)
+ {
+ if (nst2007.IsNullOrEmpty())
+ return false;
+
+ return DBManagerAsync.GetLADGNST2007Dict().ContainsKey(nst2007);
+ }
+
+ public static string GetDescription(string nst2007)
+ {
+ if (nst2007.IsNullOrEmpty())
+ return null;
+
+ if (DBManagerAsync.GetLADGNST2007Dict().TryGetValue(nst2007, out LADG_NST2007 value))
+ return value.Description;
+
+ return null;
+ }
+
+ #endregion
+
+ #region abstract method implementation
+
+ public override List LoadList(IDataReader reader)
+ {
+ List result = new List();
+ while (reader.Read())
+ {
+ LADG_NST2007 item = new LADG_NST2007();
+ item.id = reader.GetGuid(0);
+ if (!reader.IsDBNull(1)) item.Description = reader.GetString(1);
+ if (!reader.IsDBNull(2)) item.NST2007 = reader.GetString(2);
+ result.Add(item);
+ }
+ reader.Close();
+ return result;
+ }
+
+ public override void PrepareLoadCommand(IDbCommand cmd, Message.LoadFilter filter, params object[] criteria)
+ {
+ string query = string.Format("SELECT Id, Description, NST2007 FROM {0} ", this.Tablename);
+
+ switch (filter)
+ {
+ case Message.LoadFilter.ALL:
+ default:
+ break;
+ }
+
+ cmd.CommandText = query;
+ }
+
+ public override void PrepareSave(IDbCommand cmd)
+ {
+ SqlCommand scmd = cmd as SqlCommand;
+
+ scmd.Parameters.AddWithNullableValue("@DESCRIPTION", this.Description);
+ scmd.Parameters.AddWithNullableValue("@NST2007", this.NST2007);
+
+ if (this.IsNew)
+ {
+ this.CreateId();
+ scmd.Parameters.AddWithValue("@ID", this.Id);
+ scmd.CommandText = string.Format("INSERT INTO {0} (Id, Description, NST2007) VALUES (@ID, @DESCRIPTION, @NST2007)", this.Tablename);
+ }
+ else
+ {
+ scmd.Parameters.AddWithValue("@ID", this.Id);
+ scmd.CommandText = string.Format("UPDATE {0} SET Description = @DESCRIPTION, NST2007 = @NST2007 WHERE Id = @ID", this.Tablename);
+ }
+ }
+
+ #endregion
+
+ #region override
+
+ public override string ToString()
+ {
+ return string.Format("{0} {1}", this.NST2007, this.Description);
+ }
+
+ #endregion
+ }
+}
diff --git a/bsmd.database/bsmd.database.csproj b/bsmd.database/bsmd.database.csproj
index 9917f83c..42215aa6 100644
--- a/bsmd.database/bsmd.database.csproj
+++ b/bsmd.database/bsmd.database.csproj
@@ -152,9 +152,10 @@
-
-
-
+
+
+
+