git_brcal/src/BreCalClient/ShipcallControlModel.cs

255 lines
8.0 KiB
C#

// Copyright (c) 2023 schick Informatik
// Description: Container model for shipcall related info
//
using BreCalClient.misc.Api;
using BreCalClient.misc.Model;
using System;
using System.Collections.Generic;
namespace BreCalClient
{
/// <summary>
/// Container model to aggregate separate models for the Shipcall control data binding
/// </summary>
public class ShipcallControlModel
{
#region Enumerations
public enum TrafficLightMode
{
OFF,
GREEN,
YELLOW,
RED,
RED_YELLOW,
ALL
};
[Flags]
public enum StatusFlags
{
RED,
GREEN,
YELLOW,
BLINK_1,
BLINK_2
};
#endregion
#region Properties
public Shipcall? Shipcall { get; set; }
public Ship? Ship { get; set; }
public string? Berth { get; set; }
internal Dictionary<ParticipantType, ParticipantAssignment> AssignedParticipants { get; } = new();
public List<Times> Times { get; set; } = new();
public DateTime? Eta
{
get
{
Times? agencyTimes = this.GetTimesForParticipantType(ParticipantType.AGENCY);
if((agencyTimes != null) && (agencyTimes.EtaBerth != null))
return agencyTimes.EtaBerth;
return Shipcall?.Eta;
}
}
public DateTime? Etd
{
get
{
Times? agencyTimes = this.GetTimesForParticipantType(Extensions.ParticipantType.AGENCY);
if ((agencyTimes != null) && (agencyTimes.EtdBerth != null))
return agencyTimes.EtdBerth;
return Shipcall?.Etd;
}
}
public TrafficLightMode LightMode
{
get
{
TrafficLightMode tlm = TrafficLightMode.OFF;
if (this.Shipcall != null)
{
if(this.Shipcall.Evaluation.HasValue)
{
tlm = (TrafficLightMode)this.Shipcall.Evaluation;
}
}
return tlm;
}
}
public string Title
{
get
{
if (this.Shipcall == null) return "";
Extensions.TypeEnum callType = (Extensions.TypeEnum) this.Shipcall.Type;
return string.Format("{0} {1}", callType, this.Ship?.Name);
}
}
#endregion
#region public methods
public void AssignParticipants()
{
this.AssignedParticipants.Clear();
if (Shipcall != null)
{
foreach (ParticipantAssignment participantAssignment in Shipcall.Participants)
{
AssignedParticipants[(ParticipantType)participantAssignment.Type] = participantAssignment;
}
}
}
internal Times? GetTimesForParticipantType(ParticipantType type)
{
if (AssignedParticipants.ContainsKey(type)) {
int participantId = AssignedParticipants[type].ParticipantId;
foreach (Times times in this.Times)
{
if ((times.ParticipantId == participantId) && (times.ParticipantType == (int) type))
return times;
}
if(type == ParticipantType.AGENCY)
{
// if I am BSMD and no agency entry was found this means we are editing the agency entry
if(App.Participant.Type == (int) ParticipantType.BSMD)
{
foreach(Times times in this.Times)
{
if ((times.ParticipantId == App.Participant.Id) && (times.ParticipantType == (int) ParticipantType.AGENCY))
return times;
}
}
}
}
return null;
}
public bool ContainsRemarkText(string text)
{
if(Shipcall != null)
{
foreach(Times times in this.Times)
{
if (times.Remarks == null) continue;
if(times.Remarks.Contains(text)) return true;
}
}
return false;
}
public string? GetBerthText(Times times)
{
string? berthText = null;
if ((BreCalLists.Berths != null) && times.BerthId.HasValue && (this.Shipcall?.Type != ShipcallType.Shifting))
{
Berth? berth = BreCalLists.AllBerths.Find((x) => x.Id == times.BerthId);
berthText = berth?.Name;
}
if ((berthText == null) && (times.ParticipantType != ParticipantType.TERMINAL))
{
if (this.Shipcall?.Type == ShipcallType.Arrival)
{
Berth? berth = BreCalLists.AllBerths?.Find((x) => x.Id == this.Shipcall?.ArrivalBerthId);
berthText = berth?.Name;
}
else
{
Berth? berth = BreCalLists.AllBerths?.Find((x) => x.Id == this.Shipcall?.DepartureBerthId);
berthText = berth?.Name;
}
}
return berthText;
}
/// <summary>
/// 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.
/// </summary>
/// <param name="_api">API reference to PUT eidted times</param>
internal async void UpdateTimesAssignments(DefaultApi _api)
{
foreach (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);
}
}
// if somebody just removed an assignment it is gone fom AssignedParticipants, but there is still a
// times record left which must be removed
List<Times> deleteTimes = new();
foreach (Times times in this.Times)
{
bool foundTimes = false;
foreach (ParticipantAssignment pa in this.AssignedParticipants.Values)
{
if((pa.ParticipantId == times.ParticipantId) && (pa.Type == times.ParticipantType))
{
foundTimes = true;
break;
}
}
if (!foundTimes)
{
deleteTimes.Add(times);
}
}
foreach(Times times in deleteTimes)
{
_api.TimesDelete(times.Id);
this.Times.Remove(times);
}
}
#endregion
#region helper
internal Participant? GetParticipantForType(Extensions.ParticipantType participantType)
{
if(AssignedParticipants.ContainsKey(participantType) && BreCalLists.ParticipantLookupDict.ContainsKey(AssignedParticipants[participantType].ParticipantId))
return BreCalLists.ParticipantLookupDict[AssignedParticipants[participantType].ParticipantId];
return null;
}
private bool IsFlagSet(StatusFlags flag)
{
if(this.Shipcall == null) return false;
return (this.Shipcall.Flags & (int) flag) != 0;
}
#endregion
}
}