WASExemptions stored for special check regarding individual vessels and ports
This commit is contained in:
parent
96a311ba18
commit
fbf595ffd4
@ -4,6 +4,7 @@
|
||||
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="800">
|
||||
@ -28,13 +29,15 @@
|
||||
<ColumnDefinition Width="50" />
|
||||
<ColumnDefinition Width="30" />
|
||||
<ColumnDefinition Width="120" />
|
||||
<ColumnDefinition Width="80" />
|
||||
<ColumnDefinition Width="120" />
|
||||
<ColumnDefinition Width="120" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="140" />
|
||||
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
|
||||
<Button x:Name="buttonSave" Grid.Column="6" Margin="2" Content="Save all changes" Click="buttonSave_Click" />
|
||||
<Button x:Name="buttonDeleteExpired" Grid.Column="7" Margin="2" Content="Delete expired" Click="buttonDeleteExpired_Click" />
|
||||
<Button x:Name="buttonAdd" Grid.Column="8" Margin="2" Content="Add new" Click="buttonAdd_Click" />
|
||||
<Button x:Name="buttonImport" Grid.Column="9" Margin="2" Content="{x:Static p:Resources.textImportFromExcel}" Click="buttonImport_Click" />
|
||||
|
||||
</Grid>
|
||||
@ -44,17 +47,64 @@
|
||||
<local:ENIDataGrid.RowStyle>
|
||||
<Style TargetType="DataGridRow">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Value}" Value="*">
|
||||
<Setter Property="Background" Value="Pink"></Setter>
|
||||
<DataTrigger Binding="{Binding ValidUntil, Converter={util:ExpiryStateConverter}}" Value="Expired">
|
||||
<Setter Property="Background" Value="LightGray" />
|
||||
<Setter Property="Foreground" Value="Gray" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding ValidUntil, Converter={util:ExpiryStateConverter}}" Value="ExpiringSoon">
|
||||
<Setter Property="Background" Value="LightYellow" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</local:ENIDataGrid.RowStyle>
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn x:Name="columnIMO" Header="IMO" Binding="{Binding IMO, Mode=TwoWay}" IsReadOnly="False" />
|
||||
<DataGridTextColumn x:Name="columnShipName" Header="Ship name" Binding="{Binding ShipName, Mode=TwoWay}" IsReadOnly="False" />
|
||||
<DataGridTextColumn x:Name="columnPort" Header="Port" Binding="{Binding Port, Mode=TwoWay}" IsReadOnly="False" />
|
||||
<DataGridTextColumn x:Name="columnValidUntil" Header="ValidUntil" Binding="{Binding ValidUntil, Mode=TwoWay}" IsReadOnly="False" />
|
||||
<DataGridTextColumn x:Name="columnIMO" Header="IMO" IsReadOnly="False">
|
||||
<DataGridTextColumn.Binding>
|
||||
<Binding Path="IMO" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
|
||||
<Binding.ValidationRules>
|
||||
<util:RequiredStringValidationRule />
|
||||
<util:StringValidationRule MaxLength="7" />
|
||||
</Binding.ValidationRules>
|
||||
</Binding>
|
||||
</DataGridTextColumn.Binding>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn x:Name="columnShipName" Header="Ship name" IsReadOnly="False">
|
||||
<DataGridTextColumn.Binding>
|
||||
<Binding Path="ShipName" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
|
||||
<Binding.ValidationRules>
|
||||
<util:StringValidationRule MaxLength="100" />
|
||||
</Binding.ValidationRules>
|
||||
</Binding>
|
||||
</DataGridTextColumn.Binding>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn x:Name="columnPort" Header="Port" IsReadOnly="False">
|
||||
<DataGridTextColumn.Binding>
|
||||
<Binding Path="Port" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
|
||||
<Binding.ValidationRules>
|
||||
<util:RequiredStringValidationRule />
|
||||
<util:StringValidationRule MaxLength="5" />
|
||||
</Binding.ValidationRules>
|
||||
</Binding>
|
||||
</DataGridTextColumn.Binding>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn x:Name="columnValidUntil" Header="ValidUntil" IsReadOnly="False">
|
||||
<DataGridTextColumn.Binding>
|
||||
<Binding Path="ValidUntil" Mode="TwoWay" StringFormat="{}{0:d}" UpdateSourceTrigger="PropertyChanged">
|
||||
<Binding.ValidationRules>
|
||||
<util:RequiredDateValidationRule />
|
||||
</Binding.ValidationRules>
|
||||
</Binding>
|
||||
</DataGridTextColumn.Binding>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn x:Name="columnRemarks" Header="Remarks" IsReadOnly="False" Width="*">
|
||||
<DataGridTextColumn.Binding>
|
||||
<Binding Path="Remarks" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
|
||||
<Binding.ValidationRules>
|
||||
<util:StringValidationRule MaxLength="255" />
|
||||
</Binding.ValidationRules>
|
||||
</Binding>
|
||||
</DataGridTextColumn.Binding>
|
||||
</DataGridTextColumn>
|
||||
</DataGrid.Columns>
|
||||
</local:ENIDataGrid>
|
||||
</Grid>
|
||||
|
||||
@ -1,17 +1,14 @@
|
||||
using System;
|
||||
using bsmd.database;
|
||||
using ENI2.Excel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace ENI2.Controls
|
||||
{
|
||||
@ -20,34 +17,246 @@ namespace ENI2.Controls
|
||||
/// </summary>
|
||||
public partial class WASExemptionsControl : UserControl
|
||||
{
|
||||
private DataGridColumn _editColumn;
|
||||
private object _editOriginalValue;
|
||||
|
||||
public WASExemptionsControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.dataGridWASExemptions.ItemsSource = WASExemption.Exemptions;
|
||||
var view = CollectionViewSource.GetDefaultView(WASExemption.Exemptions);
|
||||
view.SortDescriptions.Add(new SortDescription(nameof(WASExemption.ShipName), ListSortDirection.Ascending));
|
||||
_ = WASExemption.EnsureLoadedAsync();
|
||||
|
||||
this.dataGridWASExemptions.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.dataGridWASExemptions.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.dataGridWASExemptions.ContextMenu.Items.Add(delItem);
|
||||
}
|
||||
|
||||
private void buttonSave_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
|
||||
_ = SaveExemptionsAsync();
|
||||
}
|
||||
|
||||
private void buttonImport_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var imported = ExcelLocalImportHelper.ImportWASExemptions();
|
||||
int skipped = 0;
|
||||
foreach (var exemption in imported)
|
||||
{
|
||||
if (IsDuplicateIMOAndPort(exemption, exemption.IMO, exemption.Port))
|
||||
{
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
WASExemption.Exemptions.Add(exemption);
|
||||
}
|
||||
|
||||
if (skipped > 0)
|
||||
{
|
||||
MessageBox.Show($"{skipped} duplicate rows were skipped (same IMO and Port).",
|
||||
Properties.Resources.textCaptionError, MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
private void buttonAdd_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
AddNewExemption();
|
||||
}
|
||||
|
||||
private async void buttonDeleteExpired_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (MessageBox.Show("Delete all expired exemptions?", Properties.Resources.textConfirmation, MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) != MessageBoxResult.Yes)
|
||||
return;
|
||||
|
||||
DateTime today = DateTime.Today;
|
||||
var toRemove = new List<WASExemption>();
|
||||
|
||||
foreach (var exemption in WASExemption.Exemptions)
|
||||
{
|
||||
if (exemption.ValidUntil.Date < today)
|
||||
{
|
||||
int result = await DBManagerAsync.DeleteAsync(exemption);
|
||||
if (result == 1 || exemption.IsNew)
|
||||
{
|
||||
toRemove.Add(exemption);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var exemption in toRemove)
|
||||
{
|
||||
WASExemption.Exemptions.Remove(exemption);
|
||||
}
|
||||
}
|
||||
|
||||
private void dataGridWASExemptions_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
|
||||
{
|
||||
if (e.Row?.Item is WASExemption exemption)
|
||||
{
|
||||
if (e.Column == columnIMO || e.Column == columnPort)
|
||||
{
|
||||
string newValue = (e.EditingElement as TextBox)?.Text?.Trim();
|
||||
string imo = e.Column == columnIMO ? newValue : exemption.IMO?.Trim();
|
||||
string port = e.Column == columnPort ? newValue : exemption.Port?.Trim();
|
||||
|
||||
if (!imo.IsNullOrEmpty() && !port.IsNullOrEmpty())
|
||||
{
|
||||
if (IsDuplicateIMOAndPort(exemption, imo, port))
|
||||
{
|
||||
MessageBox.Show("Duplicate entry detected. IMO can only appear once per Port.",
|
||||
Properties.Resources.textCaptionError, MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
|
||||
if (e.EditingElement is TextBox tb)
|
||||
{
|
||||
tb.Text = _editOriginalValue as string ?? "";
|
||||
}
|
||||
e.Cancel = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exemption.IsDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void dataGridWASExemptions_BeginningEdit(object sender, DataGridBeginningEditEventArgs e)
|
||||
{
|
||||
|
||||
_editColumn = e.Column;
|
||||
if (e.Row?.Item is WASExemption exemption)
|
||||
{
|
||||
if (e.Column == columnIMO)
|
||||
_editOriginalValue = exemption.IMO;
|
||||
else if (e.Column == columnPort)
|
||||
_editOriginalValue = exemption.Port;
|
||||
else
|
||||
_editOriginalValue = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void dataGridWASExemptions_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void AddItem_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
AddNewExemption();
|
||||
}
|
||||
|
||||
private async void DelItem_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (this.dataGridWASExemptions.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<WASExemption>();
|
||||
foreach (WASExemption was in this.dataGridWASExemptions.SelectedItems)
|
||||
selectedItems.Add(was);
|
||||
|
||||
foreach (WASExemption was in selectedItems)
|
||||
{
|
||||
int result = await DBManagerAsync.DeleteAsync(was);
|
||||
if (result == 1 || was.IsNew)
|
||||
{
|
||||
WASExemption.Exemptions.Remove(was);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddNewExemption()
|
||||
{
|
||||
var exemption = new WASExemption
|
||||
{
|
||||
ValidUntil = DateTime.Today,
|
||||
IsDirty = true
|
||||
};
|
||||
WASExemption.Exemptions.Add(exemption);
|
||||
this.dataGridWASExemptions.SelectedItem = exemption;
|
||||
this.dataGridWASExemptions.ScrollIntoView(exemption);
|
||||
}
|
||||
|
||||
private async Task SaveExemptionsAsync()
|
||||
{
|
||||
int totalSaves = 0;
|
||||
var invalids = new List<WASExemption>();
|
||||
|
||||
foreach (var exemption in WASExemption.Exemptions)
|
||||
{
|
||||
if (exemption.IsNew || exemption.IsDirty)
|
||||
{
|
||||
if (!IsValid(exemption))
|
||||
{
|
||||
invalids.Add(exemption);
|
||||
continue;
|
||||
}
|
||||
totalSaves += await DBManagerAsync.SaveAsync(exemption);
|
||||
}
|
||||
}
|
||||
|
||||
if (invalids.Count > 0)
|
||||
{
|
||||
MessageBox.Show(
|
||||
"Some rows are missing required fields (IMO, Port, ValidUntil) and were not saved.",
|
||||
Properties.Resources.textCaptionError,
|
||||
MessageBoxButton.OK,
|
||||
MessageBoxImage.Warning);
|
||||
}
|
||||
|
||||
if (totalSaves > 0)
|
||||
{
|
||||
MessageBox.Show($"{totalSaves} WAS exemptions saved", "Success", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsValid(WASExemption exemption)
|
||||
{
|
||||
if (exemption == null)
|
||||
return false;
|
||||
|
||||
if (exemption.IMO.IsNullOrEmpty())
|
||||
return false;
|
||||
|
||||
if (exemption.Port.IsNullOrEmpty())
|
||||
return false;
|
||||
|
||||
if (exemption.ValidUntil == default(DateTime))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool IsDuplicateIMOAndPort(WASExemption current, string imo, string port)
|
||||
{
|
||||
if (imo.IsNullOrEmpty() || port.IsNullOrEmpty())
|
||||
return false;
|
||||
|
||||
string imoKey = imo.Trim();
|
||||
string portKey = port.Trim();
|
||||
|
||||
return WASExemption.Exemptions.Any(x =>
|
||||
!ReferenceEquals(x, current) &&
|
||||
!x.IMO.IsNullOrEmpty() &&
|
||||
!x.Port.IsNullOrEmpty() &&
|
||||
string.Equals(x.IMO.Trim(), imoKey, StringComparison.OrdinalIgnoreCase) &&
|
||||
string.Equals(x.Port.Trim(), portKey, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1231,7 +1231,7 @@ namespace ENI2
|
||||
|
||||
#endregion
|
||||
|
||||
#region WAS special max capa rules regarding next port
|
||||
#region WAS special max capa rules regarding next port + exemption list
|
||||
|
||||
{
|
||||
string wasMessageGroup = this.MessageGroupForMessage(wasMessage);
|
||||
@ -1242,6 +1242,40 @@ namespace ENI2
|
||||
NOA_NOD noa_nod = noanodMessage.Elements[0] as NOA_NOD;
|
||||
WAS was = wasMessage.Elements[0] as WAS;
|
||||
|
||||
bool shipHasCurrentExemption = false;
|
||||
|
||||
DateTime eta_actual = DateTime.Now;
|
||||
if(this.Core.IsTransit && noa_nod.ETAToKielCanal.HasValue)
|
||||
eta_actual = noa_nod.ETAToKielCanal.Value.Date;
|
||||
else if(!this.Core.IsTransit && noa_nod.ETAToPortOfCall.HasValue)
|
||||
eta_actual = noa_nod.ETAToPortOfCall.Value.Date;
|
||||
|
||||
foreach (WASExemption we in WASExemption.Exemptions)
|
||||
{
|
||||
if(we.IMO.Equals(this.Core.IMO) && we.Port.Equals(this.Core.PoC))
|
||||
{
|
||||
if(we.ValidUntil.Date.AddDays(1) > eta_actual)
|
||||
{
|
||||
shipHasCurrentExemption = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!(was.WasteDisposalValidExemption ?? false) && shipHasCurrentExemption)
|
||||
{
|
||||
MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Note: Valid waste exemption noted", null, "Waste", null, "WAS");
|
||||
mv.MessageGroupName = wasMessageGroup;
|
||||
vViolations.Add(mv);
|
||||
}
|
||||
|
||||
if ((was.WasteDisposalValidExemption ?? false) && !shipHasCurrentExemption)
|
||||
{
|
||||
MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Note: No valid waste exemption noted. Please check", null, "Waste", null, "WAS");
|
||||
mv.MessageGroupName = wasMessageGroup;
|
||||
vViolations.Add(mv);
|
||||
}
|
||||
|
||||
bool isSpecialNextPort = RuleEngine.IsSpecialNextPort(noa_nod.NextPort);
|
||||
|
||||
if (isSpecialNextPort)
|
||||
|
||||
@ -589,11 +589,14 @@
|
||||
<Compile Include="Util\EnumToCollectionConverter.cs" />
|
||||
<Compile Include="Util\ExpandableListConverter.cs" />
|
||||
<Compile Include="Util\Extensions.cs" />
|
||||
<Compile Include="Util\ExpiryStateConverter.cs" />
|
||||
<Compile Include="Util\GlobalStructures.cs" />
|
||||
<Compile Include="Util\HighlightService.cs" />
|
||||
<Compile Include="Util\InverseBooleanConverter.cs" />
|
||||
<Compile Include="Util\NullImageConverter.cs" />
|
||||
<Compile Include="Util\NumberValidationRule.cs" />
|
||||
<Compile Include="Util\RequiredDateValidationRule.cs" />
|
||||
<Compile Include="Util\RequiredStringValidationRule.cs" />
|
||||
<Compile Include="Util\SettingBindingExtension.cs" />
|
||||
<Compile Include="Util\StringValidationRule.cs" />
|
||||
<Compile Include="Util\TrimStringConverter.cs" />
|
||||
@ -1033,7 +1036,7 @@
|
||||
<Resource Include="Resources\trafficlight_off.png" />
|
||||
<Resource Include="Resources\trafficlight_red.png" />
|
||||
<Resource Include="Resources\trafficlight_yellow.png" />
|
||||
<None Include="Resources\user_edit.png" />
|
||||
<Resource Include="Resources\user_edit.png" />
|
||||
<Resource Include="Resources\delete2.png" />
|
||||
<None Include="Resources\mail_new.png" />
|
||||
<Resource Include="Resources\document_view.png" />
|
||||
|
||||
@ -329,5 +329,81 @@ namespace ENI2.Excel
|
||||
|
||||
#endregion
|
||||
|
||||
#region WAS Exemptions Import from Excel
|
||||
|
||||
public static List<WASExemption> ImportWASExemptions()
|
||||
{
|
||||
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); // first row is header
|
||||
int columnCount = range.ColumnCount();
|
||||
|
||||
if (columnCount < 5)
|
||||
{
|
||||
throw new InvalidDataException("Sheet must have at least 5 Columns of data");
|
||||
}
|
||||
|
||||
List<WASExemption> exemptions = new List<WASExemption>();
|
||||
|
||||
foreach (var row in rows)
|
||||
{
|
||||
if (row.Cell(1).IsEmpty() && row.Cell(2).IsEmpty() && row.Cell(3).IsEmpty())
|
||||
continue;
|
||||
|
||||
WASExemption was = new WASExemption();
|
||||
|
||||
if (!row.Cell(1).IsEmpty())
|
||||
was.IMO = Truncate(row.Cell(1).GetString().Trim(), 7);
|
||||
if (!row.Cell(2).IsEmpty())
|
||||
was.ShipName = Truncate(row.Cell(2).GetString().Trim(), 100);
|
||||
if (!row.Cell(3).IsEmpty())
|
||||
was.Port = Truncate(row.Cell(3).GetString().Trim(), 5);
|
||||
|
||||
if (!row.Cell(4).IsEmpty())
|
||||
was.ValidUntil = row.Cell(4).GetDateTime();
|
||||
else
|
||||
throw new InvalidDataException($"Missing ValidUntil value in row {row.RowNumber()}");
|
||||
|
||||
if (!row.Cell(5).IsEmpty())
|
||||
was.Remarks = Truncate(row.Cell(5).GetString().Trim(), 255);
|
||||
|
||||
was.IsDirty = true;
|
||||
exemptions.Add(was);
|
||||
}
|
||||
|
||||
return exemptions;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("Error reading Excel: " + ex.Message, Properties.Resources.textCaptionError,
|
||||
MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
return new List<WASExemption>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private static string Truncate(string value, int maxLength)
|
||||
{
|
||||
if (value == null)
|
||||
return null;
|
||||
return value.Length <= maxLength ? value : value.Substring(0, maxLength);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
43
ENI2/Util/ExpiryStateConverter.cs
Normal file
43
ENI2/Util/ExpiryStateConverter.cs
Normal file
@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Markup;
|
||||
|
||||
namespace ENI2.Util
|
||||
{
|
||||
public class ExpiryStateConverter : MarkupExtension, IValueConverter
|
||||
{
|
||||
private static ExpiryStateConverter _converter;
|
||||
|
||||
public override object ProvideValue(IServiceProvider serviceProvider)
|
||||
{
|
||||
if (_converter == null)
|
||||
{
|
||||
_converter = new ExpiryStateConverter();
|
||||
}
|
||||
return _converter;
|
||||
}
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (!(value is DateTime dt))
|
||||
return "Unknown";
|
||||
|
||||
DateTime today = DateTime.Today;
|
||||
DateTime validUntil = dt.Date;
|
||||
|
||||
if (validUntil < today)
|
||||
return "Expired";
|
||||
|
||||
if (validUntil <= today.AddMonths(1))
|
||||
return "ExpiringSoon";
|
||||
|
||||
return "Ok";
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
28
ENI2/Util/RequiredDateValidationRule.cs
Normal file
28
ENI2/Util/RequiredDateValidationRule.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace ENI2.Util
|
||||
{
|
||||
public class RequiredDateValidationRule : ValidationRule
|
||||
{
|
||||
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
|
||||
{
|
||||
if (value == null)
|
||||
return new ValidationResult(false, "Date is required");
|
||||
|
||||
if (value is DateTime dt)
|
||||
{
|
||||
if (dt == default(DateTime))
|
||||
return new ValidationResult(false, "Date is required");
|
||||
}
|
||||
else if (value is string text)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
return new ValidationResult(false, "Date is required");
|
||||
}
|
||||
|
||||
return ValidationResult.ValidResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
22
ENI2/Util/RequiredStringValidationRule.cs
Normal file
22
ENI2/Util/RequiredStringValidationRule.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using System.Globalization;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace ENI2.Util
|
||||
{
|
||||
public class RequiredStringValidationRule : ValidationRule
|
||||
{
|
||||
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
|
||||
{
|
||||
if (value == null)
|
||||
return new ValidationResult(false, "Value is required");
|
||||
|
||||
if (value is string text)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
return new ValidationResult(false, "Value is required");
|
||||
}
|
||||
|
||||
return ValidationResult.ValidResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8,8 +8,9 @@ BEGIN
|
||||
[Id] UNIQUEIDENTIFIER NOT NULL,
|
||||
[IMO] NCHAR (7) NOT NULL,
|
||||
[ShipName] NVARCHAR (100) NULL,
|
||||
[Port] NCHAR (70) NOT NULL,
|
||||
[Port] NCHAR (5) NOT NULL,
|
||||
[ValidUntil] DATETIME NOT NULL,
|
||||
[Remarks] NVARCHAR (255) NULL,
|
||||
PRIMARY KEY CLUSTERED ([Id] ASC)
|
||||
);
|
||||
PRINT N'Table [dbo].[WASExemption] created.';
|
||||
|
||||
@ -103,6 +103,15 @@ namespace bsmd.database
|
||||
return (await vm.LoadListAsync(reader)).ConvertAll(x => (ValueMapping)x);
|
||||
}
|
||||
|
||||
public static async Task<List<WASExemption>> LoadWASExemptionsAsync()
|
||||
{
|
||||
SqlCommand cmd = new SqlCommand();
|
||||
WASExemption was = new WASExemption();
|
||||
was.PrepareLoadCommand(cmd, Message.LoadFilter.ALL);
|
||||
SqlDataReader reader = await PerformCommandAsync(cmd);
|
||||
return (await was.LoadListAsync(reader)).ConvertAll(x => (WASExemption)x);
|
||||
}
|
||||
|
||||
public static async Task<List<AGNT_Template>> GetAGNTTemplatesAsync()
|
||||
{
|
||||
SqlCommand cmd = new SqlCommand();
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bsmd.database
|
||||
{
|
||||
@ -21,17 +23,67 @@ namespace bsmd.database
|
||||
|
||||
#region Properties
|
||||
|
||||
private static ObservableCollection<WASExemption> _exemptions;
|
||||
private static Task _loadTask;
|
||||
|
||||
public static ObservableCollection<WASExemption> Exemptions
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_exemptions == null)
|
||||
{
|
||||
_exemptions = new ObservableCollection<WASExemption>();
|
||||
_ = EnsureLoadedAsync();
|
||||
}
|
||||
return _exemptions;
|
||||
}
|
||||
}
|
||||
|
||||
[MaxLength(7)]
|
||||
public string IMO { get; set; }
|
||||
|
||||
[MaxLength(100)]
|
||||
public string ShipName { get; set; }
|
||||
|
||||
[MaxLength(70)]
|
||||
[MaxLength(5)]
|
||||
public string Port { get; set; }
|
||||
|
||||
public DateTime ValidUntil { get; set; }
|
||||
|
||||
[MaxLength(255)]
|
||||
public string Remarks { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Static loading
|
||||
|
||||
public static async Task EnsureLoadedAsync()
|
||||
{
|
||||
if (_exemptions == null)
|
||||
{
|
||||
_exemptions = new ObservableCollection<WASExemption>();
|
||||
}
|
||||
|
||||
if (_loadTask != null)
|
||||
{
|
||||
await _loadTask;
|
||||
return;
|
||||
}
|
||||
|
||||
_loadTask = LoadInternalAsync();
|
||||
await _loadTask;
|
||||
}
|
||||
|
||||
private static async Task LoadInternalAsync()
|
||||
{
|
||||
var exemptions = await DBManagerAsync.LoadWASExemptionsAsync();
|
||||
_exemptions.Clear();
|
||||
foreach (var exemption in exemptions)
|
||||
{
|
||||
_exemptions.Add(exemption);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region DatabaseEntity implementation
|
||||
@ -47,19 +99,21 @@ namespace bsmd.database
|
||||
if (this.Port != null) scmd.Parameters.AddWithValue("@P3", this.Port);
|
||||
else scmd.Parameters.AddWithValue("@P3", DBNull.Value);
|
||||
scmd.Parameters.AddWithValue("@P4", this.ValidUntil);
|
||||
if (this.Remarks != null) scmd.Parameters.AddWithValue("@P5", this.Remarks);
|
||||
else scmd.Parameters.AddWithValue("@P5", DBNull.Value);
|
||||
|
||||
if (this.IsNew)
|
||||
{
|
||||
this.CreateId();
|
||||
scmd.Parameters.AddWithValue("@ID", this.Id);
|
||||
cmd.CommandText = string.Format(
|
||||
"INSERT INTO {0} (Id, IMO, ShipName, Port, ValidUntil) VALUES (@ID, @P1, @P2, @P3, @P4)",
|
||||
"INSERT INTO {0} (Id, IMO, ShipName, Port, ValidUntil, Remarks) VALUES (@ID, @P1, @P2, @P3, @P4, @P5)",
|
||||
this.Tablename);
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd.CommandText = string.Format(
|
||||
"UPDATE {0} SET IMO = @P1, ShipName = @P2, Port = @P3, ValidUntil = @P4 WHERE Id = @ID",
|
||||
"UPDATE {0} SET IMO = @P1, ShipName = @P2, Port = @P3, ValidUntil = @P4, Remarks = @P5 WHERE Id = @ID",
|
||||
this.Tablename);
|
||||
scmd.Parameters.AddWithValue("@ID", this.Id);
|
||||
}
|
||||
@ -67,7 +121,7 @@ namespace bsmd.database
|
||||
|
||||
public override void PrepareLoadCommand(IDbCommand cmd, Message.LoadFilter filter, params object[] criteria)
|
||||
{
|
||||
string query = string.Format("SELECT Id, IMO, ShipName, Port, ValidUntil FROM {0}", this.Tablename);
|
||||
string query = string.Format("SELECT Id, IMO, ShipName, Port, ValidUntil, Remarks FROM {0}", this.Tablename);
|
||||
|
||||
switch (filter)
|
||||
{
|
||||
@ -90,6 +144,7 @@ namespace bsmd.database
|
||||
if (!reader.IsDBNull(2)) was.ShipName = reader.GetString(2);
|
||||
if (!reader.IsDBNull(3)) was.Port = reader.GetString(3);
|
||||
if (!reader.IsDBNull(4)) was.ValidUntil = reader.GetDateTime(4);
|
||||
if (!reader.IsDBNull(5)) was.Remarks = reader.GetString(5);
|
||||
|
||||
result.Add(was);
|
||||
}
|
||||
@ -108,6 +163,7 @@ namespace bsmd.database
|
||||
if (!reader.IsDBNull(2)) was.ShipName = reader.GetString(2);
|
||||
if (!reader.IsDBNull(3)) was.Port = reader.GetString(3);
|
||||
if (!reader.IsDBNull(4)) was.ValidUntil = reader.GetDateTime(4);
|
||||
if (!reader.IsDBNull(5)) was.Remarks = reader.GetString(5);
|
||||
}
|
||||
return was;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user