Merge branch 'release/eni_7.11'

This commit is contained in:
Daniel Schick 2023-04-12 10:12:51 +02:00
commit 827ca56413
29 changed files with 510 additions and 135 deletions

View File

@ -444,8 +444,8 @@ namespace ENI2.Controls
else
{
imosAreOkay = false;
}
}
}
}
else
{
imosAreOkay = false;
@ -459,7 +459,7 @@ namespace ENI2.Controls
importData.Add(md);
if (isFirstRow) isFirstRow = false;
if (isFirstRow) isFirstRow = false;
}
}
catch (Exception ex)
@ -469,7 +469,7 @@ namespace ENI2.Controls
if (imosAreOkay && importData.Count > 0)
{
busyControl.BusyState = Util.UIHelper.BusyStateEnum.BUSY;
busyControl.BusyState = Util.UIHelper.BusyStateEnum.BUSY;
foreach (MaerskData md in importData)
{
@ -480,15 +480,37 @@ namespace ENI2.Controls
(m.ColG != null) ? m.ColG.Equals(md.ColG) : (md.ColG == null) &&
(m.ColH != null) ? m.ColH.Equals(md.ColH) : (md.ColH == null));
if(foundData.ETA.HasValue && ((foundData.ETA.Value - DateTime.Now).TotalSeconds > 0) && foundData.Update(md))
foundData.Status = MaerskData.MDStatus.UPDATED;
if ((foundData.MessageCore == null) || !(foundData.MessageCore.Cancelled ?? false))
{
if (foundData.ETA.HasValue && ((foundData.ETA.Value - DateTime.Now).TotalSeconds > 0) && foundData.Update(md))
foundData.Status = MaerskData.MDStatus.UPDATED;
}
}
else
{
if (!md.ColM.IsNullOrEmpty())
{
md.MessageCore = await DBManagerAsync.LoadCoreByVisitIdAsync(md.ColM);
if (md.MessageCore != null)
{
MaerskData existingMD = await DBManagerAsync.LoadMaerskDataForCoreAsync(md.MessageCore.Id.Value);
if(existingMD == null)
{
// we have a core but no MarskData for this import -> save it
md.MessageCoreId = (Guid) md.MessageCore.Id;
_ = DBManagerAsync.SaveAsync(md);
}
else
{
existingMD.Update(md);
_ = DBManagerAsync.SaveAsync(existingMD);
this.UpdateStatus(existingMD);
maerskDataList.Add(existingMD);
continue; // add existing instead of new one
}
}
}
this.UpdateStatus(md);
maerskDataList.Add(md);
}
@ -498,7 +520,7 @@ namespace ENI2.Controls
busyControl.BusyState = Util.UIHelper.BusyStateEnum.NEUTRAL;
this.dataGridPOCores.Items.Refresh();
}
}
}
stream.Close();
@ -531,26 +553,6 @@ namespace ENI2.Controls
}
}
/*
private async void buttonSave_Click(object sender, RoutedEventArgs e)
{
busyControl.BusyState = Util.UIHelper.BusyStateEnum.BUSY;
// save the current list to DB (only if the entries have matching cores!)
foreach(MaerskData md in this.maerskDataList)
{
if(md.MessageCore != null)
{
await DBManagerAsync.Save(md);
}
}
busyControl.BusyState = Util.UIHelper.BusyStateEnum.NEUTRAL;
}
*/
private async void buttonRequestIds_Click(object sender, RoutedEventArgs e)
{
// find all entries from now until 4 days into the future and track parallel requests

View File

@ -8,6 +8,7 @@
xmlns:enictrl="clr-namespace:ENI2.Controls"
xmlns:p="clr-namespace:ENI2.Properties"
xmlns:util="clr-namespace:ENI2.Util"
xmlns:data="clr-namespace:bsmd.database;assembly=bsmd.database"
xmlns:local="clr-namespace:ENI2.DetailViewControls"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="800">
@ -147,6 +148,13 @@
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="LightYellow" />
</Trigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=Elements, Converter={util:CutoffConverter}, ConverterParameter=0}" Value="True" />
<Condition Binding="{Binding Path=MessageNotificationClass}" Value="{x:Static data:Message+NotificationClass.PAS}" />
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="Yellow" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
@ -160,10 +168,7 @@
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<!--
<DataGridTextColumn Header="{x:Static p:Resources.textNotificationGroup}" Binding="{Binding ENINotificationDetailGroup}" IsReadOnly="True" Width="0.25*" />
-->
<DataGridTextColumn Header="{x:Static p:Resources.textNotificationClass}" Binding="{Binding MessageNotificationClassDisplay}"
IsReadOnly="True" Width="0.075*" FontWeight="Bold">
<DataGridTextColumn.ElementStyle>

View File

@ -36,8 +36,8 @@
<MinimumRequiredVersion>5.4.0.0</MinimumRequiredVersion>
<CreateWebPageOnPublish>true</CreateWebPageOnPublish>
<WebPage>publish.html</WebPage>
<ApplicationRevision>8</ApplicationRevision>
<ApplicationVersion>7.10.0.%2a</ApplicationVersion>
<ApplicationRevision>6</ApplicationRevision>
<ApplicationVersion>7.11.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<CreateDesktopShortcut>true</CreateDesktopShortcut>
<PublishWizardCompleted>true</PublishWizardCompleted>
@ -436,6 +436,7 @@
</Compile>
<Compile Include="Util\BoolToVisibilityConverter.cs" />
<Compile Include="Util\ByteConverter.cs" />
<Compile Include="Util\CutoffConverter.cs" />
<Compile Include="Util\DatabaseEntityWatchdog.cs" />
<Compile Include="Util\EnumHelper.cs" />
<Compile Include="Util\EnumToBooleanConverter.cs" />

View File

@ -46,7 +46,7 @@
<TextBox Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="3" Name="textBoxBulkCargoShippingName" MaxLength="255" Margin="2" />
<CheckBox Grid.Row="2" Grid.Column="1" VerticalAlignment="Center" Margin="2" Name="checkBoxMaterialHazardous" />
<TextBox Grid.Row="2" Grid.Column="4" Name="textBoxUNNumber" MaxLength="4" Margin="2" VerticalContentAlignment="Center" />
<TextBox Grid.Row="3" Grid.Column="1" Name="textBoxIMOClass" MaxLength="4" Margin="2" VerticalContentAlignment="Center" />
<TextBox Grid.Row="3" Grid.Column="1" Name="textBoxIMOClass" MaxLength="3" Margin="2" VerticalContentAlignment="Center" />
<xctk:DoubleUpDown Name="doubleUpDownQuantity" Grid.Row="3" Grid.Column="4" Margin="2" FormatString="N3" ShowButtonSpinner="False" TextAlignment="Left"/>
<Label Grid.Row="3" Grid.Column="5" Content="kg" />
<TextBox Grid.Row="4" Grid.Column="1" Name="textBoxStowagePosition" MaxLength="24" Margin="2" VerticalContentAlignment="Center" />

View File

@ -15,6 +15,8 @@ namespace ENI2.Excel
{
public static void WriteMaerskList(string filename, List<MaerskData> data)
{
data.Sort();
Application excelApp = new Application();
excelApp.DisplayAlerts = false;
excelApp.Visible = false;
@ -57,7 +59,7 @@ namespace ENI2.Excel
ws.Cells[i + 2, 11] = md.ColK;
ws.Cells[i + 2, 12] = md.ColL;
ws.Cells[i + 2, 13] = md.ColM ;
// ws.Cells[i + 2, 14] = md.Remark;
ws.Cells[i + 2, 14] = md.Remark;
if((md.MessageCore != null) && (md.MessageCore.Cancelled ?? false))
{

View File

@ -1613,6 +1613,15 @@ namespace ENI2.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Copy IMO to clipboard.
/// </summary>
public static string textCopyIMO {
get {
return ResourceManager.GetString("textCopyIMO", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Copy to {0}.
/// </summary>

View File

@ -1876,4 +1876,7 @@
<data name="exit" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\exit.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="textCopyIMO" xml:space="preserve">
<value>Copy IMO to clipboard</value>
</data>
</root>

View File

@ -51,6 +51,11 @@ namespace ENI2
addItem.Icon = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/Resources/documents.png")) };
addItem.Click += this.copyID;
this.dataGrid.ContextMenu.Items.Add(addItem);
MenuItem copyIMOItem = new MenuItem();
copyIMOItem.Header = Properties.Resources.textCopyIMO;
copyIMOItem.Icon = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/Resources/document_into.png")) };
copyIMOItem.Click += this.copyIMO;
this.dataGrid.ContextMenu.Items.Add(copyIMOItem);
cancelItem = new MenuItem();
cancelItem.Header = Properties.Resources.textUndoCancel;
cancelItem.Icon = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/Resources/delete.png")) };
@ -297,6 +302,14 @@ namespace ENI2
}
}
private void copyIMO(object sender, RoutedEventArgs e)
{
if (dataGrid.SelectedItem is MessageCore selectedCore)
{
Clipboard.SetText(selectedCore.IMO);
}
}
#endregion
private void logoImage_MouseUp(object sender, MouseButtonEventArgs e)

View File

@ -0,0 +1,49 @@
// Copyright (c) 2023- schick Informatik
// Description: Simple converter to check if a numeric value is greater than a specific value. This can
// be used by datatriggers in XAML
//
using System;
using System.Collections;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Markup;
namespace ENI2.Util
{
public class CutoffConverter : MarkupExtension, IValueConverter
{
#region MarkupExtension implementation
private static CutoffConverter _converter = null;
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (_converter == null)
{
_converter = new CutoffConverter();
}
return _converter;
}
#endregion
#region IValueConverter implementation
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is ICollection collection)
return collection.Count > Cutoff;
return ((int)value) > Cutoff;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
public int Cutoff { get; set; }
}
}

View File

@ -45,7 +45,7 @@ namespace ENI2.Locode
public static string LocodeFromCity(string city, string country)
{
string result = null;
string query = string.Format("SELECT city_code FROM locodes JOIN countries ON locodes.country_id = countries.ID WHERE countries.code = '{0}' AND locodes.port='t' AND (locodes.name like '{1}' OR locodes.name_wo_diacritics like '{1}')",
string query = string.Format("SELECT city_code FROM locodes JOIN countries ON locodes.country_id = countries.ID WHERE countries.code = '{0}' AND locodes.port=1 AND (locodes.name like '{1}' OR locodes.name_wo_diacritics like '{1}')",
country, city);
SQLiteCommand cmd = new SQLiteCommand(query, _con);
IDataReader reader = cmd.ExecuteReader();
@ -73,7 +73,7 @@ namespace ENI2.Locode
if ((countryCode != null) && (lcLookup != null))
results.Add(lcLookup);
}
string query = string.Format("SELECT city_code, countries.code FROM locodes JOIN countries ON locodes.country_id = countries.ID WHERE locodes.port='t' AND (locodes.name like '{0}' OR locodes.name_wo_diacritics like '{0}')", city);
string query = string.Format("SELECT city_code, countries.code FROM locodes JOIN countries ON locodes.country_id = countries.ID WHERE locodes.port=1 AND (locodes.name like '{0}' OR locodes.name_wo_diacritics like '{0}')", city);
SQLiteCommand cmd = new SQLiteCommand(query, _con);
IDataReader reader = cmd.ExecuteReader();
while (reader.Read())
@ -103,7 +103,7 @@ namespace ENI2.Locode
}
}
string query = "SELECT locodes.name_wo_diacritics, city_code, countries.code FROM locodes JOIN countries ON locodes.country_id = countries.ID WHERE locodes.port='t' AND (locodes.name like $PAR OR locodes.name_wo_diacritics like $PAR)";
string query = "SELECT locodes.name_wo_diacritics, city_code, countries.code FROM locodes JOIN countries ON locodes.country_id = countries.ID WHERE locodes.port=1 AND (locodes.name like $PAR OR locodes.name_wo_diacritics like $PAR)";
if(!onlyPorts)
query = "SELECT locodes.name_wo_diacritics, city_code, countries.code FROM locodes JOIN countries ON locodes.country_id = countries.ID WHERE (locodes.name like $PAR OR locodes.name_wo_diacritics like $PAR)";
@ -190,7 +190,7 @@ namespace ENI2.Locode
try
{
string locodeUpper = locode.ToUpper();
string query = string.Format("SELECT locodes.name_wo_diacritics FROM locodes JOIN countries ON locodes.country_id = countries.ID WHERE locodes.port='t' AND locodes.city_code = '{0}' AND countries.code = '{1}'",
string query = string.Format("SELECT locodes.name_wo_diacritics FROM locodes JOIN countries ON locodes.country_id = countries.ID WHERE locodes.port=1 AND locodes.city_code = '{0}' AND countries.code = '{1}'",
locodeUpper.Substring(2), locodeUpper.Substring(0, 2));
SQLiteCommand cmd = new SQLiteCommand(query, _con);
IDataReader reader = cmd.ExecuteReader();

View File

@ -1,22 +1,51 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25123.0
# Visual Studio Version 16
VisualStudioVersion = 16.0.33328.57
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "bsmd.Tool", "bsmd.Tool\bsmd.Tool.csproj", "{5F5E65EE-9351-4F30-817A-9C6C6D6835AE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "bsmd.database", "bsmd.database\bsmd.database.csproj", "{19945AF2-379B-46A5-B27A-303B5EC1D557}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug 64|Any CPU = Debug 64|Any CPU
Debug 64|x64 = Debug 64|x64
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5F5E65EE-9351-4F30-817A-9C6C6D6835AE}.Debug 64|Any CPU.ActiveCfg = Debug|Any CPU
{5F5E65EE-9351-4F30-817A-9C6C6D6835AE}.Debug 64|Any CPU.Build.0 = Debug|Any CPU
{5F5E65EE-9351-4F30-817A-9C6C6D6835AE}.Debug 64|x64.ActiveCfg = Debug|Any CPU
{5F5E65EE-9351-4F30-817A-9C6C6D6835AE}.Debug 64|x64.Build.0 = Debug|Any CPU
{5F5E65EE-9351-4F30-817A-9C6C6D6835AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5F5E65EE-9351-4F30-817A-9C6C6D6835AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5F5E65EE-9351-4F30-817A-9C6C6D6835AE}.Debug|x64.ActiveCfg = Debug|Any CPU
{5F5E65EE-9351-4F30-817A-9C6C6D6835AE}.Debug|x64.Build.0 = Debug|Any CPU
{5F5E65EE-9351-4F30-817A-9C6C6D6835AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5F5E65EE-9351-4F30-817A-9C6C6D6835AE}.Release|Any CPU.Build.0 = Release|Any CPU
{5F5E65EE-9351-4F30-817A-9C6C6D6835AE}.Release|x64.ActiveCfg = Release|Any CPU
{5F5E65EE-9351-4F30-817A-9C6C6D6835AE}.Release|x64.Build.0 = Release|Any CPU
{19945AF2-379B-46A5-B27A-303B5EC1D557}.Debug 64|Any CPU.ActiveCfg = Debug 64|Any CPU
{19945AF2-379B-46A5-B27A-303B5EC1D557}.Debug 64|Any CPU.Build.0 = Debug 64|Any CPU
{19945AF2-379B-46A5-B27A-303B5EC1D557}.Debug 64|x64.ActiveCfg = Debug 64|x64
{19945AF2-379B-46A5-B27A-303B5EC1D557}.Debug 64|x64.Build.0 = Debug 64|x64
{19945AF2-379B-46A5-B27A-303B5EC1D557}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19945AF2-379B-46A5-B27A-303B5EC1D557}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19945AF2-379B-46A5-B27A-303B5EC1D557}.Debug|x64.ActiveCfg = Debug|x64
{19945AF2-379B-46A5-B27A-303B5EC1D557}.Debug|x64.Build.0 = Debug|x64
{19945AF2-379B-46A5-B27A-303B5EC1D557}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19945AF2-379B-46A5-B27A-303B5EC1D557}.Release|Any CPU.Build.0 = Release|Any CPU
{19945AF2-379B-46A5-B27A-303B5EC1D557}.Release|x64.ActiveCfg = Release|x64
{19945AF2-379B-46A5-B27A-303B5EC1D557}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6B3F5B6D-3615-4A93-A6A7-46BD448CEED6}
EndGlobalSection
EndGlobal

View File

@ -1,30 +1,30 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,Log4net"/>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="bsmd.Tool.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="bsmd.Tool.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
</sectionGroup>
</configSections>
<log4net>
<root>
<level value="DEBUG" />
<appender-ref ref="LogFileAppender" />
<level value="DEBUG"/>
<appender-ref ref="LogFileAppender"/>
</root>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender" >
<param name="File" value="log.bsmd.Tool.txt" />
<param name="AppendToFile" value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="log.bsmd.Tool.txt"/>
<param name="AppendToFile" value="true"/>
<rollingStyle value="Size"/>
<maxSizeRollBackups value="10"/>
<maximumFileSize value="10MB"/>
<staticLogFileName value="true"/>
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%date [%thread] %-5level [%logger] - %message%newline" />
<param name="ConversionPattern" value="%date [%thread] %-5level [%logger] - %message%newline"/>
</layout>
</appender>
</log4net>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
</startup>
<userSettings>
<bsmd.Tool.Properties.Settings>
@ -33,4 +33,4 @@
</setting>
</bsmd.Tool.Properties.Settings>
</userSettings>
</configuration>
</configuration>

View File

@ -14,9 +14,9 @@ using log4net;
namespace bsmd.Tool
{
public class CheckRules
public static class CheckRules
{
private static ILog log = LogManager.GetLogger("CheckRules");
private static readonly ILog log = LogManager.GetLogger("CheckRules");
public static void Check(Guid messageCoreId)
{
if(DBManager.Instance.Connect(Properties.Settings.Default.ConnectionString))
@ -28,16 +28,15 @@ namespace bsmd.Tool
List<Message> messages = DBManager.Instance.GetMessagesForCore(core, DBManager.MessageLoad.ALL);
RuleEngine ruleEngine = new RuleEngine();
foreach(Message message in messages) {
foreach(Message message in messages)
{
// clear old results
DBManager.Instance.DeleteMessageErrors(message);
DBManager.Instance.DeleteMessageViolations(message);
// perform validation
ruleEngine.Validate(message);
}
}
}
else
{

View File

@ -7,9 +7,8 @@ using System.IO;
namespace bsmd.Tool
{
class CleanupFiles
internal static class CleanupFiles
{
/// <summary>
/// Alle XML Dateien in einem Dateipfad(rootPath) (recursive) löschen, die älter als (staleDays) Tage sind
/// </summary>
@ -35,6 +34,5 @@ namespace bsmd.Tool
Cleanup(directory, staleDays, recursive);
}
}
}
}

View File

@ -0,0 +1,210 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SQLite;
using log4net;
namespace bsmd.Tool
{
public static class LocodeSQliteImport
{
private static readonly ILog _log = LogManager.GetLogger(typeof(LocodeSQliteImport));
/// <summary>
/// Importer / Updater für CSV files, die im SVN unter \bsmd\nsw\Archiv abgelegt wurde
/// (offizielle UNLOCODEs)..
/// </summary>
/// <param name="sqliteDBPath"></param>
/// <param name="csvFilePath"></param>
public static void Import(string sqliteDBPath, string csvFilePath)
{
if (!File.Exists(sqliteDBPath)) throw new ArgumentException($"file {sqliteDBPath} does not exits");
if (!File.Exists(csvFilePath)) throw new ArgumentException($"file {csvFilePath} does not exist");
List<string> currentLocodes = new List<string>();
using (var connection = new SQLiteConnection($"Data Source={sqliteDBPath}"))
{
connection.Open();
// preload countries
Dictionary<string, int> countryDict = new Dictionary<string, int>();
SQLiteCommand countryCmd = new SQLiteCommand(connection);
countryCmd.CommandText = "SELECT id, code FROM countries";
SQLiteDataReader reader = countryCmd.ExecuteReader();
while (reader.Read())
{
countryDict[reader.GetString(1)] = reader.GetInt32(0);
}
SQLiteCommand lookupCmd = new SQLiteCommand(connection);
lookupCmd.CommandText = "SELECT locodes.id FROM locodes INNER JOIN countries ON locodes.country_id = countries.id WHERE countries.code = @CCODE AND locodes.city_code = @LCODE";
SQLiteParameter ccode = new SQLiteParameter("@CCODE", DbType.String);
lookupCmd.Parameters.Add(ccode);
SQLiteParameter lcode = new SQLiteParameter("@LCODE", DbType.String);
lookupCmd.Parameters.Add(lcode);
SQLiteCommand insertCmd = new SQLiteCommand(connection);
insertCmd.CommandText = "INSERT INTO locodes (country_id, city_code, name, name_wo_diacritics, sub_div, port, rail_terminal, road_terminal, airport, postal_exchange_office, inland_clearance_depot, fixed_transport_functions, border_crossing_function, status, date, iata, coordinates, remarks) VALUES " +
"(@P1, @P2, @P3, @P4, @P5, @P6, @P7, @P8, @P9, @P10, @P11, @P12, @P13, @P14, @P15, @P16, @P17, @P18)";
SQLiteCommand updateCmd = new SQLiteCommand(connection);
updateCmd.CommandText = "UPDATE locodes SET name = @P3, name_wo_diacritics = @P4, sub_div = @P5, port = @P6, rail_terminal = @P7, road_terminal = @P8, airport = @P9, postal_exchange_office = @P10, " +
"inland_clearance_depot = @P11, fixed_transport_functions = @P12, border_crossing_function = @P13, status = @P14, date = @P15, iata = @P16, coordinates = @P17, remarks = @P18 WHERE id = @ID";
SQLiteParameter p1 = new SQLiteParameter("@P1", DbType.Int32);
SQLiteParameter p2 = new SQLiteParameter("@P2", DbType.String);
SQLiteParameter p3 = new SQLiteParameter("@P3", DbType.String);
SQLiteParameter p4 = new SQLiteParameter("@P4", DbType.String);
SQLiteParameter p5 = new SQLiteParameter("@P5", DbType.String);
SQLiteParameter p6 = new SQLiteParameter("@P6", DbType.Boolean);
SQLiteParameter p7 = new SQLiteParameter("@P7", DbType.Boolean);
SQLiteParameter p8 = new SQLiteParameter("@P8", DbType.Boolean);
SQLiteParameter p9 = new SQLiteParameter("@P9", DbType.Boolean);
SQLiteParameter p10 = new SQLiteParameter("@P10", DbType.Boolean);
SQLiteParameter p11 = new SQLiteParameter("@P11", DbType.Boolean);
SQLiteParameter p12 = new SQLiteParameter("@P12", DbType.Boolean);
SQLiteParameter p13 = new SQLiteParameter("@P13", DbType.Boolean);
SQLiteParameter p14 = new SQLiteParameter("@P14", DbType.String);
SQLiteParameter p15 = new SQLiteParameter("@P15", DbType.String);
SQLiteParameter p16 = new SQLiteParameter("@P16", DbType.String);
SQLiteParameter p17 = new SQLiteParameter("@P17", DbType.String);
SQLiteParameter p18 = new SQLiteParameter("@P18", DbType.String);
SQLiteParameter idParam = new SQLiteParameter("@ID", DbType.Int32);
insertCmd.Parameters.AddRange(new[] { p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18 });
updateCmd.Parameters.AddRange(new[] { p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, idParam });
string[] csvLines = File.ReadAllLines(csvFilePath);
int updateCnt = 0, insertCnt = 0;
for (int i = 0; i < csvLines.Length; i++)
{
string line = csvLines[i];
string[] elems = line.Split(',');
if (elems.Length < 12) continue;
string country = elems[1].Trim().Replace("\"", "");
if (country.Length < 2) continue;
string code = elems[2].Trim().Replace("\"", "");
if (code.Length < 3) continue;
currentLocodes.Add(country + code);
ccode.Value = country;
lcode.Value = code;
// Eingabeformat: https://service.unece.org/trade/locode/Service/LocodeColumn.htm
object lookupResult = lookupCmd.ExecuteScalar();
if ((lookupResult != null) && (lookupResult != DBNull.Value))
{
int lid = Convert.ToInt32(lookupResult);
p3.Value = elems[3].Trim().Replace("\"", "");
p4.Value = elems[4].Trim().Replace("\"", "");
p5.Value = elems[5].Trim().Replace("\"", "");
SetBoolParamsFromFunctionString(elems[6].Trim().Replace("\"", ""), p6, p7, p8, p9, p10, p11, p12, p13);
p14.Value = elems[7].Trim().Replace("\"", "");
p15.Value = elems[8].Trim().Replace("\"", "");
p16.Value = elems[9].Trim().Replace("\"", "");
p17.Value = elems[10].Trim().Replace("\"", "");
p18.Value = elems[11].Trim().Replace("\"", "");
idParam.Value = lid;
if (updateCmd.ExecuteNonQuery() == 0)
{
_log.WarnFormat("Update of {0} affected no rows.", lid);
}
// UPDATE entry
updateCnt++;
}
else
{
if(!countryDict.ContainsKey(country))
{
_log.WarnFormat("Country {0} not in dictionary!", country);
continue;
}
p1.Value = countryDict[country];
p2.Value = code;
p3.Value = elems[3].Trim().Replace("\"", "");
p4.Value = elems[4].Trim().Replace("\"", "");
p5.Value = elems[5].Trim().Replace("\"", "");
SetBoolParamsFromFunctionString(elems[6].Trim().Replace("\"", ""), p6, p7, p8, p9, p10, p11, p12, p13);
p14.Value = elems[7].Trim().Replace("\"", "");
p15.Value = elems[8].Trim().Replace("\"", "");
p16.Value = elems[9].Trim().Replace("\"", "");
p17.Value = elems[10].Trim().Replace("\"", "");
p18.Value = elems[11].Trim().Replace("\"", "");
if (insertCmd.ExecuteNonQuery() == 0)
{
_log.Warn("Insert of {0} affected no rows.");
}
// CREATE new entry
insertCnt++;
}
Console.Write($"\r({i}/{csvLines.Length})");
}
Console.Write("\n");
Console.WriteLine($"{insertCnt} new entries, {updateCnt} updated");
// jetzt durch alle Ids in der DB laufen und mit dem Import vergleichen
List<int> deleteIds = new List<int>();
SQLiteCommand cmd = new SQLiteCommand(connection);
cmd.CommandText = "SELECT countries.code, locodes.id, locodes.city_code FROM countries INNER JOIN locodes on locodes.country_id = countries.id";
SQLiteDataReader reader2 = cmd.ExecuteReader();
while (reader2.Read())
{
if (reader2.IsDBNull(2))
{
deleteIds.Add(reader2.GetInt32(1));
}
else
{
string locode = reader2.GetString(0) + reader2.GetString(2);
if (locode.Equals("ZZUKN")) continue;
if (locode.Equals("ZZNOK")) continue;
if (!currentLocodes.Contains(locode))
deleteIds.Add(reader2.GetInt32(1));
}
}
Console.WriteLine($"deleting {deleteIds.Count} obsolete entries");
SQLiteCommand delCmd = new SQLiteCommand(connection);
delCmd.CommandText = "DELETE FROM locodes where id = @DELID";
// diejenigen löschen, die nicht mehr in der Quell CSV Datei auftauchen
foreach (int deleteId in deleteIds)
{
delCmd.Parameters.AddWithValue("@DELID", deleteId);
if (delCmd.ExecuteNonQuery() != 1)
_log.WarnFormat("{0} affected no rows", deleteId);
}
}
}
private static void SetBoolParamsFromFunctionString(string func, SQLiteParameter p6, SQLiteParameter p7, SQLiteParameter p8,
SQLiteParameter p9, SQLiteParameter p10, SQLiteParameter p11, SQLiteParameter p12, SQLiteParameter p13)
{
if (func.Length < 8) return;
p6.Value = (func[0] == '1');
p7.Value = (func[1] == '2');
p8.Value = (func[2] == '3');
p9.Value = (func[3] == '4');
p10.Value = (func[4] == '5');
p11.Value = (func[5] == '6');
p12.Value = (func[6] == '7');
p13.Value = (func[7] == 'B');
}
}
}

View File

@ -7,10 +7,7 @@
//
// Copyright (c) 2015 Informatikbüro Daniel Schick. All rights reserved.
using System;
using System.Collections.Generic;
using CommandLine;
using CommandLine.Text;
namespace bsmd.Tool
{
@ -19,30 +16,28 @@ namespace bsmd.Tool
[Option('c', "core", Required=false, HelpText="MessageCoreId to process")]
public string MessageCoreId { get; set; }
[Option('v',"verbose", DefaultValue=true, HelpText="print messages to console")]
[Option('v',"verbose", Default=true, HelpText="print messages to console")]
public bool Verbose { get; set; }
[Option('r', "checkrules", MutuallyExclusiveSet = "command", HelpText = "Use rule engine on message core")]
[Option('r', "checkrules", HelpText = "Use rule engine on message core")]
public bool CheckRules { get; set; }
[Option('s', "staledays", DefaultValue = 30, HelpText ="Delete files older than X days")]
[Option("locodes", HelpText = "use this flag if you want to import locodes")]
public bool ImportLocodes { get; set; }
[Option('s', "staledays", Default = 30, HelpText ="Delete files older than X days")]
public int StaleDays { get; set; }
[Option('p', "path", HelpText ="Path to cleanup root folder")]
public string CleanupFolderRoot { get; set; }
[Option('x', "recursive", DefaultValue = false, HelpText ="Cleanup subdirectories recursively")]
[Option('x', "recursive", Default = false, HelpText ="Cleanup subdirectories recursively")]
public bool CleanupRecursive { get; set; }
[ParserState]
public IParserState LastParserState { get; set; }
[HelpOption]
public string GetUsage()
{
return HelpText.AutoBuild(this, (HelpText current) => HelpText.DefaultParsingErrorsHandler(this, current));
}
[Option("csv", HelpText = "PATH to import LOCODE csv")]
public string LocodeCSV { get; set; }
[Option("db", HelpText = "PATH to locode db (SQLITE)")]
public string LocodeDB { get; set; }
}
}

View File

@ -1,28 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CommandLine;
using log4net;
using System;
namespace bsmd.Tool
{
class Program
public static class Program
{
private static ILog log = LogManager.GetLogger("Tool");
private static readonly ILog log = LogManager.GetLogger("Tool");
static int Main(string[] args)
public static int Main(string[] args)
{
int result = 0;
log4net.Config.XmlConfigurator.Configure();
Options options = new Options();
if (CommandLine.Parser.Default.ParseArguments(args, options))
try
{
try
Parser.Default.ParseArguments<Options>(args).WithParsed<Options>(o =>
{
if (options.CheckRules)
if (o.CheckRules)
{
Guid coreId;
if (Guid.TryParse(options.MessageCoreId, out coreId))
if (Guid.TryParse(options.MessageCoreId, out Guid coreId))
{
CheckRules.Check(coreId);
}
@ -32,27 +29,27 @@ namespace bsmd.Tool
log.FatalFormat("CheckRules: cannot parse message core id");
}
}
else if((options.CleanupFolderRoot != null) && (options.CleanupFolderRoot.Length > 0))
if (!string.IsNullOrEmpty(o.CleanupFolderRoot))
{
CleanupFiles.Cleanup(options.CleanupFolderRoot, options.StaleDays, options.CleanupRecursive);
}
else
if(o.ImportLocodes)
{
if(!string.IsNullOrEmpty(o.LocodeCSV) && !string.IsNullOrEmpty(o.LocodeDB))
{
LocodeSQliteImport.Import(o.LocodeDB, o.LocodeCSV);
}
}
return 0;
}
catch (Exception ex)
{
log.ErrorFormat("an exception occurred: {0}", ex.Message);
return 1;
}
});
}
else
catch (Exception ex)
{
Console.WriteLine(options.GetUsage());
return 1;
log.Fatal(ex.ToString());
result = 1;
}
Console.Read();
return result;
}
}
}

View File

@ -12,7 +12,7 @@ namespace bsmd.Tool.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));

View File

@ -9,8 +9,11 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>bsmd.Tool</RootNamespace>
<AssemblyName>bsmd.Tool</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@ -38,15 +41,23 @@
<AssemblyOriginatorKeyFile>..\bsmdKey.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="CommandLine">
<HintPath>..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll</HintPath>
<Reference Include="bsmd.database">
<HintPath>..\bsmd.database\bin\Debug\bsmd.database.dll</HintPath>
</Reference>
<Reference Include="log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.2.0.8\lib\net45-full\log4net.dll</HintPath>
<Private>True</Private>
<Reference Include="CommandLine, Version=2.9.1.0, Culture=neutral, PublicKeyToken=5a870481e358d379, processorArchitecture=MSIL">
<HintPath>..\packages\CommandLineParser.2.9.1\lib\net461\CommandLine.dll</HintPath>
</Reference>
<Reference Include="log4net, Version=2.0.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.2.0.15\lib\net45\log4net.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Data.SQLite, Version=1.0.117.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
<HintPath>..\packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.117.0\lib\net46\System.Data.SQLite.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
@ -65,6 +76,7 @@
</Compile>
<Compile Include="CheckRules.cs" />
<Compile Include="CleanupFiles.cs" />
<Compile Include="LocodeSQliteImport.cs" />
<Compile Include="Options.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
@ -83,13 +95,14 @@
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\bsmd.database\bsmd.database.csproj">
<Project>{19945af2-379b-46a5-b27a-303b5ec1d557}</Project>
<Name>bsmd.database</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.117.0\build\net46\Stub.System.Data.SQLite.Core.NetFramework.targets" Condition="Exists('..\packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.117.0\build\net46\Stub.System.Data.SQLite.Core.NetFramework.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.117.0\build\net46\Stub.System.Data.SQLite.Core.NetFramework.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.117.0\build\net46\Stub.System.Data.SQLite.Core.NetFramework.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<StartArguments>-s 100 -p E:\svnlager\BSMD\nsw\HIS-NORD\Transmitter-Tool -x</StartArguments>
<StartArguments>--locodes --csv="C:\svn_lager\bsmd\nsw\Archiv\2022-2.UNLOCODE.all.csv" --db "C:\git_lager\git_bsmd\misc\db.sqlite"</StartArguments>
</PropertyGroup>
</Project>

View File

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="CommandLineParser" version="1.9.71" targetFramework="net45" />
<package id="log4net" version="2.0.8" targetFramework="net45" />
<package id="CommandLineParser" version="2.9.1" targetFramework="net48" />
<package id="log4net" version="2.0.15" targetFramework="net48" />
<package id="Stub.System.Data.SQLite.Core.NetFramework" version="1.0.117.0" targetFramework="net48" />
<package id="System.Data.SQLite.Core" version="1.0.117.0" targetFramework="net48" />
</packages>

View File

@ -543,6 +543,7 @@ namespace bsmd.database
foreach(IGCPosition igc in this.IGCPositions)
{
RuleEngine.ValidateProperties(igc, errors, violations);
igc.Validate(errors, violations);
}
foreach(IMSBCPosition imsbc in this.IMSBCPositions)

View File

@ -12,6 +12,7 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
namespace bsmd.database
@ -27,6 +28,13 @@ namespace bsmd.database
this.tablename = "[dbo].[IGCPosition]";
}
#region static regex
private static readonly Regex unNumberRegex = new Regex("^[0-9]{4}$");
private static readonly Regex imoClassRegex = new Regex(@"^[1-9]{1}(\.[1-9]{1})?$");
#endregion
#region Properties
[JsonIgnore]
@ -189,6 +197,19 @@ namespace bsmd.database
#endregion
#region Validation
public override void Validate(List<MessageError> errors, List<MessageViolation> violations)
{
if (!this.UNNumber.IsNullOrEmpty() && !unNumberRegex.IsMatch(this.UNNumber))
violations.Add(RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "UNNumber", null, this.Title, this.Identifier, this.HAZ.IsDeparture ? "HAZD" : "HAZA"));
if (!this.IMOClass.IsNullOrEmpty() && !imoClassRegex.IsMatch(this.IMOClass))
violations.Add(RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "IMOClass", null, this.Title, this.Identifier, this.HAZ.IsDeparture ? "HAZD" : "HAZA"));
}
#endregion
}
}

View File

@ -28,6 +28,13 @@ namespace bsmd.database
this.tablename = "[dbo].[IMDGPosition]";
}
#region static Regex
private static Regex imoClassRegex = new Regex(@"^[1-9]{1}(\.[1-9]{1}([A-Z]{1})?)?$");
private static Regex unNumberRegex = new Regex(@"^[0-9]{4}$");
#endregion
#region Properties
[JsonIgnore]
@ -507,13 +514,16 @@ namespace bsmd.database
if(!this.IMOClass.IsNullOrEmpty())
{
const string pattern = @"^[1-9]{1}(\.[1-9]{1}([A-Z]{1})?)?$";
Regex regex = new Regex(pattern);
if (!regex.IsMatch(this.IMOClass))
if (!imoClassRegex.IsMatch(this.IMOClass))
errors.Add(RuleEngine.CreateError(ValidationCode.IMPLAUSIBLE, "IMOClass", null, this.Title, this.Identifier, this.HAZ.IsDeparture ? "HAZD" : "HAZA"));
}
if(!this.UNNumber.IsNullOrEmpty())
{
if(!unNumberRegex.IsMatch(this.UNNumber))
errors.Add(RuleEngine.CreateError(ValidationCode.IMPLAUSIBLE, "UNNumber", null, this.Title, this.Identifier, this.HAZ.IsDeparture ? "HAZD" : "HAZA"));
}
if (!this.StowagePosition.IsNullOrEmpty() && (!this.Bay.IsNullOrEmpty() || !this.Row.IsNullOrEmpty() || !this.Tier.IsNullOrEmpty()))
{
errors.Add(RuleEngine.CreateError(ValidationCode.IMPLAUSIBLE, "StowagePosition AND Bay/Row/Tier SET", null, this.Title, this.Identifier, this.HAZ.IsDeparture ? "HAZD" : "HAZA"));

View File

@ -12,6 +12,7 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
namespace bsmd.database
@ -22,6 +23,8 @@ namespace bsmd.database
public class IMSBCPosition : DatabaseEntity, ISublistElement
{
#region static defs
public static string[] hazardClass =
{
"A",
@ -29,6 +32,11 @@ namespace bsmd.database
"A and B"
};
private static readonly Regex unNumberRegex = new Regex("^[0-9]{4}$");
private static readonly Regex imoClassRegex = new Regex(@"^[1-9]{1}(\.[1-9]{1})?$");
#endregion
public IMSBCPosition()
{
this.tablename = "[dbo].[IMSBCPosition]";
@ -230,15 +238,23 @@ namespace bsmd.database
{
if(!MHB ?? false)
{
if(this.UNNumber.IsNullOrEmpty() || this.IMOClass.IsNullOrEmpty())
violations.Add(RuleEngine.CreateViolation(ValidationCode.V803, null, null, this.Title, this.Identifier, this.HAZ.IsDeparture ? "HAZD" : "HAZA"));
if(this.UNNumber.IsNullOrEmpty())
violations.Add(RuleEngine.CreateViolation(ValidationCode.V803, "UNNumber", this.UNNumber, this.Title, this.Identifier, this.HAZ.IsDeparture ? "HAZD" : "HAZA"));
if (this.IMOClass.IsNullOrEmpty())
violations.Add(RuleEngine.CreateViolation(ValidationCode.V803, "IMOClass", this.IMOClass, this.Title, this.Identifier, this.HAZ.IsDeparture ? "HAZD" : "HAZA"));
}
if(!this.UNNumber.IsNullOrEmpty() && !unNumberRegex.IsMatch(this.UNNumber))
violations.Add(RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "UNNumber", null, this.Title, this.Identifier, this.HAZ.IsDeparture ? "HAZD" : "HAZA"));
if(!this.IMOClass.IsNullOrEmpty() && !imoClassRegex.IsMatch(this.IMOClass))
violations.Add(RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "IMOClass", null, this.Title, this.Identifier, this.HAZ.IsDeparture ? "HAZD" : "HAZA"));
if (!this.IMOHazardClass.HasValue)
{
violations.Add(RuleEngine.CreateViolation(ValidationCode.V810, "Hazards", null, this.Title, this.Identifier, this.HAZ.IsDeparture ? "HAZD" : "HAZA"));
}
}
#endregion

View File

@ -258,9 +258,9 @@ namespace bsmd.database
/// </summary>
public int CompareTo(MaerskData other)
{
if (this.ColA == null) return 0;
if (other == null) return 0;
return this.ColA.CompareTo(other.ColA);
if (this.ETA == null) return 0;
if ((other == null) || (other.ETA == null)) return 0;
return this.ETA.Value.CompareTo(other.ETA.Value);
}
public bool Update(MaerskData md)

View File

@ -2,6 +2,6 @@
[assembly: AssemblyCompany("schick Informatik")]
[assembly: AssemblyProduct("BSMD NSW interface")]
[assembly: AssemblyInformationalVersion("7.10.0")]
[assembly: AssemblyInformationalVersion("7.11.0")]
[assembly: AssemblyCopyright("Copyright © 2014-2023 schick Informatik")]
[assembly: AssemblyTrademark("")]

View File

@ -1,4 +1,4 @@
using System.Reflection;
[assembly: AssemblyVersion("7.10.0.*")]
[assembly: AssemblyVersion("7.11.0.*")]

Binary file not shown.