Version 6.0.10 abgeschlossen

This commit is contained in:
Daniel Schick 2021-01-20 09:07:12 +00:00
parent 6d2577631e
commit fb48538223
10 changed files with 307 additions and 126 deletions

View File

@ -26,12 +26,12 @@
<value>1000</value>
</setting>
<setting name="LockingServerAddress" serializeAs="String">
<!--value>http://192.168.2.24/LockingService/LockingService.svc</value-->
<value>http://heupferd/bsmd.LockingService/LockingService.svc</value>
<value>http://192.168.2.24/LockingService/LockingService.svc</value>
<!--value>http://heupferd/bsmd.LockingService/LockingService.svc</value-->
</setting>
<setting name="ConnectionString" serializeAs="String">
<!--value>Initial Catalog=nsw;Data Source=192.168.2.24\SQLEXPRESS;Uid=dfuser;pwd=dfpasswd;Persist Security Info=False;Connection Reset=false</value-->
<value>Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=E:\DATA\DB\NSW.MDF;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False</value>
<value>Initial Catalog=nsw;Data Source=192.168.2.24\SQLEXPRESS;Uid=dfuser;pwd=dfpasswd;Persist Security Info=False;Connection Reset=false</value>
<!--value>Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=E:\DATA\DB\NSW.MDF;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False</value-->
</setting>
</ENI2.Properties.Settings>
</applicationSettings>

View File

@ -29,6 +29,7 @@ namespace ENI2.DetailViewControls
private Timer _checkStatusTimer;
private DateTime _startStatusCheck;
private readonly object _collectionLock = new object();
private MessageSendStatusDialog mssd = null;
public OverViewDetailControl()
{
@ -267,101 +268,8 @@ namespace ENI2.DetailViewControls
#region Meldeklassen einrichten und Icons / Gruppen / Index zuordnen
foreach (Message aMessage in this.Messages)
{
switch (aMessage.MessageNotificationClass)
{
case Message.NotificationClass.VISIT:
case Message.NotificationClass.TRANSIT:
aMessage.ENINotificationDetailGroup = Properties.Resources.textOverview;
aMessage.ENINotificationIconString = "../Resources/documents.png";
aMessage.ENINotificationDetailIndex = 0;
break;
case Message.NotificationClass.NOA_NOD:
case Message.NotificationClass.AGNT:
aMessage.ENINotificationIconString = "../Resources/eye_blue.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textPortCall;
aMessage.ENINotificationDetailIndex = 1;
break;
case Message.NotificationClass.NAME:
case Message.NotificationClass.INFO:
case Message.NotificationClass.SERV:
case Message.NotificationClass.LADG:
aMessage.ENINotificationIconString = "../Resources/anchor.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textPortNotification;
aMessage.ENINotificationDetailIndex = 2;
break;
case Message.NotificationClass.WAS:
aMessage.ENINotificationIconString = "../Resources/garbage.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textWaste;
aMessage.ENINotificationDetailIndex = 3;
break;
case Message.NotificationClass.ATA:
case Message.NotificationClass.POBA:
case Message.NotificationClass.TIEFA:
case Message.NotificationClass.BKRA:
aMessage.ENINotificationIconString = "../Resources/arrow_down_right_red.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textArrivalNotification;
aMessage.ENINotificationDetailIndex = 4;
break;
case Message.NotificationClass.SEC:
aMessage.ENINotificationIconString = "../Resources/shield_yellow.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textSecurity;
aMessage.ENINotificationDetailIndex = 5;
break;
case Message.NotificationClass.PRE72H:
aMessage.ENINotificationIconString = "../Resources/alarmclock.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textPSC72h;
aMessage.ENINotificationDetailIndex = 6;
break;
case Message.NotificationClass.MDH:
aMessage.ENINotificationIconString = "../Resources/medical_bag.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textMDH;
aMessage.ENINotificationDetailIndex = 7;
break;
case Message.NotificationClass.ATD:
case Message.NotificationClass.TIEFD:
case Message.NotificationClass.BKRD:
case Message.NotificationClass.POBD:
aMessage.ENINotificationIconString = "../Resources/arrow_up_right_green.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textDepartureNotification;
aMessage.ENINotificationDetailIndex = 8;
break;
case Message.NotificationClass.STAT:
aMessage.ENINotificationIconString = "../Resources/containership.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textShipData;
aMessage.ENINotificationDetailIndex = 9;
break;
case Message.NotificationClass.BPOL:
case Message.NotificationClass.CREW:
case Message.NotificationClass.PAS:
aMessage.ENINotificationIconString = "../Resources/policeman_german.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textBorderPolice;
aMessage.ENINotificationDetailIndex = 10;
break;
case Message.NotificationClass.HAZA:
aMessage.ENINotificationIconString = "../Resources/sign_warning_radiation.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textDGArrival;
aMessage.ENINotificationDetailIndex = 11;
break;
case Message.NotificationClass.HAZD:
aMessage.ENINotificationIconString = "../Resources/sign_warning_radiation.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textDGDeparture;
aMessage.ENINotificationDetailIndex = 12;
break;
case Message.NotificationClass.TOWA:
case Message.NotificationClass.TOWD:
aMessage.ENINotificationIconString = "../Resources/ship2.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textTowage;
aMessage.ENINotificationDetailIndex = 13;
break;
default:
aMessage.ENINotificationDetailGroup = "unspecified";
break;
}
}
Util.UIHelper.SetMessageIcons(this.Messages);
#endregion
#region Meldeklassen nach ihrem Vorkommen in den Detailansichten sortieren (SH, 12.5.17)
@ -506,6 +414,7 @@ namespace ENI2.DetailViewControls
return;
}
List<Message> watchList = new List<Message>();
foreach (Message selectedMessage in this.dataGridMessages.SelectedItems)
{
if (selectedMessage.Reset) selectedMessage.Reset = false; // "nochmal" Versenden ist möglich
@ -518,15 +427,36 @@ namespace ENI2.DetailViewControls
selectedMessage.ChangedBy = string.Format("{0} at {1} (Send)", userName, DateTime.Now);
selectedMessage.StatusInfo = string.Format(Properties.Resources.textMessageSentAt, DateTime.Now);
DBManager.GetSingleCon(Properties.Settings.Default.ConnectionString).Save(selectedMessage);
watchList.Add(selectedMessage);
}
// komplette Anmeldung auf "zu versenden" stellen
this.Core.BSMDStatusInternal = MessageCore.BSMDStatus.TOSEND;
this.Core.DefaultReportingPartyId = App.UserId;
DBManager.GetSingleCon(Properties.Settings.Default.ConnectionString).Save(this.Core);
DBManager.GetSingleCon(Properties.Settings.Default.ConnectionString).Save(this.Core); // löst auch den Watchdog aus
this.OnRequestSendValidation();
this.dataGridMessages.Items.Refresh();
if (this.mssd == null)
{
this.mssd = new MessageSendStatusDialog(this.Core);
this.mssd.Closed += (s,args) => { this.mssd = null; };
this.mssd.SendComplete += (() => {
this.Dispatcher.Invoke(() =>
{
if (this.mssd != null)
{
this.mssd.Close();
this.OnRequestReload(this.Core.Id.Value);
}
});
});
this.mssd.Show();
}
this.mssd.AddMessages(watchList);
}
}

View File

@ -4,14 +4,85 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ENI2.EditControls"
xmlns:util="clr-namespace:ENI2.Util"
xmlns:enictrl="clr-namespace:ENI2.Controls"
xmlns:p="clr-namespace:ENI2.Properties"
mc:Ignorable="d"
Title="{x:Static p:Resources.textMessageStatus}" Height="450" Width="400" Loaded="StatusWindowBase_Loaded">
Title="{x:Static p:Resources.textMessageStatus}" Height="450" Width="800" Loaded="StatusWindowBase_Loaded" Closing="StatusWindowBase_Closing">
<Grid>
<ListView x:Name="listViewMessages">
</ListView>
<!-- Data Grid -->
<DataGrid Grid.Row="9" Grid.ColumnSpan="6" Margin="0,8,0,0" x:Name="dataGridMessages" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" CanUserAddRows="False"
SelectionMode="Extended" AutoGenerateColumns="False">
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding InternalStatus}" Value="SUSPENDED">
<Setter Property="Background" Value="LightSalmon"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding InternalStatus}" Value="SENT">
<Setter Property="Background" Value="LightGreen"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding InternalStatus}" Value="TOSEND">
<Setter Property="Background" Value="LightYellow"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTemplateColumn Header=" " Width="SizeToCells" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding ENINotificationIconString, Converter={util:NullImageConverter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="{x:Static p:Resources.textNotificationClass}" Binding="{Binding MessageNotificationClassDisplay}"
IsReadOnly="True" Width="0.075*" FontWeight="Bold">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="10,0,0,0" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTemplateColumn Header="" Width="SizeToCells" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image x:Name="imageSendSuccess"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=SendSuccess}" Value="True">
<Setter Property="Source" Value="/Resources/bullet_ball_green.png" TargetName="imageSendSuccess"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="{x:Static p:Resources.textChanged}" Binding="{Binding Changed}" IsReadOnly="True" Width="0.15*">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="{x:Static p:Resources.textStatus}" Binding="{Binding InternalStatus}" IsReadOnly="True" Width="0.1*">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="{x:Static p:Resources.textSentBy}" Binding="{Binding SentBy}" IsReadOnly="True" Width="0.1*">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</enictrl:StatusWindowBase>

View File

@ -2,23 +2,12 @@
// Description: Overview of messages currently in transmission
//
using System;
using System.Collections.Generic;
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.Shapes;
using System.Timers;
using bsmd.database;
using ENI2.Controls;
using log4net;
using System;
using System.Collections.Generic;
using System.Timers;
using System.Windows;
namespace ENI2.EditControls
{
@ -28,30 +17,93 @@ namespace ENI2.EditControls
public partial class MessageSendStatusDialog : StatusWindowBase
{
private readonly Timer bgTimer;
private List<Message> _messages = new List<Message>();
private MessageCore _messageCore;
public MessageSendStatusDialog()
public MessageSendStatusDialog(MessageCore core)
{
InitializeComponent();
this.bgTimer = new Timer();
_messageCore = core;
this.bgTimer.Elapsed += BgTimer_Elapsed;
this.bgTimer.AutoReset = true;
this.bgTimer.Interval = Properties.Settings.Default.changeTimerTimeout;
}
List<Message> Messages { get; set; }
public void AddMessages(List<Message> messages)
{
if (!messages.IsNullOrEmpty())
{
foreach (Message newMessage in messages)
{
if (!_messages.Contains(newMessage))
_messages.Add(newMessage);
}
this.RefreshGrid();
}
}
public event Action SendComplete;
private void RefreshGrid()
{
this.Dispatcher.Invoke(() =>
{
Util.UIHelper.SetMessageIcons(_messages);
this.dataGridMessages.ItemsSource = null;
this.dataGridMessages.ItemsSource = _messages;
});
}
private void BgTimer_Elapsed(object sender, ElapsedEventArgs e)
{
// check if a message has changed its status
bool updatedMessage = false;
bool finished = true;
System.Diagnostics.Trace.WriteLine(string.Format("Watching {0} messages.", _messages.Count));
for (int i = 0; i < _messages.Count; i++)
{
Message testMessage = (Message) DBManager.Instance.GetMessageById(_messages[i].Id.Value);
if(testMessage.Changed > _messages[i].Changed)
{
_messages[i] = testMessage; // replace Message in Array with "newer" Message
updatedMessage = true;
System.Diagnostics.Trace.WriteLine(string.Format("Updating {0} To status {1}", testMessage.Id, testMessage.InternalStatus));
}
finished &= (testMessage.InternalStatus != Message.BSMDStatus.TOSEND);
}
if (finished)
{
_messageCore.IsHighlighted = true;
this.OnSendComplete();
}
if(updatedMessage)
{
this.RefreshGrid();
}
}
private void StatusWindowBase_Loaded(object sender, RoutedEventArgs e)
{
this.bgTimer.Start();
this.dataGridMessages.DataContext = _messages;
}
protected void OnSendComplete()
{
if (!this.Messages.IsNullOrEmpty())
this.bgTimer.Start();
this.SendComplete?.Invoke();
}
private void StatusWindowBase_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
this.bgTimer.Stop();
this.bgTimer.Dispose();
}
}
}

View File

@ -510,6 +510,7 @@ namespace ENI2
if (tabitem is ClosableTabItem closableTabItem)
(closableTabItem).IsHighlighted = true;
}));
changedCore.IsHighlighted = false;
}
}
}

View File

@ -42,12 +42,19 @@ namespace ENI2.Util
MessageCore entity = DBManager.GetSingleCon(Properties.Settings.Default.ConnectionString).GetMessageCoreById(watchedEntity.Id ?? Guid.Empty);
if (entity != null)
{
if (entity.Changed > this._watchedEntities[watchedEntity])
// Der Core muss einen dieser Zustände einnehmen bevor das Highlighting erlaubt ist. Diese Zustände werden im Send Prozess gesetzt
// (wenn die Nachrichten bearbeitet sind)
bool isValidState = (entity.BSMDStatusInternal == MessageCore.BSMDStatus.FAILURE) ||
(entity.BSMDStatusInternal == MessageCore.BSMDStatus.SENT) ||
(entity.BSMDStatusInternal == MessageCore.BSMDStatus.PREPARE);
if (isValidState && ((entity.Changed > this._watchedEntities[watchedEntity]) || watchedEntity.IsHighlighted))
{
OnDatabaseEntityChanged(entity);
changedCores.Add(entity);
}
// Test ob eventuell Visit/Transit-ID inzwischen gesetzt wurde
if(entity.IsTransit)
{
if (!entity.TransitId.IsNullOrEmpty() && watchedEntity.TransitId.IsNullOrEmpty() && !entity.TransitId.Equals(watchedEntity.TransitId))

View File

@ -4,12 +4,15 @@
// https://stackoverflow.com/a/7482321
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using bsmd.database;
namespace ENI2.Util
{
public static class UIHelper
@ -56,5 +59,103 @@ namespace ENI2.Util
return Color.FromRgb((byte) r.Next(150, 255), (byte) r.Next(150, 255), (byte) r.Next(150, 255));
}
public static void SetMessageIcons(List<Message> messages)
{
foreach (Message aMessage in messages)
{
switch (aMessage.MessageNotificationClass)
{
case Message.NotificationClass.VISIT:
case Message.NotificationClass.TRANSIT:
aMessage.ENINotificationDetailGroup = Properties.Resources.textOverview;
aMessage.ENINotificationIconString = "../Resources/documents.png";
aMessage.ENINotificationDetailIndex = 0;
break;
case Message.NotificationClass.NOA_NOD:
case Message.NotificationClass.AGNT:
aMessage.ENINotificationIconString = "../Resources/eye_blue.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textPortCall;
aMessage.ENINotificationDetailIndex = 1;
break;
case Message.NotificationClass.NAME:
case Message.NotificationClass.INFO:
case Message.NotificationClass.SERV:
case Message.NotificationClass.LADG:
aMessage.ENINotificationIconString = "../Resources/anchor.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textPortNotification;
aMessage.ENINotificationDetailIndex = 2;
break;
case Message.NotificationClass.WAS:
aMessage.ENINotificationIconString = "../Resources/garbage.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textWaste;
aMessage.ENINotificationDetailIndex = 3;
break;
case Message.NotificationClass.ATA:
case Message.NotificationClass.POBA:
case Message.NotificationClass.TIEFA:
case Message.NotificationClass.BKRA:
aMessage.ENINotificationIconString = "../Resources/arrow_down_right_red.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textArrivalNotification;
aMessage.ENINotificationDetailIndex = 4;
break;
case Message.NotificationClass.SEC:
aMessage.ENINotificationIconString = "../Resources/shield_yellow.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textSecurity;
aMessage.ENINotificationDetailIndex = 5;
break;
case Message.NotificationClass.PRE72H:
aMessage.ENINotificationIconString = "../Resources/alarmclock.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textPSC72h;
aMessage.ENINotificationDetailIndex = 6;
break;
case Message.NotificationClass.MDH:
aMessage.ENINotificationIconString = "../Resources/medical_bag.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textMDH;
aMessage.ENINotificationDetailIndex = 7;
break;
case Message.NotificationClass.ATD:
case Message.NotificationClass.TIEFD:
case Message.NotificationClass.BKRD:
case Message.NotificationClass.POBD:
aMessage.ENINotificationIconString = "../Resources/arrow_up_right_green.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textDepartureNotification;
aMessage.ENINotificationDetailIndex = 8;
break;
case Message.NotificationClass.STAT:
aMessage.ENINotificationIconString = "../Resources/containership.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textShipData;
aMessage.ENINotificationDetailIndex = 9;
break;
case Message.NotificationClass.BPOL:
case Message.NotificationClass.CREW:
case Message.NotificationClass.PAS:
aMessage.ENINotificationIconString = "../Resources/policeman_german.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textBorderPolice;
aMessage.ENINotificationDetailIndex = 10;
break;
case Message.NotificationClass.HAZA:
aMessage.ENINotificationIconString = "../Resources/sign_warning_radiation.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textDGArrival;
aMessage.ENINotificationDetailIndex = 11;
break;
case Message.NotificationClass.HAZD:
aMessage.ENINotificationIconString = "../Resources/sign_warning_radiation.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textDGDeparture;
aMessage.ENINotificationDetailIndex = 12;
break;
case Message.NotificationClass.TOWA:
case Message.NotificationClass.TOWD:
aMessage.ENINotificationIconString = "../Resources/ship2.png";
aMessage.ENINotificationDetailGroup = Properties.Resources.textTowage;
aMessage.ENINotificationDetailIndex = 13;
break;
default:
aMessage.ENINotificationDetailGroup = "unspecified";
break;
}
}
}
}
}

Binary file not shown.

View File

@ -8,4 +8,20 @@ GO
ALTER TABLE [dbo].[MessageCore]
ADD [POATA] DATETIME NULL;
GO
-- genauere Auflösung für Changed Spalte!
PRINT N'Altering [dbo].[MessageHeader]...';
GO
ALTER TABLE [dbo].[MessageHeader] ALTER COLUMN [Changed] DATETIME NULL;
GO
PRINT N'Altering [dbo].[MessageCore]...';
GO
ALTER TABLE [dbo].[MessageCore] ALTER COLUMN [Changed] DATETIME NULL;
GO

View File

@ -323,7 +323,10 @@ namespace bsmd.database
#region Flag properties not backed by field
/// <summary>
/// ENI helper to mark this Core in Overview (tabheader)
/// </summary>
public bool IsHighlighted { get; set; }
#endregion