Added script, entity and editor dialog for NST2007 lookup table (LADG)

This commit is contained in:
Daniel Schick 2026-02-19 13:22:32 +01:00
parent 8a44a664dd
commit acc4fde897
11 changed files with 502 additions and 27 deletions

View File

@ -0,0 +1,62 @@
<UserControl x:Class="ENI2.Controls.LADG_NST2007Control"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ENI2.Controls"
xmlns:util="clr-namespace:ENI2.Util"
xmlns:p="clr-namespace:ENI2.Properties"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="900">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="28" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label Grid.Row="0" Content="LADG NST2007" />
<GroupBox Header="" Grid.Row="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="28" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button x:Name="buttonSave" Grid.Column="0" Margin="2" Content="Save all changes" Click="buttonSave_Click" />
<Button x:Name="buttonAdd" Grid.Column="1" Margin="2" Content="Add new" Click="buttonAdd_Click" />
<Button x:Name="buttonImport" Grid.Column="2" Margin="2" Content="{x:Static p:Resources.textImportFromExcel}" Click="buttonImport_Click" />
</Grid>
<local:ENIDataGrid Grid.Row="1" Margin="2,8,2,2" x:Name="dataGridLADGNST2007" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"
SelectionMode="Extended" AutoGenerateColumns="False" CanUserAddRows="False"
CellEditEnding="dataGridLADGNST2007_CellEditEnding">
<DataGrid.Columns>
<DataGridTextColumn Header="NST2007" Width="120">
<DataGridTextColumn.Binding>
<Binding Path="NST2007" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<util:RequiredStringValidationRule />
<util:StringValidationRule MaxLength="3" />
</Binding.ValidationRules>
</Binding>
</DataGridTextColumn.Binding>
</DataGridTextColumn>
<DataGridTextColumn Header="Description" Width="*">
<DataGridTextColumn.Binding>
<Binding Path="Description" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<util:StringValidationRule MaxLength="100" />
</Binding.ValidationRules>
</Binding>
</DataGridTextColumn.Binding>
</DataGridTextColumn>
</DataGrid.Columns>
</local:ENIDataGrid>
</Grid>
</GroupBox>
</Grid>
</UserControl>

View File

@ -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
{
/// <summary>
/// Interaction logic for LADG_NST2007Control.xaml
/// </summary>
public partial class LADG_NST2007Control : UserControl
{
private readonly ObservableCollection<LADG_NST2007> _items = new ObservableCollection<LADG_NST2007>();
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<LADG_NST2007> 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<LADG_NST2007>();
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);
}
}
}
}

View File

@ -337,6 +337,9 @@
<Compile Include="Controls\PortAreaControl.xaml.cs">
<DependentUpon>PortAreaControl.xaml</DependentUpon>
</Compile>
<Compile Include="Controls\LADG_NST2007Control.xaml.cs">
<DependentUpon>LADG_NST2007Control.xaml</DependentUpon>
</Compile>
<Compile Include="Controls\WASExemptionsControl.xaml.cs">
<DependentUpon>WASExemptionsControl.xaml</DependentUpon>
</Compile>
@ -667,6 +670,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Controls\LADG_NST2007Control.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Controls\WASExemptionsControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>

View File

@ -577,6 +577,61 @@ namespace ENI2.Excel
#endregion
#region LADG NST2007 Import from Excel
public static List<LADG_NST2007> 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<LADG_NST2007> items = new List<LADG_NST2007>();
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<LADG_NST2007>();
}
#endregion
private static string Truncate(string value, int maxLength)
{
if (value == null)

View File

@ -113,6 +113,11 @@
<Image Source="Resources/anchor.png" />
</MenuItem.Icon>
</MenuItem>
<MenuItem x:Name="menuItemLADGNST2007" Header="LADG NST2007" Click="radioButton_Click">
<MenuItem.Icon>
<Image Source="Resources/nav_refresh_blue.png" />
</MenuItem.Icon>
</MenuItem>
</MenuItem>
<MenuItem x:Name="menuItemMaersk" Header="{x:Static p:Resources.textPOLists}" Click="radioButton_Click" Visibility="Hidden" />
<MenuItem x:Name="menuItemValueMappings" Header="{x:Static p:Resources.textExcelValueMappings}" Click="radioButton_Click" Visibility="Hidden" />

View File

@ -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)

View File

@ -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

View File

@ -439,10 +439,15 @@ namespace bsmd.database
return result;
}
public Dictionary<string, PortArea> GetPortAreaDict()
{
return DBManagerAsync.GetPortAreaDict();
}
public Dictionary<string, PortArea> GetPortAreaDict()
{
return DBManagerAsync.GetPortAreaDict();
}
public Dictionary<string, LADG_NST2007> 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)
{

View File

@ -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<PortArea> _allPortAreaRows;
private static Dictionary<string, PortArea> _allPortAreasByCode;
private static List<LADG_NST2007> _allLADGNST2007Rows;
private static Dictionary<string, LADG_NST2007> _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<List<LADG_NST2007>> LoadLADGNST2007Async(bool forceReload = false)
{
await EnsureLADGNST2007LoadedAsync(forceReload);
return new List<LADG_NST2007>(_allLADGNST2007Rows);
}
public static async Task<Dictionary<string, LADG_NST2007>> GetLADGNST2007DictAsync(bool forceReload = false)
{
await EnsureLADGNST2007LoadedAsync(forceReload);
return _allLADGNST2007ByCode;
}
public static Dictionary<string, LADG_NST2007> GetLADGNST2007Dict(bool forceReload = false)
{
return Task.Run(() => GetLADGNST2007DictAsync(forceReload)).GetAwaiter().GetResult();
}
public static void InvalidateLADGNST2007Cache()
{
_allLADGNST2007Rows = null;
_allLADGNST2007ByCode = null;
}
public static async Task<List<AGNT_Template>> 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<LADG_NST2007> rows = new List<LADG_NST2007>();
if (reader != null)
{
foreach (DatabaseEntity entity in item.LoadList(reader))
{
if (entity is LADG_NST2007 nst)
rows.Add(nst);
}
}
Dictionary<string, LADG_NST2007> byCode = new Dictionary<string, LADG_NST2007>(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

View File

@ -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<DatabaseEntity> LoadList(IDataReader reader)
{
List<DatabaseEntity> result = new List<DatabaseEntity>();
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
}
}

View File

@ -152,9 +152,10 @@
<Compile Include="CREW.cs" />
<Compile Include="DBManager.cs" />
<Compile Include="DatabaseEntity.cs" />
<Compile Include="INFO.cs" />
<Compile Include="LADG.cs" />
<Compile Include="MDH.cs" />
<Compile Include="INFO.cs" />
<Compile Include="LADG.cs" />
<Compile Include="LADG_NST2007.cs" />
<Compile Include="MDH.cs" />
<Compile Include="Message.cs" />
<Compile Include="MessageCore.cs" />
<Compile Include="MessageError.cs" />