diff --git a/src/BreCalClient/BreCalClient.csproj b/src/BreCalClient/BreCalClient.csproj index beb5c4b..012ca50 100644 --- a/src/BreCalClient/BreCalClient.csproj +++ b/src/BreCalClient/BreCalClient.csproj @@ -8,8 +8,8 @@ True BreCalClient.App ..\..\misc\brecal.snk - 0.9.0.0 - 0.9.0.0 + 0.9.3.0 + 0.9.3.0 Bremen calling client A Windows WPF client for the Bremen calling API. containership.ico @@ -24,14 +24,17 @@ + + + @@ -72,14 +75,17 @@ + + + MSBuild:Compile diff --git a/src/BreCalClient/EditTimesAgencyIncomingControl.xaml.cs b/src/BreCalClient/EditTimesAgencyIncomingControl.xaml.cs index e9b584a..b488d3e 100644 --- a/src/BreCalClient/EditTimesAgencyIncomingControl.xaml.cs +++ b/src/BreCalClient/EditTimesAgencyIncomingControl.xaml.cs @@ -92,11 +92,9 @@ namespace BreCalClient { this.ShipcallModel.Shipcall.PierSide = (this.comboBoxPierside.SelectedIndex == 0) ? true : false; } - this.Times.BerthInfo = this.textBoxBerthRemarks.Text.Trim(); - if((this.comboBoxArrivalBerth.SelectedValue != null) && ((int?)this.comboBoxArrivalBerth.SelectedValue != this.ShipcallModel.Shipcall.ArrivalBerthId)) - { - this.Times.BerthId = (int?)this.comboBoxArrivalBerth.SelectedValue; - } + + this.Times.BerthInfo = this.textBoxBerthRemarks.Text.Trim(); + this.Times.BerthId = (int?)this.comboBoxArrivalBerth.SelectedValue; this.ShipcallModel.Shipcall.Draft = (float?)this.doubleUpDownDraft.Value; this.ShipcallModel.Shipcall.TidalWindowFrom = this.datePickerTidalWindowFrom.Value; diff --git a/src/BreCalClient/EditTimesAgencyOutgoingControl.xaml.cs b/src/BreCalClient/EditTimesAgencyOutgoingControl.xaml.cs index b697ebd..6117df4 100644 --- a/src/BreCalClient/EditTimesAgencyOutgoingControl.xaml.cs +++ b/src/BreCalClient/EditTimesAgencyOutgoingControl.xaml.cs @@ -89,10 +89,9 @@ namespace BreCalClient { this.ShipcallModel.Shipcall.PierSide = (this.comboBoxPierside.SelectedIndex == 0) ? true : false; } - if ((this.comboBoxDepartureBerth.SelectedValue != null) && ((int?)this.comboBoxDepartureBerth.SelectedValue != this.ShipcallModel.Shipcall.DepartureBerthId)) - { - this.Times.BerthId = (int?)this.comboBoxDepartureBerth.SelectedValue; - } + + this.Times.BerthId = (int?)this.comboBoxDepartureBerth.SelectedValue; + this.Times.BerthInfo = this.textBoxBerthRemarks.Text.Trim(); this.ShipcallModel.Shipcall.Draft = (float?)this.doubleUpDownDraft.Value; this.ShipcallModel.Shipcall.TidalWindowFrom = this.datePickerTidalWindowFrom.Value; diff --git a/src/BreCalClient/EditTimesAgencyShiftingControl.xaml.cs b/src/BreCalClient/EditTimesAgencyShiftingControl.xaml.cs index beb7e04..0bb4f61 100644 --- a/src/BreCalClient/EditTimesAgencyShiftingControl.xaml.cs +++ b/src/BreCalClient/EditTimesAgencyShiftingControl.xaml.cs @@ -92,11 +92,9 @@ namespace BreCalClient { this.ShipcallModel.Shipcall.PierSide = (this.comboBoxPiersideArrival.SelectedIndex == 0) ? true : false; } - this.Times.BerthInfo = this.textBoxBerthRemarksArrival.Text.Trim(); - if ((this.comboBoxArrivalBerth.SelectedValue != null) && ((int?)this.comboBoxArrivalBerth.SelectedValue != this.ShipcallModel.Shipcall.ArrivalBerthId)) - { - this.Times.BerthId = (int?)this.comboBoxArrivalBerth.SelectedValue; - } + + this.Times.BerthInfo = this.textBoxBerthRemarksArrival.Text.Trim(); + this.Times.BerthId = (int?)this.comboBoxArrivalBerth.SelectedValue; this.ShipcallModel.Shipcall.Draft = (float?)this.doubleUpDownDraft.Value; this.ShipcallModel.Shipcall.TidalWindowFrom = this.datePickerTidalWindowFrom.Value; diff --git a/src/BreCalClient/EditTimesControl.xaml.cs b/src/BreCalClient/EditTimesControl.xaml.cs index 66ceb6d..4b5850e 100644 --- a/src/BreCalClient/EditTimesControl.xaml.cs +++ b/src/BreCalClient/EditTimesControl.xaml.cs @@ -27,9 +27,7 @@ namespace BreCalClient public Times Times { get; set; } = new(); - public Extensions.TypeEnum CallType { get; set; } - - internal Extensions.ParticipantType ParticipantType { get; set; } = Extensions.ParticipantType.NONE; + public Extensions.TypeEnum CallType { get; set; } #endregion @@ -88,7 +86,9 @@ namespace BreCalClient private void EnableControls() { - switch (this.ParticipantType) + Extensions.ParticipantType pType = (Extensions.ParticipantType) (this.Times.ParticipantType ?? 0); + + switch (pType) { case Extensions.ParticipantType.MOORING: case Extensions.ParticipantType.PORT_ADMINISTRATION: diff --git a/src/BreCalClient/MainWindow.xaml b/src/BreCalClient/MainWindow.xaml index b87b972..39ba515 100644 --- a/src/BreCalClient/MainWindow.xaml +++ b/src/BreCalClient/MainWindow.xaml @@ -72,7 +72,7 @@ - + diff --git a/src/BreCalClient/MainWindow.xaml.cs b/src/BreCalClient/MainWindow.xaml.cs index 97415e5..6df2daf 100644 --- a/src/BreCalClient/MainWindow.xaml.cs +++ b/src/BreCalClient/MainWindow.xaml.cs @@ -16,7 +16,7 @@ using BreCalClient.misc.Client; using BreCalClient.misc.Model; using static BreCalClient.Extensions; -using System.Runtime.Serialization; +using System.Collections.Concurrent; namespace BreCalClient { @@ -31,11 +31,13 @@ namespace BreCalClient #region Fields + private static Int32 _uiUpdateRunning = 0; + private Timer? _timer; private Credentials? _credentials; - private readonly Dictionary _allShipcallsDict = new(); - private readonly Dictionary _allShipCallsControlDict = new(); + private readonly ConcurrentDictionary _allShipcallsDict = new(); + private readonly ConcurrentDictionary _allShipCallsControlDict = new(); private readonly List _visibleControlModels = new(); private readonly DefaultApi _api; @@ -412,8 +414,8 @@ namespace BreCalClient ShipcallControlModel removeModel = this._allShipcallsDict[shipcallId]; _visibleControlModels.Remove(removeModel); - this._allShipCallsControlDict.Remove(shipcallId); - this._allShipcallsDict.Remove(shipcallId); + this._allShipCallsControlDict.Remove(shipcallId, out _); + this._allShipcallsDict.Remove(shipcallId, out _); } private void FilterShipcalls() @@ -505,28 +507,45 @@ namespace BreCalClient } } - + #endregion + #region UpdateUI func + private void UpdateUI() { this.Dispatcher.Invoke(new Action(() => { - this.stackPanel.Children.Clear(); - foreach(ShipcallControlModel visibleModel in this._visibleControlModels) + if (Interlocked.CompareExchange(ref _uiUpdateRunning, 1, 0) == 1) return; + + try { - if (visibleModel.Shipcall == null) continue; // should not happen - if(this._allShipCallsControlDict.ContainsKey(visibleModel.Shipcall.Id)) + this.stackPanel.Children.Clear(); + foreach (ShipcallControlModel visibleModel in this._visibleControlModels) { - this._allShipCallsControlDict[visibleModel.Shipcall.Id].RefreshData(); - this.stackPanel.Children.Add(this._allShipCallsControlDict[visibleModel.Shipcall.Id]); + if (visibleModel.Shipcall == null) continue; // should not happen + if (this._allShipCallsControlDict.ContainsKey(visibleModel.Shipcall.Id)) + { + this._allShipCallsControlDict[visibleModel.Shipcall.Id].RefreshData(); + this.stackPanel.Children.Add(this._allShipCallsControlDict[visibleModel.Shipcall.Id]); + } } } + catch(Exception e) { + _log.ErrorFormat("Exception running ui update: {0}", e.ToString()); + } + finally + { + _uiUpdateRunning = 0; + } + })); } + #endregion + #region control event handler private async void Sc_EditRequested(ShipcallControl obj) @@ -543,6 +562,7 @@ namespace BreCalClient try { obj.ShipcallControlModel.Shipcall?.Participants.Clear(); + obj.ShipcallControlModel.UpdateTimesAssignments(this._api); foreach(ParticipantAssignment pa in obj.ShipcallControlModel.AssignedParticipants.Values) obj.ShipcallControlModel.Shipcall?.Participants.Add(pa); await _api.ShipcallsPutAsync(obj.ShipcallControlModel.Shipcall); @@ -569,6 +589,7 @@ namespace BreCalClient if(obj.ShipcallControlModel.Shipcall != null) etc.CallType = (TypeEnum) obj.ShipcallControlModel.Shipcall.Type; + bool wasEdit = false; if (times != null) { @@ -639,12 +660,19 @@ namespace BreCalClient { editControl.Times = times; wasEdit = true; + } + else + { + if(editControl.ShipcallModel.AssignedParticipants.ContainsKey(ParticipantType.AGENCY)) + editControl.Times.ParticipantId = editControl.ShipcallModel.AssignedParticipants[ParticipantType.AGENCY].ParticipantId; } editControl.Times.ParticipantType = (int)ParticipantType.AGENCY; if(editControl.ShowDialog() ?? false) { try { + sc.ShipcallControlModel?.UpdateTimesAssignments(_api); // if the agent changed the assignment of the participant to another + // always try to be the agent, even if we are BSMD if (editControl.ShipcallModel.AssignedParticipants.ContainsKey(ParticipantType.AGENCY)) { diff --git a/src/BreCalClient/Properties/PublishProfiles/ClickOnceProfile.pubxml b/src/BreCalClient/Properties/PublishProfiles/ClickOnceProfile.pubxml index 58ef08a..fab3079 100644 --- a/src/BreCalClient/Properties/PublishProfiles/ClickOnceProfile.pubxml +++ b/src/BreCalClient/Properties/PublishProfiles/ClickOnceProfile.pubxml @@ -5,7 +5,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. 0 - 0.9.0.0 + 0.9.3.0 False Release True diff --git a/src/BreCalClient/Properties/PublishProfiles/ClickOnceTestProfile.pubxml b/src/BreCalClient/Properties/PublishProfiles/ClickOnceTestProfile.pubxml index 2bacd27..300d77f 100644 --- a/src/BreCalClient/Properties/PublishProfiles/ClickOnceTestProfile.pubxml +++ b/src/BreCalClient/Properties/PublishProfiles/ClickOnceTestProfile.pubxml @@ -5,7 +5,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. 0 - 0.9.0.0 + 0.9.3.0 False Debug True diff --git a/src/BreCalClient/Resources/Resources.Designer.cs b/src/BreCalClient/Resources/Resources.Designer.cs index 5c8f167..66aadc9 100644 --- a/src/BreCalClient/Resources/Resources.Designer.cs +++ b/src/BreCalClient/Resources/Resources.Designer.cs @@ -110,6 +110,16 @@ namespace BreCalClient.Resources { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + public static byte[] check { + get { + object obj = ResourceManager.GetObject("check", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized resource of type System.Byte[]. /// @@ -160,6 +170,16 @@ namespace BreCalClient.Resources { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + public static byte[] delete2 { + get { + object obj = ResourceManager.GetObject("delete2", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized resource of type System.Byte[]. /// @@ -190,6 +210,16 @@ namespace BreCalClient.Resources { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + public static byte[] sign_warning { + get { + object obj = ResourceManager.GetObject("sign_warning", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized string similar to Agencies. /// diff --git a/src/BreCalClient/Resources/Resources.resx b/src/BreCalClient/Resources/Resources.resx index 78c37b9..1bad839 100644 --- a/src/BreCalClient/Resources/Resources.resx +++ b/src/BreCalClient/Resources/Resources.resx @@ -133,6 +133,9 @@ arrow_up_red.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + check.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + clipboard.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -148,6 +151,9 @@ delete.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + delete2.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + emergency_stop_button.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -157,6 +163,9 @@ ship2.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + sign_warning.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + Agencies diff --git a/src/BreCalClient/Resources/check.png b/src/BreCalClient/Resources/check.png new file mode 100644 index 0000000..5d739b1 Binary files /dev/null and b/src/BreCalClient/Resources/check.png differ diff --git a/src/BreCalClient/Resources/delete2.png b/src/BreCalClient/Resources/delete2.png new file mode 100644 index 0000000..d31437a Binary files /dev/null and b/src/BreCalClient/Resources/delete2.png differ diff --git a/src/BreCalClient/Resources/sign_warning.png b/src/BreCalClient/Resources/sign_warning.png new file mode 100644 index 0000000..317ccc8 Binary files /dev/null and b/src/BreCalClient/Resources/sign_warning.png differ diff --git a/src/BreCalClient/ShipcallControl.xaml b/src/BreCalClient/ShipcallControl.xaml index d034112..913e936 100644 --- a/src/BreCalClient/ShipcallControl.xaml +++ b/src/BreCalClient/ShipcallControl.xaml @@ -2,18 +2,16 @@ 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:BreCalClient" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:p = "clr-namespace:BreCalClient.Resources" xmlns:sets="clr-namespace:BreCalClient.Properties" - xmlns:db="clr-namespace:BreCalClient;assembly=BreCalClient" - xmlns:db2="clr-namespace:BreCalClient.misc.Model;assembly=BreCalClient" + xmlns:db="clr-namespace:BreCalClient;assembly=BreCalTestClient" mc:Ignorable="d" d:DesignHeight="120" d:DesignWidth="800" Loaded="UserControl_Loaded"> - + @@ -40,14 +38,18 @@ - + + @@ -211,34 +213,6 @@ - - diff --git a/src/BreCalClient/ShipcallControl.xaml.cs b/src/BreCalClient/ShipcallControl.xaml.cs index 00b541c..a087172 100644 --- a/src/BreCalClient/ShipcallControl.xaml.cs +++ b/src/BreCalClient/ShipcallControl.xaml.cs @@ -3,13 +3,13 @@ // using BreCalClient.misc.Model; +using log4net; using System; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Imaging; - namespace BreCalClient { /// @@ -25,6 +25,7 @@ namespace BreCalClient Participant? _terminal; Participant? _tug; Participant? _port_administration; + private static readonly ILog _log = LogManager.GetLogger(typeof(ShipcallControl)); #endregion @@ -60,208 +61,258 @@ namespace BreCalClient public void RefreshData() { - if (this.ShipcallControlModel != null) + try { - string agentName = ""; - string? name; - _agency = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.AGENCY); - name = _agency?.Name; - if (name != null) agentName = name; - this.labelAgent.Content = name ?? "- / -"; - - _mooring = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.MOORING); - name = _mooring?.Name; - this.labelMooring.Content = name ?? "- / -"; - - _pilot = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.PILOT); - name = _pilot?.Name; - this.labelPilot.Content = name ?? "- / - "; - - _tug = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.TUG); - name = _tug?.Name; - this.labelTug.Content = name ?? "- / - "; - - _port_administration = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.PORT_ADMINISTRATION); - name = _port_administration?.Name; - this.labelPortAuthority.Content = name ?? "- / - "; - - _terminal = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.TERMINAL); - name = _terminal?.Name; - this.labelTerminal.Content = name ?? "- / - "; - - if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.TERMINAL) && (App.Participant.Id == _terminal?.Id)) + if (this.ShipcallControlModel != null) { - this.labelTerminal.FontWeight = FontWeights.Bold; - this.labelTerminal.Foreground = Brushes.LightYellow; - } + string agentName = ""; + string? name; + _agency = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.AGENCY); + name = _agency?.Name; + if (name != null) agentName = name; + this.labelAgent.Content = name ?? "- / -"; - if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.PILOT) && (App.Participant.Id == _pilot?.Id)) - { - this.labelPilot.FontWeight = FontWeights.Bold; - this.labelPilot.Foreground = Brushes.LightYellow; - } + _mooring = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.MOORING); + name = _mooring?.Name; + this.labelMooring.Content = name ?? "- / -"; - if ((App.Participant.IsTypeFlagSet(Extensions.ParticipantType.AGENCY) && (App.Participant.Id == _agency?.Id)) || - (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.BSMD) && (_agency != null) && _agency.IsFlagSet(Extensions.ParticipantFlag.ALLOW_BSMD))) - { - this.labelAgent.FontWeight = FontWeights.Bold; - this.labelAgent.Foreground = Brushes.LightYellow; - } + _pilot = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.PILOT); + name = _pilot?.Name; + this.labelPilot.Content = name ?? "- / - "; - if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.MOORING) && (App.Participant.Id == _mooring?.Id)) - { - this.labelMooring.FontWeight = FontWeights.Bold; - this.labelMooring.Foreground = Brushes.LightYellow; - } + _tug = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.TUG); + name = _tug?.Name; + this.labelTug.Content = name ?? "- / - "; - if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.PORT_ADMINISTRATION) && (App.Participant.Id == _port_administration?.Id)) - { - this.labelPortAuthority.FontWeight = FontWeights.Bold; - this.labelPortAuthority.Foreground = Brushes.LightYellow; - } + _port_administration = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.PORT_ADMINISTRATION); + name = _port_administration?.Name; + this.labelPortAuthority.Content = name ?? "- / - "; - if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.TUG) && (App.Participant.Id == _tug?.Id)) - { - this.labelTug.FontWeight = FontWeights.Bold; - this.labelTug.Foreground = Brushes.LightYellow; - } + _terminal = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.TERMINAL); + name = _terminal?.Name; + this.labelTerminal.Content = name ?? "- / - "; - if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.BSMD)) - { - this.labelShipName.FontWeight = FontWeights.Bold; - this.labelShipName.Foreground = Brushes.LightYellow; - } - - this.labelShipName.Content = this.ShipcallControlModel?.Ship?.Name; - switch (this.ShipcallControlModel?.Shipcall?.Type) - { - case 1: // incoming - this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalTestClient;component/Resources/arrow_down_red.png")); - break; - case 2: // outgoing - this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalTestClient;component/Resources/arrow_up_blue.png")); - break; - case 3: // shifting - this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalTestClient;component/Resources/arrow_right_green.png")); - break; - default: - break; - } - - this.textBlockBerth.Text = this.ShipcallControlModel?.Berth; - this.textBlockCallsign.Text = this.ShipcallControlModel?.Ship?.Callsign; - if ((this.ShipcallControlModel?.Shipcall?.Type == 1) || (this.ShipcallControlModel?.Shipcall?.Type == 3)) - { - this.textBlockETA.Text = this.ShipcallControlModel?.Shipcall?.Eta?.ToString("dd.MM. HH:mm"); - } - if (this.ShipcallControlModel?.Shipcall?.Type == 2) - { - this.labelETA.Text = "ETD"; - this.textBlockETA.Text = this.ShipcallControlModel?.Shipcall?.Etd?.ToString("dd.MM. HH:mm"); - } - - this.textBlockIMO.Text = this.ShipcallControlModel?.Ship?.Imo.ToString(); - this.textBlockLengthWidth.Text = $"{this.ShipcallControlModel?.Ship?.Length} / {this.ShipcallControlModel?.Ship?.Width}"; - - // rename labels if this is not an incoming - // must be here because there may not be a times record for each participant (yet) - - if (this.ShipcallControlModel?.Shipcall?.Type != 1) - { - this.labelETAETDAgent.Content = "ETD"; - this.labelETAETDMooring.Content = "ETD"; - this.labelETAETDPilot.Content = "ETD"; - this.labelETAETDPortAuthority.Content = "ETD"; - this.labelETAETDTug.Content = "ETD"; - this.labelETAETDTerminal.Content = BreCalClient.Resources.Resources.textOperationsEnd; - } - - foreach (Times times in this.ShipcallControlModel.Times) - { - string? berthText = null; - if ((BreCalLists.Berths != null) && times.BerthId.HasValue) + if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.TERMINAL) && (App.Participant.Id == _terminal?.Id)) { - Berth? berth = BreCalLists.Berths.Find((x) => x.Id == times.BerthId); - berthText = berth?.Name; + this.labelTerminal.FontWeight = FontWeights.Bold; + this.labelTerminal.Foreground = Brushes.LightYellow; } - if (berthText == null) + + if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.PILOT) && (App.Participant.Id == _pilot?.Id)) { - if (this.ShipcallControlModel?.Shipcall?.Type == (int)Extensions.TypeEnum.Outgoing) - { - Berth? berth = BreCalLists.Berths?.Find((x) => x.Id == this.ShipcallControlModel.Shipcall?.DepartureBerthId); - berthText = berth?.Name; - } - else - { - Berth? berth = BreCalLists.Berths?.Find((x) => x.Id == this.ShipcallControlModel?.Shipcall?.ArrivalBerthId); - berthText = berth?.Name; - } + this.labelPilot.FontWeight = FontWeights.Bold; + this.labelPilot.Foreground = Brushes.LightYellow; } - if (times.ParticipantType == (int)Extensions.ParticipantType.AGENCY) + if ((App.Participant.IsTypeFlagSet(Extensions.ParticipantType.AGENCY) && (App.Participant.Id == _agency?.Id)) || + (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.BSMD) && (_agency != null) && _agency.IsFlagSet(Extensions.ParticipantFlag.ALLOW_BSMD))) { - this.labelAgencyBerth.Content = berthText; - this.labelAgencyETAETDValue.Content = times.EtaBerth.HasValue ? times.EtaBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -"; - this.textBlockAgencyRemarks.Text = times.Remarks; - this.textBlockAgencyBerthRemarks.Text = times.BerthInfo; - if (this.ShipcallControlModel?.Shipcall?.Type != 1) - { - this.labelAgencyETAETDValue.Content = times.EtdBerth.HasValue ? times.EtdBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -"; - } + this.labelAgent.FontWeight = FontWeights.Bold; + this.labelAgent.Foreground = Brushes.LightYellow; } - if (times.ParticipantType == (int)Extensions.ParticipantType.MOORING) + if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.MOORING) && (App.Participant.Id == _mooring?.Id)) { - this.labelMooringETAETDValue.Content = times.EtaBerth.HasValue ? times.EtaBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -"; - this.textBlockMooringRemarks.Text = times.Remarks; - if (this.ShipcallControlModel?.Shipcall?.Type != 1) - { - this.labelMooringETAETDValue.Content = times.EtdBerth.HasValue ? times.EtdBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -"; + this.labelMooring.FontWeight = FontWeights.Bold; + this.labelMooring.Foreground = Brushes.LightYellow; + } + + if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.PORT_ADMINISTRATION) && (App.Participant.Id == _port_administration?.Id)) + { + this.labelPortAuthority.FontWeight = FontWeights.Bold; + this.labelPortAuthority.Foreground = Brushes.LightYellow; + } + + if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.TUG) && (App.Participant.Id == _tug?.Id)) + { + this.labelTug.FontWeight = FontWeights.Bold; + this.labelTug.Foreground = Brushes.LightYellow; + } + + if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.BSMD)) + { + this.labelShipName.FontWeight = FontWeights.Bold; + this.labelShipName.Foreground = Brushes.LightYellow; + } + + this.labelShipName.Content = this.ShipcallControlModel?.Ship?.Name; + switch (this.ShipcallControlModel?.Shipcall?.Type) + { + case 1: // incoming + this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalTestClient;component/Resources/arrow_down_red.png")); + break; + case 2: // outgoing + this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalTestClient;component/Resources/arrow_up_blue.png")); + break; + case 3: // shifting + this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalTestClient;component/Resources/arrow_right_green.png")); + break; + default: + break; + } + + switch(this.ShipcallControlModel?.LightMode) + { + case ShipcallControlModel.TrafficLightMode.GREEN: + this.imageEvaluation.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalTestClient;component/Resources/check.png")); + break; + case ShipcallControlModel.TrafficLightMode.YELLOW: + this.imageEvaluation.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalTestClient;component/Resources/sign_warning.png")); + break; + case ShipcallControlModel.TrafficLightMode.RED: + this.imageEvaluation.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalTestClient;component/Resources/delete2.png")); + break; + default: + break; + } + + if (this.ShipcallControlModel?.Shipcall?.Evaluation != null) + { + ShipcallControlModel.TrafficLightMode resultColor = (ShipcallControlModel.TrafficLightMode) (this.ShipcallControlModel?.Shipcall?.Evaluation ?? 0); // der nullable Operator hier ist so doof, die VS validation blickts einfach nicht + switch (resultColor) + { + case ShipcallControlModel.TrafficLightMode.GREEN: + this.Background = Brushes.LightGreen; + break; + case ShipcallControlModel.TrafficLightMode.YELLOW: + this.Background= Brushes.LightYellow; + break; + case ShipcallControlModel.TrafficLightMode.RED: + this.Background = new SolidColorBrush(Color.FromArgb(200, 255, 100, 100)); + break; + default: + this.Background = Brushes.Transparent; + break; } } - if (times.ParticipantType == (int)Extensions.ParticipantType.PORT_ADMINISTRATION) - { - this.labelPortAuthorityETAETDValue.Content = times.EtaBerth.HasValue ? times.EtaBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -"; - this.textBlockPortAuthorityRemarks.Text = times.Remarks; - if (this.ShipcallControlModel?.Shipcall?.Type != 1) - { - this.labelPortAuthorityETAETDValue.Content = times.EtdBerth.HasValue ? times.EtdBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -"; - } + if (!string.IsNullOrEmpty(this.ShipcallControlModel?.Shipcall?.EvaluationMessage)) + this.imageEvaluation.ToolTip = this.ShipcallControlModel?.Shipcall?.EvaluationMessage; + + this.textBlockBerth.Text = this.ShipcallControlModel?.Berth; + this.textBlockCallsign.Text = this.ShipcallControlModel?.Ship?.Callsign; + if ((this.ShipcallControlModel?.Shipcall?.Type == 1) || (this.ShipcallControlModel?.Shipcall?.Type == 3)) + { + this.textBlockETA.Text = this.ShipcallControlModel?.Shipcall?.Eta?.ToString("dd.MM. HH:mm"); + } + if (this.ShipcallControlModel?.Shipcall?.Type == 2) + { + this.labelETA.Text = "ETD"; + this.textBlockETA.Text = this.ShipcallControlModel?.Shipcall?.Etd?.ToString("dd.MM. HH:mm"); } - if (times.ParticipantType == (int)Extensions.ParticipantType.PILOT) - { - this.labelPilotETAETDValue.Content = times.EtaBerth.HasValue ? times.EtaBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -"; - this.textBlockPilotRemarks.Text = times.Remarks; - if (this.ShipcallControlModel?.Shipcall?.Type != 1) - { - this.labelPilotETAETDValue.Content = times.EtdBerth.HasValue ? times.EtdBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -"; - } + this.textBlockIMO.Text = this.ShipcallControlModel?.Ship?.Imo.ToString(); + this.textBlockLengthWidth.Text = $"{this.ShipcallControlModel?.Ship?.Length} / {this.ShipcallControlModel?.Ship?.Width}"; + + // rename labels if this is not an incoming + // must be here because there may not be a times record for each participant (yet) + + if (this.ShipcallControlModel?.Shipcall?.Type != 1) + { + this.labelETAETDAgent.Content = "ETD"; + this.labelETAETDMooring.Content = "ETD"; + this.labelETAETDPilot.Content = "ETD"; + this.labelETAETDPortAuthority.Content = "ETD"; + this.labelETAETDTug.Content = "ETD"; + this.labelETAETDTerminal.Content = BreCalClient.Resources.Resources.textOperationsEnd; } - if (times.ParticipantType == (int)Extensions.ParticipantType.TUG) - { - this.labelTugETAETDValue.Content = times.EtaBerth.HasValue ? times.EtaBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -"; - this.textBlockTugRemarks.Text = times.Remarks; - if (this.ShipcallControlModel?.Shipcall?.Type != 1) + if (this.ShipcallControlModel != null) + { + foreach (Times times in this.ShipcallControlModel.Times) { - this.labelTugETAETDValue.Content = times.EtdBerth.HasValue ? times.EtdBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -"; - } - } + string? berthText = null; + if ((BreCalLists.Berths != null) && times.BerthId.HasValue) + { + Berth? berth = BreCalLists.Berths.Find((x) => x.Id == times.BerthId); + berthText = berth?.Name; + } + if (berthText == null) + { + if (this.ShipcallControlModel?.Shipcall?.Type == (int)Extensions.TypeEnum.Outgoing) + { + Berth? berth = BreCalLists.Berths?.Find((x) => x.Id == this.ShipcallControlModel.Shipcall?.DepartureBerthId); + berthText = berth?.Name; + } + else + { + Berth? berth = BreCalLists.Berths?.Find((x) => x.Id == this.ShipcallControlModel?.Shipcall?.ArrivalBerthId); + berthText = berth?.Name; + } + } - if (times.ParticipantType == (int)Extensions.ParticipantType.TERMINAL) - { - this.labelOperationsStart.Content = times.OperationsStart.HasValue ? times.OperationsStart.Value.ToString("dd.MM.yyyy HH:mm") : "- / -"; - this.textBlockTerminalRemarks.Text = times.Remarks; - if (this.ShipcallControlModel?.Shipcall?.Type != 1) - { - this.labelOperationsStart.Content = times.OperationsEnd.HasValue ? times.OperationsEnd.Value.ToString("dd.MM.yyyy HH:mm") : "- / -"; + if (times.ParticipantType == (int)Extensions.ParticipantType.AGENCY) + { + this.labelAgencyBerth.Content = berthText; + this.labelAgencyETAETDValue.Content = times.EtaBerth.HasValue ? times.EtaBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -"; + this.textBlockAgencyRemarks.Text = times.Remarks; + this.textBlockAgencyBerthRemarks.Text = times.BerthInfo; + if (this.ShipcallControlModel?.Shipcall?.Type != 1) + { + this.labelAgencyETAETDValue.Content = times.EtdBerth.HasValue ? times.EtdBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -"; + } + } + + if (times.ParticipantType == (int)Extensions.ParticipantType.MOORING) + { + this.labelMooringETAETDValue.Content = times.EtaBerth.HasValue ? times.EtaBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -"; + this.textBlockMooringRemarks.Text = times.Remarks; + if (this.ShipcallControlModel?.Shipcall?.Type != 1) + { + this.labelMooringETAETDValue.Content = times.EtdBerth.HasValue ? times.EtdBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -"; + } + } + + if (times.ParticipantType == (int)Extensions.ParticipantType.PORT_ADMINISTRATION) + { + this.labelPortAuthorityETAETDValue.Content = times.EtaBerth.HasValue ? times.EtaBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -"; + this.textBlockPortAuthorityRemarks.Text = times.Remarks; + if (this.ShipcallControlModel?.Shipcall?.Type != 1) + { + this.labelPortAuthorityETAETDValue.Content = times.EtdBerth.HasValue ? times.EtdBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -"; + } + } + + if (times.ParticipantType == (int)Extensions.ParticipantType.PILOT) + { + this.labelPilotETAETDValue.Content = times.EtaBerth.HasValue ? times.EtaBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -"; + this.textBlockPilotRemarks.Text = times.Remarks; + if (this.ShipcallControlModel?.Shipcall?.Type != 1) + { + this.labelPilotETAETDValue.Content = times.EtdBerth.HasValue ? times.EtdBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -"; + } + } + + if (times.ParticipantType == (int)Extensions.ParticipantType.TUG) + { + this.labelTugETAETDValue.Content = times.EtaBerth.HasValue ? times.EtaBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -"; + this.textBlockTugRemarks.Text = times.Remarks; + if (this.ShipcallControlModel?.Shipcall?.Type != 1) + { + this.labelTugETAETDValue.Content = times.EtdBerth.HasValue ? times.EtdBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -"; + } + } + + if (times.ParticipantType == (int)Extensions.ParticipantType.TERMINAL) + { + this.labelTerminalBerth.Content = berthText; + this.labelOperationsStart.Content = times.OperationsStart.HasValue ? times.OperationsStart.Value.ToString("dd.MM.yyyy HH:mm") : "- / -"; + this.textBlockTerminalRemarks.Text = times.Remarks; + if (this.ShipcallControlModel?.Shipcall?.Type != 1) + { + this.labelOperationsStart.Content = times.OperationsEnd.HasValue ? times.OperationsEnd.Value.ToString("dd.MM.yyyy HH:mm") : "- / -"; + } + this.textBlockTerminalBerthRemarks.Text = times.BerthInfo; + } } - this.textBlockTerminalBerthRemarks.Text = times.BerthInfo; } + this.DataContext = this.ShipcallControlModel; } - } + } + catch (Exception ex) + { + _log.ErrorFormat("Something went wrong during data refresh: {0}", ex.ToString()); + } } #endregion diff --git a/src/BreCalClient/ShipcallControlModel.cs b/src/BreCalClient/ShipcallControlModel.cs index f3148d0..a5e8e73 100644 --- a/src/BreCalClient/ShipcallControlModel.cs +++ b/src/BreCalClient/ShipcallControlModel.cs @@ -2,6 +2,7 @@ // Description: Container model for shipcall related info // +using BreCalClient.misc.Api; using BreCalClient.misc.Model; using System; using System.Collections.Generic; @@ -55,24 +56,17 @@ namespace BreCalClient { get { - if (IsFlagSet(StatusFlags.RED)) + TrafficLightMode tlm = TrafficLightMode.OFF; + + if (this.Shipcall != null) { - if (IsFlagSet((StatusFlags)StatusFlags.YELLOW)) + if(this.Shipcall.Evaluation.HasValue) { - if (IsFlagSet(StatusFlags.GREEN)) - { - return TrafficLightMode.ALL; - } - return TrafficLightMode.RED_YELLOW; + tlm = (TrafficLightMode)this.Shipcall.Evaluation; } - return TrafficLightMode.RED; } - if (IsFlagSet(StatusFlags.YELLOW)) - return TrafficLightMode.YELLOW; - if (IsFlagSet(StatusFlags.GREEN)) - return TrafficLightMode.GREEN; - return TrafficLightMode.OFF; - } + return tlm; + } } #endregion @@ -131,6 +125,25 @@ namespace BreCalClient return false; } + /// + /// After closing the edit shipcall or edit agency dialogs, the times assignments may have changed. + /// This function updates the assignments for existing times records accordingly and saves them. + /// + /// API reference to PUT eidted times + internal async void UpdateTimesAssignments(DefaultApi _api) + { + foreach (Extensions.ParticipantType participantType in this.AssignedParticipants.Keys) + { + Times? times = this.GetTimesForParticipantType(participantType); + if(times == null) continue; + if(times.ParticipantId != this.AssignedParticipants[participantType].ParticipantId) + { + times.ParticipantId = this.AssignedParticipants[participantType].ParticipantId; + await _api.TimesPutAsync(times); + } + } + } + #endregion #region helper