diff --git a/misc/BreCalApi.cs b/misc/BreCalApi.cs index f33e5df..e9d4464 100644 --- a/misc/BreCalApi.cs +++ b/misc/BreCalApi.cs @@ -1,7 +1,7 @@ //---------------------- // -// Generated REST API Client Code Generator v1.8.4.0 on 06.10.2023 16:40:06 +// Generated REST API Client Code Generator v1.8.4.0 on 09.10.2023 17:46:55 // Using the tool OpenAPI Generator v7.0.0 // //---------------------- @@ -51,8 +51,7 @@ using System.Threading.Tasks; */ namespace BreCalClient.misc.Api { - -#pragma warning disable CS8073 // The result of the expression is always the same since a value of this type is never equal to 'null' + #pragma warning disable CS8073 // The result of the expression is always the same since a value of this type is never equal to 'null' /// /// Represents a collection of functions to interact with the API endpoints @@ -4913,16 +4912,18 @@ namespace BreCalClient.misc.Model /// /// id. /// name. - /// participantId. + /// ownerId. + /// authorityId. /// varLock. /// created. /// modified. /// deleted (default to false). - public Berth(int id = default(int), string name = default(string), int? participantId = default(int?), bool? varLock = default(bool?), DateTime created = default(DateTime), DateTime? modified = default(DateTime?), bool deleted = false) + public Berth(int id = default(int), string name = default(string), int? ownerId = default(int?), int? authorityId = default(int?), bool? varLock = default(bool?), DateTime created = default(DateTime), DateTime? modified = default(DateTime?), bool deleted = false) { this.Id = id; this.Name = name; - this.ParticipantId = participantId; + this.OwnerId = ownerId; + this.AuthorityId = authorityId; this.VarLock = varLock; this.Created = created; this.Modified = modified; @@ -4939,10 +4940,15 @@ namespace BreCalClient.misc.Model [DataMember(Name = "name", EmitDefaultValue = true)] public string Name { get; set; } /// - /// Gets or Sets ParticipantId + /// Gets or Sets OwnerId /// - [DataMember(Name = "participant_id", EmitDefaultValue = true)] - public int? ParticipantId { get; set; } + [DataMember(Name = "owner_id", EmitDefaultValue = true)] + public int? OwnerId { get; set; } + /// + /// Gets or Sets AuthorityId + /// + [DataMember(Name = "authority_id", EmitDefaultValue = true)] + public int? AuthorityId { get; set; } /// /// Gets or Sets VarLock /// @@ -4973,7 +4979,8 @@ namespace BreCalClient.misc.Model sb.Append("class Berth {\n"); sb.Append(" Id: ").Append(Id).Append("\n"); sb.Append(" Name: ").Append(Name).Append("\n"); - sb.Append(" ParticipantId: ").Append(ParticipantId).Append("\n"); + sb.Append(" OwnerId: ").Append(OwnerId).Append("\n"); + sb.Append(" AuthorityId: ").Append(AuthorityId).Append("\n"); sb.Append(" VarLock: ").Append(VarLock).Append("\n"); sb.Append(" Created: ").Append(Created).Append("\n"); sb.Append(" Modified: ").Append(Modified).Append("\n"); @@ -5020,9 +5027,14 @@ namespace BreCalClient.misc.Model this.Name.Equals(input.Name)) ) && ( - this.ParticipantId == input.ParticipantId || - (this.ParticipantId != null && - this.ParticipantId.Equals(input.ParticipantId)) + this.OwnerId == input.OwnerId || + (this.OwnerId != null && + this.OwnerId.Equals(input.OwnerId)) + ) && + ( + this.AuthorityId == input.AuthorityId || + (this.AuthorityId != null && + this.AuthorityId.Equals(input.AuthorityId)) ) && ( this.VarLock == input.VarLock || @@ -5058,9 +5070,13 @@ namespace BreCalClient.misc.Model { hashCode = (hashCode * 59) + this.Name.GetHashCode(); } - if (this.ParticipantId != null) + if (this.OwnerId != null) { - hashCode = (hashCode * 59) + this.ParticipantId.GetHashCode(); + hashCode = (hashCode * 59) + this.OwnerId.GetHashCode(); + } + if (this.AuthorityId != null) + { + hashCode = (hashCode * 59) + this.AuthorityId.GetHashCode(); } if (this.VarLock != null) { @@ -6153,6 +6169,125 @@ namespace BreCalClient.misc.Model } } +/* + * Bremen calling API + * + * Administer DEBRE ship calls, times and notifications + * + * The version of the OpenAPI document: 0.6.0 + * Contact: info@textbausteine.net + * Generated by: https://github.com/openapitools/openapi-generator.git + */ +namespace BreCalClient.misc.Model +{ + /// + /// Participant assigned to a shipcall with a given role (type) + /// + [DataContract(Name = "participant_assignment")] + public partial class ParticipantAssignment : IEquatable, IValidatableObject + { + /// + /// Initializes a new instance of the class. + /// + [JsonConstructorAttribute] + protected ParticipantAssignment() { } + /// + /// Initializes a new instance of the class. + /// + /// participantId (required). + /// type (required). + public ParticipantAssignment(int participantId = default(int), int type = default(int)) + { + this.ParticipantId = participantId; + this.Type = type; + } + /// + /// Gets or Sets ParticipantId + /// + [DataMember(Name = "participant_id", IsRequired = true, EmitDefaultValue = true)] + public int ParticipantId { get; set; } + /// + /// Gets or Sets Type + /// + [DataMember(Name = "type", IsRequired = true, EmitDefaultValue = true)] + public int Type { get; set; } + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.Append("class ParticipantAssignment {\n"); + sb.Append(" ParticipantId: ").Append(ParticipantId).Append("\n"); + sb.Append(" Type: ").Append(Type).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public virtual string ToJson() + { + return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented); + } + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as ParticipantAssignment); + } + /// + /// Returns true if ParticipantAssignment instances are equal + /// + /// Instance of ParticipantAssignment to be compared + /// Boolean + public bool Equals(ParticipantAssignment input) + { + if (input == null) + { + return false; + } + return + ( + this.ParticipantId == input.ParticipantId || + this.ParticipantId.Equals(input.ParticipantId) + ) && + ( + this.Type == input.Type || + this.Type.Equals(input.Type) + ); + } + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + hashCode = (hashCode * 59) + this.ParticipantId.GetHashCode(); + hashCode = (hashCode * 59) + this.Type.GetHashCode(); + return hashCode; + } + } + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } +} + /* * Bremen calling API * @@ -6513,7 +6648,7 @@ namespace BreCalClient.misc.Model /// participants. /// created. /// modified. - public Shipcall(int id = default(int), int shipId = default(int), int type = default(int), DateTime? eta = default(DateTime?), string voyage = default(string), DateTime? etd = default(DateTime?), int? arrivalBerthId = default(int?), int? departureBerthId = default(int?), bool? tugRequired = default(bool?), bool? pilotRequired = default(bool?), int? flags = default(int?), bool? pierSide = default(bool?), bool? bunkering = default(bool?), bool? replenishingTerminal = default(bool?), bool? replenishingLock = default(bool?), float? draft = default(float?), DateTime? tidalWindowFrom = default(DateTime?), DateTime? tidalWindowTo = default(DateTime?), bool? rainSensitiveCargo = default(bool?), int? recommendedTugs = default(int?), bool? anchored = default(bool?), bool? mooredLock = default(bool?), bool? canceled = default(bool?), int? evaluation = default(int?), string evaluationMessage = default(string), List participants = default(List), DateTime created = default(DateTime), DateTime? modified = default(DateTime?)) + public Shipcall(int id = default(int), int shipId = default(int), int type = default(int), DateTime? eta = default(DateTime?), string voyage = default(string), DateTime? etd = default(DateTime?), int? arrivalBerthId = default(int?), int? departureBerthId = default(int?), bool? tugRequired = default(bool?), bool? pilotRequired = default(bool?), int? flags = default(int?), bool? pierSide = default(bool?), bool? bunkering = default(bool?), bool? replenishingTerminal = default(bool?), bool? replenishingLock = default(bool?), float? draft = default(float?), DateTime? tidalWindowFrom = default(DateTime?), DateTime? tidalWindowTo = default(DateTime?), bool? rainSensitiveCargo = default(bool?), int? recommendedTugs = default(int?), bool? anchored = default(bool?), bool? mooredLock = default(bool?), bool? canceled = default(bool?), int? evaluation = default(int?), string evaluationMessage = default(string), List participants = default(List), DateTime created = default(DateTime), DateTime? modified = default(DateTime?)) { this.Id = id; this.ShipId = shipId; @@ -6678,9 +6813,8 @@ namespace BreCalClient.misc.Model /// /// Gets or Sets Participants /// - /// [1,5,7] [DataMember(Name = "participants", EmitDefaultValue = true)] - public List Participants { get; set; } + public List Participants { get; set; } /// /// Gets or Sets Created /// @@ -7640,8 +7774,6 @@ namespace BreCalClient.misc.Model yield break; } } - -#pragma warning restore CS8073 // The result of the expression is always the same since a value of this type is never equal to 'null' + #pragma warning restore CS8073 // The result of the expression is always the same since a value of this type is never equal to 'null' } - diff --git a/misc/BreCalApi.yaml b/misc/BreCalApi.yaml index 7829b13..dedbede 100644 --- a/misc/BreCalApi.yaml +++ b/misc/BreCalApi.yaml @@ -332,6 +332,17 @@ components: shipcallId: description: The unique identifier of a ship call type: integer + participant_assignment: + description: Participant assigned to a shipcall with a given role (type) + type: object + required: + - participant_id + - type + properties: + participant_id: + type: integer + type: + type: integer shipcall: type: object required: @@ -422,8 +433,7 @@ components: participants: type: array items: - type: integer - example: [1, 5, 7] + $ref: "#/components/schemas/participant_assignment" created: type: string format: date-time diff --git a/misc/create_schema.sql b/misc/create_schema.sql index 5bdb3e8..adbe508 100644 --- a/misc/create_schema.sql +++ b/misc/create_schema.sql @@ -225,6 +225,7 @@ CREATE TABLE `shipcall_participant_map` ( `id` int NOT NULL AUTO_INCREMENT, `shipcall_id` int unsigned DEFAULT NULL, `participant_id` int unsigned DEFAULT NULL, + `type` int unsigned DEFAULT NULL COMMENT 'Type of participant role', `created` datetime DEFAULT CURRENT_TIMESTAMP, `modified` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), diff --git a/src/BreCalClient/EditShipcallControl.xaml.cs b/src/BreCalClient/EditShipcallControl.xaml.cs index 69dd9d8..5627531 100644 --- a/src/BreCalClient/EditShipcallControl.xaml.cs +++ b/src/BreCalClient/EditShipcallControl.xaml.cs @@ -1,6 +1,6 @@ // Copyright (c) 2023 schick Informatik // Description: Windows dialog to create / edit ship calls -// +// using BreCalClient.misc.Model; using System; @@ -26,11 +26,11 @@ namespace BreCalClient public ShipcallControlModel ShipcallModel { get; set; } = new (); - public Ship? SelectedShip { + public Ship? SelectedShip { get { return this.comboBoxShip.SelectedItem as Ship; - } + } } #endregion @@ -39,7 +39,7 @@ namespace BreCalClient private void Window_Loaded(object sender, RoutedEventArgs e) { - this.comboBoxAgency.ItemsSource = BreCalLists.Participants_Agent; + this.comboBoxAgency.ItemsSource = BreCalLists.Participants_Agent; this.comboBoxShip.ItemsSource = BreCalLists.Ships; this.comboBoxCategories.ItemsSource = Enum.GetValues(typeof(Extensions.TypeEnum)); @@ -55,13 +55,13 @@ namespace BreCalClient private void buttonOK_Click(object sender, RoutedEventArgs e) { this.CopyToModel(); - this.DialogResult = true; + this.DialogResult = true; this.Close(); } private void buttonCancel_Click(object sender, RoutedEventArgs e) { - this.DialogResult= false; + this.DialogResult= false; this.Close(); } @@ -98,7 +98,7 @@ namespace BreCalClient { this.comboBoxAgency.SelectedIndex = -1; this.ShipcallModel.AssignedParticipants.Remove(Extensions.ParticipantType.AGENCY); - } + } private void contextMenuItemArrivalBerth_Click(object sender, RoutedEventArgs e) { @@ -155,14 +155,14 @@ namespace BreCalClient this.ShipcallModel.Shipcall.Type = (int)this.comboBoxCategories.SelectedItem; this.ShipcallModel.Shipcall.Eta = this.datePickerETA.Value; this.ShipcallModel.Shipcall.Etd = this.datePickerETD.Value; - + this.ShipcallModel.Shipcall.ShipId = ((Ship)this.comboBoxShip.SelectedItem).Id; this.ShipcallModel.Ship = (Ship)this.comboBoxShip.SelectedItem; this.ShipcallModel.Shipcall.ArrivalBerthId = (this.comboBoxArrivalBerth.SelectedItem != null) ? ((Berth)this.comboBoxArrivalBerth.SelectedItem).Id : null; this.ShipcallModel.Shipcall.DepartureBerthId = (this.comboBoxDepartureBerth.SelectedItem != null) ? ((Berth)this.comboBoxDepartureBerth.SelectedItem).Id : null; - - - + + + // remove all and add selected participants this.ShipcallModel.Shipcall.Participants.Clear(); this.ShipcallModel.AssignedParticipants.Clear(); @@ -171,23 +171,42 @@ namespace BreCalClient participant = (Participant?)this.comboBoxAgency.SelectedItem; if (participant != null) { - this.ShipcallModel.Shipcall.Participants.Add(participant.Id); - this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.AGENCY] = participant; + ParticipantAssignment pa = new() + { + ParticipantId = participant.Id, + Type = (int)Extensions.ParticipantType.AGENCY + }; + this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.AGENCY] = pa; } - + // BSMD and port authority are always added - foreach (Participant p in BreCalLists.Participants) + + // get port authority from berth + + int? berthId = this.ShipcallModel.Shipcall.ArrivalBerthId; + if (berthId == null) berthId = this.ShipcallModel.Shipcall.DepartureBerthId; + if (berthId != null) { - if (p.Type == (int)Extensions.ParticipantType.PORT_ADMINISTRATION) + Berth? selectedBerth = BreCalLists.Berths.Find((x) => x.Id == berthId); + if (selectedBerth?.AuthorityId != null) { - this.ShipcallModel.Shipcall.Participants.Add(p.Id); - this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.PORT_ADMINISTRATION] = p; + if (BreCalLists.ParticipantLookupDict.ContainsKey(selectedBerth.AuthorityId.Value)) + { + ParticipantAssignment pab = new() + { + ParticipantId = selectedBerth.AuthorityId.Value, + Type = (int)Extensions.ParticipantType.PORT_ADMINISTRATION + }; + this.ShipcallModel.AssignedParticipants[ParticipantType.PORT_ADMINISTRATION] = pab; + } } - if (p.Type == (int)Extensions.ParticipantType.BSMD) + + ParticipantAssignment pa = new() { - this.ShipcallModel.Shipcall.Participants.Add(p.Id); - this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.BSMD] = p; - } + ParticipantId = App.Participant.Id, + Type = (int)Extensions.ParticipantType.BSMD + }; + this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.BSMD] = pa; } } } @@ -201,16 +220,16 @@ namespace BreCalClient if (this.ShipcallModel.Shipcall.Eta != DateTime.MinValue) this.datePickerETA.Value = this.ShipcallModel.Shipcall.Eta; // this.textBoxVoyage.Text = this.ShipcallModel.Shipcall.Voyage; - this.datePickerETD.Value = this.ShipcallModel.Shipcall.Etd; + this.datePickerETD.Value = this.ShipcallModel.Shipcall.Etd; this.comboBoxShip.SelectedValue = this.ShipcallModel.Shipcall.ShipId; this.comboBoxArrivalBerth.SelectedValue = this.ShipcallModel.Shipcall.ArrivalBerthId; this.comboBoxDepartureBerth.SelectedValue = this.ShipcallModel.Shipcall.DepartureBerthId; - + if (this.ShipcallModel.Shipcall.Participants == null) this.ShipcallModel.Shipcall.Participants = new(); - foreach (int participant_id in this.ShipcallModel.Shipcall.Participants) + foreach (ParticipantAssignment participantAssignment in this.ShipcallModel.Shipcall.Participants) { - if (((List)this.comboBoxAgency.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxAgency.SelectedValue = participant_id; + if (((List)this.comboBoxAgency.ItemsSource).Any(x => x.Id == participantAssignment.ParticipantId)) this.comboBoxAgency.SelectedValue = participantAssignment.ParticipantId; } } } @@ -231,7 +250,7 @@ namespace BreCalClient { if(p.IsFlagSet(ParticipantFlag.ALLOW_BSMD) && isBsmd) isAgency = true; - if(p.IsFlagSet(ParticipantFlag.ALLOW_BSMD)) + if(p.IsFlagSet(ParticipantFlag.ALLOW_BSMD)) editRightGrantedForBSMD = true; } } @@ -239,16 +258,16 @@ namespace BreCalClient this.comboBoxAgency.IsEnabled = isBsmd; this.comboBoxArrivalBerth.IsEnabled = isBsmd || isAgency; this.comboBoxCategories.IsEnabled = isBsmd; - this.comboBoxDepartureBerth.IsEnabled = isBsmd || isAgency; - this.comboBoxShip.IsEnabled = isBsmd; + this.comboBoxDepartureBerth.IsEnabled = isBsmd || isAgency; + this.comboBoxShip.IsEnabled = isBsmd; this.datePickerETA.IsEnabled = isAgency || isBsmd; this.datePickerETD.IsEnabled = isAgency; - + this.labelBSMDGranted.Visibility = editRightGrantedForBSMD ? Visibility.Visible : Visibility.Hidden; } #endregion - + } } diff --git a/src/BreCalClient/EditTimesAgencyIncomingControl.xaml.cs b/src/BreCalClient/EditTimesAgencyIncomingControl.xaml.cs index 48f2b34..2cea953 100644 --- a/src/BreCalClient/EditTimesAgencyIncomingControl.xaml.cs +++ b/src/BreCalClient/EditTimesAgencyIncomingControl.xaml.cs @@ -98,26 +98,42 @@ namespace BreCalClient Participant? participant = (Participant?)this.comboBoxMooring.SelectedItem; if (participant != null) { - this.ShipcallModel.Shipcall.Participants.Add(participant.Id); - this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.MOORING] = participant; + ParticipantAssignment participantAssignment = new() { + ParticipantId = participant.Id, + Type = (int)Extensions.ParticipantType.MOORING + }; + this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.MOORING] = participantAssignment; } + participant = (Participant?)this.comboBoxPilot.SelectedItem; if (participant != null) { - this.ShipcallModel.Shipcall.Participants.Add(participant.Id); - this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.PILOT] = participant; + ParticipantAssignment participantAssignment = new() + { + ParticipantId = participant.Id, + Type = (int)Extensions.ParticipantType.PILOT + }; + this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.PILOT] = participantAssignment; } participant = (Participant?)this.comboBoxTerminal.SelectedItem; if (participant != null) { - this.ShipcallModel.Shipcall.Participants.Add(participant.Id); - this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.TERMINAL] = participant; + ParticipantAssignment participantAssignment = new() + { + ParticipantId = participant.Id, + Type = (int)Extensions.ParticipantType.TERMINAL + }; + this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.TERMINAL] = participantAssignment; } participant = (Participant?)this.comboBoxTug.SelectedItem; if (participant != null) { - this.ShipcallModel.Shipcall.Participants.Add(participant.Id); - this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.TUG] = participant; + ParticipantAssignment participantAssignment = new() + { + ParticipantId = participant.Id, + Type = (int)Extensions.ParticipantType.TUG + }; + this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.TUG] = participantAssignment; } } } @@ -168,12 +184,12 @@ namespace BreCalClient if(!string.IsNullOrEmpty(this.Times.Remarks)) this.textBoxRemarks.Text = this.Times.Remarks; - foreach (int participant_id in this.ShipcallModel.Shipcall.Participants) + foreach (ParticipantAssignment participantAssignment in this.ShipcallModel.Shipcall.Participants) { - if (((List)this.comboBoxMooring.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxMooring.SelectedValue = participant_id; - if (((List)this.comboBoxPilot.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxPilot.SelectedValue = participant_id; - if (((List)this.comboBoxTerminal.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxTerminal.SelectedValue = participant_id; - if (((List)this.comboBoxTug.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxTug.SelectedValue = participant_id; + if (((List)this.comboBoxMooring.ItemsSource).Any(x => x.Id == participantAssignment.ParticipantId)) this.comboBoxMooring.SelectedValue = participantAssignment.ParticipantId; + if (((List)this.comboBoxPilot.ItemsSource).Any(x => x.Id == participantAssignment.ParticipantId)) this.comboBoxPilot.SelectedValue = participantAssignment.ParticipantId; + if (((List)this.comboBoxTerminal.ItemsSource).Any(x => x.Id == participantAssignment.ParticipantId)) this.comboBoxTerminal.SelectedValue = participantAssignment.ParticipantId; + if (((List)this.comboBoxTug.ItemsSource).Any(x => x.Id == participantAssignment.ParticipantId)) this.comboBoxTug.SelectedValue = participantAssignment.ParticipantId; } } } diff --git a/src/BreCalClient/EditTimesAgencyOutgoingControl.xaml.cs b/src/BreCalClient/EditTimesAgencyOutgoingControl.xaml.cs index f53a5e8..e918307 100644 --- a/src/BreCalClient/EditTimesAgencyOutgoingControl.xaml.cs +++ b/src/BreCalClient/EditTimesAgencyOutgoingControl.xaml.cs @@ -93,26 +93,42 @@ namespace BreCalClient Participant? participant = (Participant?)this.comboBoxMooring.SelectedItem; if (participant != null) { - this.ShipcallModel.Shipcall.Participants.Add(participant.Id); - this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.MOORING] = participant; + ParticipantAssignment participantAssignment = new() + { + ParticipantId = participant.Id, + Type = (int)Extensions.ParticipantType.MOORING + }; + this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.MOORING] = participantAssignment; } participant = (Participant?)this.comboBoxPilot.SelectedItem; if (participant != null) { - this.ShipcallModel.Shipcall.Participants.Add(participant.Id); - this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.PILOT] = participant; + ParticipantAssignment participantAssignment = new() + { + ParticipantId = participant.Id, + Type = (int)Extensions.ParticipantType.PILOT + }; + this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.PILOT] = participantAssignment; } participant = (Participant?)this.comboBoxTerminal.SelectedItem; if (participant != null) { - this.ShipcallModel.Shipcall.Participants.Add(participant.Id); - this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.TERMINAL] = participant; + ParticipantAssignment participantAssignment = new() + { + ParticipantId = participant.Id, + Type = (int)Extensions.ParticipantType.TERMINAL + }; + this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.TERMINAL] = participantAssignment; } participant = (Participant?)this.comboBoxTug.SelectedItem; if (participant != null) { - this.ShipcallModel.Shipcall.Participants.Add(participant.Id); - this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.TUG] = participant; + ParticipantAssignment participantAssignment = new() + { + ParticipantId = participant.Id, + Type = (int)Extensions.ParticipantType.TUG + }; + this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.TUG] = participantAssignment; } } } @@ -158,12 +174,12 @@ namespace BreCalClient if(!string.IsNullOrEmpty(this.Times.Remarks)) this.textBoxRemarks.Text = this.Times.Remarks; - foreach (int participant_id in this.ShipcallModel.Shipcall.Participants) + foreach (ParticipantAssignment participantAssignment in this.ShipcallModel.Shipcall.Participants) { - if (((List)this.comboBoxMooring.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxMooring.SelectedValue = participant_id; - if (((List)this.comboBoxPilot.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxPilot.SelectedValue = participant_id; - if (((List)this.comboBoxTerminal.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxTerminal.SelectedValue = participant_id; - if (((List)this.comboBoxTug.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxTug.SelectedValue = participant_id; + if (((List)this.comboBoxMooring.ItemsSource).Any(x => x.Id == participantAssignment.ParticipantId)) this.comboBoxMooring.SelectedValue = participantAssignment.ParticipantId; + if (((List)this.comboBoxPilot.ItemsSource).Any(x => x.Id == participantAssignment.ParticipantId)) this.comboBoxPilot.SelectedValue = participantAssignment.ParticipantId; + if (((List)this.comboBoxTerminal.ItemsSource).Any(x => x.Id == participantAssignment.ParticipantId)) this.comboBoxTerminal.SelectedValue = participantAssignment.ParticipantId; + if (((List)this.comboBoxTug.ItemsSource).Any(x => x.Id == participantAssignment.ParticipantId)) this.comboBoxTug.SelectedValue = participantAssignment.ParticipantId; } } } diff --git a/src/BreCalClient/EditTimesAgencyShiftingControl.xaml.cs b/src/BreCalClient/EditTimesAgencyShiftingControl.xaml.cs index 362cfc8..493368c 100644 --- a/src/BreCalClient/EditTimesAgencyShiftingControl.xaml.cs +++ b/src/BreCalClient/EditTimesAgencyShiftingControl.xaml.cs @@ -98,26 +98,42 @@ namespace BreCalClient Participant? participant = (Participant?)this.comboBoxMooring.SelectedItem; if (participant != null) { - this.ShipcallModel.Shipcall.Participants.Add(participant.Id); - this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.MOORING] = participant; + ParticipantAssignment pa = new() + { + ParticipantId = participant.Id, + Type = (int)Extensions.ParticipantType.MOORING + }; + this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.MOORING] = pa; } participant = (Participant?)this.comboBoxPilot.SelectedItem; if (participant != null) { - this.ShipcallModel.Shipcall.Participants.Add(participant.Id); - this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.PILOT] = participant; + ParticipantAssignment pa = new() + { + ParticipantId = participant.Id, + Type = (int)Extensions.ParticipantType.PILOT + }; + this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.PILOT] = pa; } participant = (Participant?)this.comboBoxTerminal.SelectedItem; if (participant != null) { - this.ShipcallModel.Shipcall.Participants.Add(participant.Id); - this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.TERMINAL] = participant; + ParticipantAssignment pa = new() + { + ParticipantId = participant.Id, + Type = (int)Extensions.ParticipantType.TERMINAL + }; + this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.TERMINAL] = pa; } participant = (Participant?)this.comboBoxTug.SelectedItem; if (participant != null) { - this.ShipcallModel.Shipcall.Participants.Add(participant.Id); - this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.TUG] = participant; + ParticipantAssignment pa = new() + { + ParticipantId = participant.Id, + Type = (int)Extensions.ParticipantType.TUG + }; + this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.TUG] = pa; } } } @@ -175,12 +191,12 @@ namespace BreCalClient if(!string.IsNullOrEmpty(this.Times.Remarks)) this.textBoxRemarks.Text = this.Times.Remarks; - foreach (int participant_id in this.ShipcallModel.Shipcall.Participants) + foreach (ParticipantAssignment participantAssignment in this.ShipcallModel.Shipcall.Participants) { - if (((List)this.comboBoxMooring.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxMooring.SelectedValue = participant_id; - if (((List)this.comboBoxPilot.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxPilot.SelectedValue = participant_id; - if (((List)this.comboBoxTerminal.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxTerminal.SelectedValue = participant_id; - if (((List)this.comboBoxTug.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxTug.SelectedValue = participant_id; + if (((List)this.comboBoxMooring.ItemsSource).Any(x => x.Id == participantAssignment.ParticipantId)) this.comboBoxMooring.SelectedValue = participantAssignment.ParticipantId; + if (((List)this.comboBoxPilot.ItemsSource).Any(x => x.Id == participantAssignment.ParticipantId)) this.comboBoxPilot.SelectedValue = participantAssignment.ParticipantId; + if (((List)this.comboBoxTerminal.ItemsSource).Any(x => x.Id == participantAssignment.ParticipantId)) this.comboBoxTerminal.SelectedValue = participantAssignment.ParticipantId; + if (((List)this.comboBoxTug.ItemsSource).Any(x => x.Id == participantAssignment.ParticipantId)) this.comboBoxTug.SelectedValue = participantAssignment.ParticipantId; } } } diff --git a/src/BreCalClient/MainWindow.xaml.cs b/src/BreCalClient/MainWindow.xaml.cs index e6a3d90..8f4e568 100644 --- a/src/BreCalClient/MainWindow.xaml.cs +++ b/src/BreCalClient/MainWindow.xaml.cs @@ -173,6 +173,9 @@ namespace BreCalClient { this.UpdateUI(); + esc.ShipcallModel.Shipcall?.Participants.Clear(); + foreach (ParticipantAssignment pa in esc.ShipcallModel.AssignedParticipants.Values) + esc.ShipcallModel.Shipcall?.Participants.Add(pa); this._api.ShipcallsPost(esc.ShipcallModel.Shipcall); // save new ship call this.AddShipcall(esc.ShipcallModel); @@ -371,7 +374,7 @@ namespace BreCalClient scm.Ship = BreCalLists.ShipLookupDict[shipcall.ShipId]; if (BreCalLists.BerthLookupDict.ContainsKey(shipcall.ArrivalBerthId ?? 0)) scm.Berth = BreCalLists.BerthLookupDict[shipcall.ArrivalBerthId ?? 0].Name; - scm.AssignParticipants(BreCalLists.Participants); + scm.AssignParticipants(); this.Dispatcher.Invoke(() => { @@ -396,7 +399,7 @@ namespace BreCalClient scm.Ship = BreCalLists.ShipLookupDict[shipcall.ShipId]; if (BreCalLists.BerthLookupDict.ContainsKey(shipcall.ArrivalBerthId ?? 0)) scm.Berth = BreCalLists.BerthLookupDict[shipcall.ArrivalBerthId ?? 0].Name; - scm.AssignParticipants(BreCalLists.Participants); + scm.AssignParticipants(); } private void RemoveShipcall(int shipcallId) @@ -539,6 +542,9 @@ namespace BreCalClient { try { + obj.ShipcallControlModel.Shipcall?.Participants.Clear(); + foreach(ParticipantAssignment pa in obj.ShipcallControlModel.AssignedParticipants.Values) + obj.ShipcallControlModel.Shipcall?.Participants.Add(pa); await _api.ShipcallsPutAsync(obj.ShipcallControlModel.Shipcall); obj.RefreshData(); _refreshImmediately = true; @@ -643,6 +649,9 @@ namespace BreCalClient sc.ShipcallControlModel?.Times.Add(editControl.Times); } + editControl.ShipcallModel.Shipcall?.Participants.Clear(); + foreach (ParticipantAssignment pa in editControl.ShipcallModel.AssignedParticipants.Values) + editControl.ShipcallModel.Shipcall?.Participants.Add(pa); await _api.ShipcallsPutAsync(editControl.ShipcallModel.Shipcall); _refreshImmediately = true; _tokenSource.Cancel(); diff --git a/src/BreCalClient/ShipcallControlModel.cs b/src/BreCalClient/ShipcallControlModel.cs index 36857e3..f3148d0 100644 --- a/src/BreCalClient/ShipcallControlModel.cs +++ b/src/BreCalClient/ShipcallControlModel.cs @@ -47,7 +47,7 @@ namespace BreCalClient public string? Berth { get; set; } - internal Dictionary AssignedParticipants { get; } = new(); + internal Dictionary AssignedParticipants { get; } = new(); public List Times { get; set; } = new(); @@ -79,22 +79,14 @@ namespace BreCalClient #region public methods - public void AssignParticipants(List participants) + public void AssignParticipants() { this.AssignedParticipants.Clear(); if (Shipcall != null) { - foreach (int participantId in Shipcall.Participants) + foreach (ParticipantAssignment participantAssignment in Shipcall.Participants) { - Participant? participant = participants.Find((x) => x.Id == participantId); - if (participant != null) - { - foreach(Extensions.ParticipantType participantType in Enum.GetValues(typeof(Extensions.ParticipantType))) - { - if(participant.IsTypeFlagSet(participantType)) - AssignedParticipants[participantType] = participant; - } - } + AssignedParticipants[(Extensions.ParticipantType)participantAssignment.Type] = participantAssignment; } } } @@ -103,7 +95,7 @@ namespace BreCalClient { if (AssignedParticipants.ContainsKey(type)) { - int participantId = AssignedParticipants[type].Id; + int participantId = AssignedParticipants[type].ParticipantId; foreach (Times times in this.Times) { if ((times.ParticipantId == participantId) && (times.ParticipantType == (int) type)) @@ -145,11 +137,9 @@ namespace BreCalClient internal Participant? GetParticipantForType(Extensions.ParticipantType participantType) { - foreach(Participant p in AssignedParticipants.Values) - { - if (p.IsTypeFlagSet(participantType)) - return p; - } + if(AssignedParticipants.ContainsKey(participantType) && BreCalLists.ParticipantLookupDict.ContainsKey(AssignedParticipants[participantType].ParticipantId)) + return BreCalLists.ParticipantLookupDict[AssignedParticipants[participantType].ParticipantId]; + return null; } diff --git a/src/server/BreCal/impl/shipcalls.py b/src/server/BreCal/impl/shipcalls.py index 7aa8e95..b8c20e5 100644 --- a/src/server/BreCal/impl/shipcalls.py +++ b/src/server/BreCal/impl/shipcalls.py @@ -22,9 +22,11 @@ def GetShipcalls(options): "anchored, moored_lock, canceled, evaluation, evaluation_message, created, modified FROM shipcall WHERE eta IS NULL OR eta >= DATE(NOW() - INTERVAL 2 DAY) " + "ORDER BY eta", model=model.Shipcall) for shipcall in data: - participant_query = "SELECT participant_id FROM shipcall_participant_map WHERE shipcall_id=?shipcall_id?"; + participant_query = "SELECT participant_id, type FROM shipcall_participant_map WHERE shipcall_id=?shipcall_id?"; for record in commands.query(participant_query, model=dict, param={"shipcall_id" : shipcall.id}, buffered=False): - shipcall.participants.append(record["participant_id"]) + # model.Participant_Assignment = model.Participant_Assignment() + pa = model.Participant_Assignment(record["participant_id"], record["type"]) + shipcall.participants.append(pa) pooledConnection.close() @@ -96,11 +98,9 @@ def PostShipcalls(schemaModel): new_id = commands.execute_scalar("select last_insert_id()") # add participant assignments - # TODO: make sure there are not two participants of the same type - - pquery = "INSERT INTO shipcall_participant_map (shipcall_id, participant_id) VALUES (?shipcall_id?, ?participant_id?)" - for participant_id in schemaModel["participants"]: - commands.execute(pquery, param={"shipcall_id" : new_id, "participant_id" : participant_id}) + pquery = "INSERT INTO shipcall_participant_map (shipcall_id, participant_id, type) VALUES (?shipcall_id?, ?participant_id?, ?type?)" + for participant_assignment in schemaModel["participants"]: + commands.execute(pquery, param={"shipcall_id" : new_id, "participant_id" : participant_assignment["participant_id"], "type" : participant_assignment["type"]}) pooledConnection.close() @@ -157,27 +157,26 @@ def PutShipcalls(schemaModel): query += "WHERE id = ?id?" affected_rows = commands.execute(query, param=schemaModel) - pquery = "SELECT id, participant_id FROM shipcall_participant_map where shipcall_id = ?id?" + pquery = "SELECT id, participant_id, type FROM shipcall_participant_map where shipcall_id = ?id?" pdata = commands.query(pquery,param={"id" : schemaModel["id"]}) # existing list of assignments # loop across passed participant ids, creating entries for those not present in pdata - # TODO: make sure there are not two participants of the same type - for participant_id in schemaModel["participants"]: + for participant_assignment in schemaModel["participants"]: found_participant = False for elem in pdata: - if elem["participant_id"] == participant_id: + if elem["participant_id"] == participant_assignment["participant_id"] and elem["type"] == participant_assignment["type"]: found_participant = True break if not found_participant: - nquery = "INSERT INTO shipcall_participant_map (shipcall_id, participant_id) VALUES (?shipcall_id?, ?participant_id?)" - commands.execute(nquery, param={"shipcall_id" : schemaModel["id"], "participant_id" : participant_id}) + nquery = "INSERT INTO shipcall_participant_map (shipcall_id, participant_id, type) VALUES (?shipcall_id?, ?participant_id?, ?type?)" + commands.execute(nquery, param={"shipcall_id" : schemaModel["id"], "participant_id" : participant_assignment["participant_id"], "type" : participant_assignment["type"]}) # loop across existing pdata entries, deleting those not present in participant list for elem in pdata: found_participant = False - for participant_id in schemaModel["participants"]: - if(participant_id == elem["participant_id"]): + for participant_assignment in schemaModel["participants"]: + if(participant_assignment["participant_id"] == elem["participant_id"] and participant_assignment["type"] == elem["type"]): found_participant = True break; if not found_participant: diff --git a/src/server/BreCal/schemas/model.py b/src/server/BreCal/schemas/model.py index 434b92f..fdd6e94 100644 --- a/src/server/BreCal/schemas/model.py +++ b/src/server/BreCal/schemas/model.py @@ -59,6 +59,10 @@ class Participant(Schema): class ParticipantList(Participant): pass +class ParticipantAssignmentSchema(Schema): + participant_id = fields.Int() + type = fields.Int() + class ShipcallSchema(Schema): def __init__(self): super().__init__(unknown=None) @@ -89,10 +93,20 @@ class ShipcallSchema(Schema): canceled = fields.Bool(Required = False, allow_none=True) evaluation = fields.Int(Required = False, allow_none=True) evaluation_message = fields.Str(Required = False, allow_none=True) - participants = fields.List(fields.Int) + participants = fields.List(fields.Nested(ParticipantAssignmentSchema)) created = fields.DateTime(Required = False, allow_none=True) modified = fields.DateTime(Required = False, allow_none=True) +@dataclass +class Participant_Assignment: + def __init__(self, participant_id, type): + self.participant_id = participant_id + self.type = type + pass + + participant_id: int + type: int + @dataclass class Shipcall: @@ -123,7 +137,7 @@ class Shipcall: evaluation_message: str created: datetime modified: datetime - participants: List[int] = field(default_factory=list) + participants: List[Participant_Assignment] = field(default_factory=list) class ShipcallId(Schema): pass