Merge branch 'release/1.6.0'
This commit is contained in:
commit
3f37ee67e5
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
23
misc/clear_entries_for_participant.sql
Normal file
23
misc/clear_entries_for_participant.sql
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
DELETE FROM times WHERE
|
||||||
|
times.shipcall_id IN
|
||||||
|
(
|
||||||
|
SELECT s.id FROM shipcall s
|
||||||
|
JOIN shipcall_participant_map spm ON s.id = spm.shipcall_id
|
||||||
|
JOIN participant p ON spm.participant_id = p.id
|
||||||
|
WHERE p.id = 10
|
||||||
|
);
|
||||||
|
|
||||||
|
DELETE `history` FROM `history`
|
||||||
|
JOIN shipcall s on `history`.shipcall_id = s.id
|
||||||
|
JOIN shipcall_participant_map spm ON s.id = spm.shipcall_id
|
||||||
|
WHERE spm.participant_id = 10;
|
||||||
|
|
||||||
|
-- damit das hier funktioniert muss der FK in shipcall_participant_map von "RESTRICT" auf "SET NULL"
|
||||||
|
-- geändert werden
|
||||||
|
|
||||||
|
DELETE shipcall FROM shipcall
|
||||||
|
INNER JOIN shipcall_participant_map spm ON shipcall.id = spm.shipcall_id
|
||||||
|
JOIN participant p ON spm.participant_id = p.id
|
||||||
|
WHERE p.id = 10;
|
||||||
|
|
||||||
|
DELETE FROM shipcall_participant_map WHERE participant_id = 10;
|
||||||
37
misc/requirements.txt
Normal file
37
misc/requirements.txt
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
bcrypt==4.2.0
|
||||||
|
blinker==1.8.2
|
||||||
|
cached-property==1.5.2
|
||||||
|
click==8.1.7
|
||||||
|
coro-context-manager==0.2.0
|
||||||
|
coverage==7.6.1
|
||||||
|
dsnparse==0.1.15
|
||||||
|
Flask==3.0.3
|
||||||
|
Flask-JWT-Extended==4.6.0
|
||||||
|
iniconfig==2.0.0
|
||||||
|
itsdangerous==2.2.0
|
||||||
|
Jinja2==3.1.4
|
||||||
|
MarkupSafe==2.1.5
|
||||||
|
marshmallow==3.22.0
|
||||||
|
marshmallow-enum==1.5.1
|
||||||
|
marshmallow_dataclass==8.7.1
|
||||||
|
mypy-extensions==1.0.0
|
||||||
|
mysql-connector-python==9.0.0
|
||||||
|
numpy==2.1.1
|
||||||
|
packaging==24.1
|
||||||
|
pandas==2.2.3
|
||||||
|
pluggy==1.5.0
|
||||||
|
pydapper==0.10.0
|
||||||
|
PyJWT==2.9.0
|
||||||
|
pytest==8.3.3
|
||||||
|
pytest-cov==5.0.0
|
||||||
|
python-dateutil==2.9.0.post0
|
||||||
|
pytz==2024.2
|
||||||
|
schedule==1.2.2
|
||||||
|
six==1.16.0
|
||||||
|
tqdm==4.66.5
|
||||||
|
typeguard==4.3.0
|
||||||
|
typing-inspect==0.9.0
|
||||||
|
typing_extensions==4.12.2
|
||||||
|
tzdata==2024.1
|
||||||
|
webargs==8.6.0
|
||||||
|
Werkzeug==3.0.4
|
||||||
57
misc/update_1.5_to_1.6.sql
Normal file
57
misc/update_1.5_to_1.6.sql
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
CREATE TABLE `port` (
|
||||||
|
`id` int unsigned NOT NULL AUTO_INCREMENT,
|
||||||
|
`name` varchar(128) NOT NULL COMMENT 'Name of port',
|
||||||
|
`locode` char(5) DEFAULT NULL COMMENT 'UNECE locode',
|
||||||
|
`created` datetime DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`modified` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
`deleted` bit(1) DEFAULT b'0',
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Port as reference for shipcalls and berths';
|
||||||
|
|
||||||
|
-- Add default port to table
|
||||||
|
INSERT INTO port (id, name, locode) VALUES (1, 'Bremen', 'DEBRE');
|
||||||
|
|
||||||
|
-- Adding new ref column to berth
|
||||||
|
ALTER TABLE `berth`
|
||||||
|
ADD COLUMN `port_id` INT UNSIGNED DEFAULT NULL AFTER `authority_id`;
|
||||||
|
ALTER TABLE `berth` ALTER INDEX `FK_AUTHORITY_PART_idx` INVISIBLE;
|
||||||
|
|
||||||
|
-- adding a foreign key berth.port_id -> port.id
|
||||||
|
ALTER TABLE `berth`
|
||||||
|
ADD INDEX `FK_PORT_PART_idx` (`port_id` ASC) VISIBLE;
|
||||||
|
|
||||||
|
ALTER TABLE `berth`
|
||||||
|
ADD CONSTRAINT `FK_PORT`
|
||||||
|
FOREIGN KEY (`port_id`)
|
||||||
|
REFERENCES `port` (`id`)
|
||||||
|
ON DELETE RESTRICT
|
||||||
|
ON UPDATE RESTRICT;
|
||||||
|
|
||||||
|
-- adding new ref column to shipcall incl. foreign key
|
||||||
|
ALTER TABLE `shipcall`
|
||||||
|
ADD COLUMN `port_id` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'Selected port for this shipcall' AFTER `evaluation_notifications_sent`,
|
||||||
|
CHANGE COLUMN `time_ref_point` `time_ref_point` INT NULL DEFAULT '0' COMMENT 'Index of a location which is the reference point for all time value entries, e.g. berth or Geeste' AFTER `port_id`,
|
||||||
|
ADD INDEX `FK_SHIPCALL_PORT_idx` (`port_id` ASC) VISIBLE;
|
||||||
|
;
|
||||||
|
ALTER TABLE `shipcall`
|
||||||
|
ADD CONSTRAINT `FK_SHIPCALL_PORT`
|
||||||
|
FOREIGN KEY (`port_id`)
|
||||||
|
REFERENCES `port` (`id`)
|
||||||
|
ON DELETE RESTRICT
|
||||||
|
ON UPDATE RESTRICT;
|
||||||
|
|
||||||
|
CREATE TABLE `participant_port_map` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT,
|
||||||
|
`participant_id` int unsigned NOT NULL COMMENT 'Ref to participant',
|
||||||
|
`port_id` int unsigned NOT NULL COMMENT 'Ref to port',
|
||||||
|
`created` datetime DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`modified` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `FK_PP_PARTICIPANT` (`participant_id`),
|
||||||
|
KEY `FK_PP_PORT` (`port_id`),
|
||||||
|
CONSTRAINT `FK_PP_PARTICIPANT` FOREIGN KEY (`participant_id`) REFERENCES `participant` (`id`),
|
||||||
|
CONSTRAINT `FK_PP_PORT` FOREIGN KEY (`port_id`) REFERENCES `port` (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Mapping table that assigns participants to a port';
|
||||||
|
|
||||||
|
-- all existing berths shall default to "bremen"
|
||||||
|
UPDATE berth SET port_id = 1 where port_id is null;
|
||||||
@ -1 +1 @@
|
|||||||
1.4.1.0
|
1.6.0.8
|
||||||
@ -8,8 +8,8 @@
|
|||||||
<SignAssembly>True</SignAssembly>
|
<SignAssembly>True</SignAssembly>
|
||||||
<StartupObject>BreCalClient.App</StartupObject>
|
<StartupObject>BreCalClient.App</StartupObject>
|
||||||
<AssemblyOriginatorKeyFile>..\..\misc\brecal.snk</AssemblyOriginatorKeyFile>
|
<AssemblyOriginatorKeyFile>..\..\misc\brecal.snk</AssemblyOriginatorKeyFile>
|
||||||
<AssemblyVersion>1.5.0.12</AssemblyVersion>
|
<AssemblyVersion>1.6.0.8</AssemblyVersion>
|
||||||
<FileVersion>1.5.0.12</FileVersion>
|
<FileVersion>1.6.0.8</FileVersion>
|
||||||
<Title>Bremen calling client</Title>
|
<Title>Bremen calling client</Title>
|
||||||
<Description>A Windows WPF client for the Bremen calling API.</Description>
|
<Description>A Windows WPF client for the Bremen calling API.</Description>
|
||||||
<ApplicationIcon>containership.ico</ApplicationIcon>
|
<ApplicationIcon>containership.ico</ApplicationIcon>
|
||||||
|
|||||||
@ -25,16 +25,19 @@ namespace BreCalClient
|
|||||||
private static List<Participant> _participants = new();
|
private static List<Participant> _participants = new();
|
||||||
private static readonly List<ShipModel> _ships = new();
|
private static readonly List<ShipModel> _ships = new();
|
||||||
private static readonly List<ShipModel> _allShips = new();
|
private static readonly List<ShipModel> _allShips = new();
|
||||||
|
private static readonly List<Port> _ports = new();
|
||||||
|
private static readonly List<Port> _allPorts = new();
|
||||||
|
|
||||||
private readonly static ConcurrentDictionary<int, ShipModel> _shipLookupDict = new();
|
private readonly static ConcurrentDictionary<int, ShipModel> _shipLookupDict = new();
|
||||||
private readonly static ConcurrentDictionary<int, Berth> _berthLookupDict = new();
|
private readonly static ConcurrentDictionary<int, Berth> _berthLookupDict = new();
|
||||||
private readonly static Dictionary<int, Participant> _participantLookupDict = new();
|
private readonly static Dictionary<int, Participant> _participantLookupDict = new();
|
||||||
|
private readonly static ConcurrentDictionary<int, Port> _portLookupDict = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// List of TimeRef points
|
/// List of TimeRef points
|
||||||
/// </summary>
|
/// </summary>
|
||||||
// TODO: To make this portable the list of texts should come from a configuration file
|
// TODO: To make this portable the list of texts should come from a configuration file
|
||||||
private readonly static List<string> _timeRefs = new List<string>
|
private readonly static List<string> _timeRefs = new()
|
||||||
{
|
{
|
||||||
"ETB",
|
"ETB",
|
||||||
"Geeste",
|
"Geeste",
|
||||||
@ -45,12 +48,26 @@ namespace BreCalClient
|
|||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// fast ship lookup
|
||||||
|
/// </summary>
|
||||||
public static ConcurrentDictionary<int, ShipModel> ShipLookupDict { get { return _shipLookupDict; } }
|
public static ConcurrentDictionary<int, ShipModel> ShipLookupDict { get { return _shipLookupDict; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// fast port lookup
|
||||||
|
/// </summary>
|
||||||
public static ConcurrentDictionary<int, Berth> BerthLookupDict { get { return _berthLookupDict; } }
|
public static ConcurrentDictionary<int, Berth> BerthLookupDict { get { return _berthLookupDict; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// fast participant lookup
|
||||||
|
/// </summary>
|
||||||
public static Dictionary<int, Participant> ParticipantLookupDict { get { return _participantLookupDict; } }
|
public static Dictionary<int, Participant> ParticipantLookupDict { get { return _participantLookupDict; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// fast port lookup
|
||||||
|
/// </summary>
|
||||||
|
public static ConcurrentDictionary<int, Port> PortLookupDict { get { return _portLookupDict; } }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Participants that are agents
|
/// Participants that are agents
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -91,6 +108,16 @@ namespace BreCalClient
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static List<Berth> AllBerths { get { return _allBerths; } }
|
public static List<Berth> AllBerths { get { return _allBerths; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// All active ports
|
||||||
|
/// </summary>
|
||||||
|
public static List<Port> Ports { get { return _ports; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// All ports including deleted ports
|
||||||
|
/// </summary>
|
||||||
|
public static List<Port> AllPorts { get { return _allPorts; } }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// All active ships
|
/// All active ships
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -108,7 +135,33 @@ namespace BreCalClient
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region methods
|
#region public static methods
|
||||||
|
|
||||||
|
public static List<Berth> GetBerthsByPort(int port)
|
||||||
|
{
|
||||||
|
List<Berth> berths = new();
|
||||||
|
foreach(Berth berth in _berths)
|
||||||
|
{
|
||||||
|
if(berth.PortId == port)
|
||||||
|
berths.Add(berth);
|
||||||
|
}
|
||||||
|
return berths;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Participant> GetParticipants(int port, Extensions.ParticipantType type)
|
||||||
|
{
|
||||||
|
List<Participant> participants = new();
|
||||||
|
foreach(Participant participant in _participants)
|
||||||
|
{
|
||||||
|
if(participant.IsTypeFlagSet(type) && participant.Ports.Contains(port))
|
||||||
|
participants.Add(participant);
|
||||||
|
}
|
||||||
|
return participants;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Internal initializer methods
|
||||||
|
|
||||||
internal static void InitializeParticipants(List<Participant> participants)
|
internal static void InitializeParticipants(List<Participant> participants)
|
||||||
{
|
{
|
||||||
@ -157,6 +210,17 @@ namespace BreCalClient
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static void InitializePorts(List<Port> ports)
|
||||||
|
{
|
||||||
|
foreach(var port in ports)
|
||||||
|
{
|
||||||
|
_portLookupDict[port.Id] = port;
|
||||||
|
if(!port.Deleted)
|
||||||
|
_ports.Add(port);
|
||||||
|
_allPorts.Add(port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,7 +44,9 @@
|
|||||||
<xctk:DoubleUpDown x:Name="doubleUpDownWidth" Margin="2" Grid.Column="1" Grid.Row="4" FormatString="N2" IsReadOnly="True" IsEnabled="False" ShowButtonSpinner="False"/>
|
<xctk:DoubleUpDown x:Name="doubleUpDownWidth" Margin="2" Grid.Column="1" Grid.Row="4" FormatString="N2" IsReadOnly="True" IsEnabled="False" ShowButtonSpinner="False"/>
|
||||||
<Label Content="{x:Static p:Resources.textCancelled}" Grid.Column="0" Grid.Row="5" HorizontalContentAlignment="Right" />
|
<Label Content="{x:Static p:Resources.textCancelled}" Grid.Column="0" Grid.Row="5" HorizontalContentAlignment="Right" />
|
||||||
<CheckBox x:Name="checkBoxCancelled" Grid.Column="1" Grid.Row="5" Margin="2" VerticalContentAlignment="Center" />
|
<CheckBox x:Name="checkBoxCancelled" Grid.Column="1" Grid.Row="5" Margin="2" VerticalContentAlignment="Center" />
|
||||||
<Button x:Name="buttonEditShips" Grid.Column="1" Grid.Row="6" Margin="2" Content="{x:Static p:Resources.textEditShips}" Click="buttonEditShips_Click" Visibility="Hidden" />
|
<Label Content="{x:Static p:Resources.textHarbour}" Grid.Column="0" Grid.Row="6" HorizontalContentAlignment="Right" />
|
||||||
|
<ComboBox x:Name="comboBoxHarbour" Grid.Column="1" Margin="2" Grid.Row="6" DisplayMemberPath="Name" SelectedValuePath="Id" />
|
||||||
|
<Button x:Name="buttonEditShips" Grid.Column="1" Grid.Row="7" Margin="2" Content="{x:Static p:Resources.textEditShips}" Click="buttonEditShips_Click" Visibility="Hidden" />
|
||||||
|
|
||||||
<Label Content="{x:Static p:Resources.textType}" Grid.Column="2" Grid.Row="0" HorizontalContentAlignment="Right" />
|
<Label Content="{x:Static p:Resources.textType}" Grid.Column="2" Grid.Row="0" HorizontalContentAlignment="Right" />
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ using BreCalClient.misc.Api;
|
|||||||
using BreCalClient.misc.Model;
|
using BreCalClient.misc.Model;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using static BreCalClient.Extensions;
|
using static BreCalClient.Extensions;
|
||||||
@ -41,13 +42,14 @@ namespace BreCalClient
|
|||||||
|
|
||||||
public ShipApi? ShipApi { get; set; }
|
public ShipApi? ShipApi { get; set; }
|
||||||
|
|
||||||
|
public bool IsCreate { get; set; } = false;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Event handler
|
#region Event handler
|
||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
this.comboBoxAgency.ItemsSource = BreCalLists.Participants_Agent;
|
|
||||||
|
|
||||||
this.comboBoxShip.ItemsSource = BreCalLists.Ships;
|
this.comboBoxShip.ItemsSource = BreCalLists.Ships;
|
||||||
Array types = Enum.GetValues(typeof(ShipcallType));
|
Array types = Enum.GetValues(typeof(ShipcallType));
|
||||||
@ -59,10 +61,8 @@ namespace BreCalClient
|
|||||||
else first = false;
|
else first = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.comboBoxArrivalBerth.ItemsSource = BreCalLists.Berths;
|
|
||||||
this.comboBoxDepartureBerth.ItemsSource = BreCalLists.Berths;
|
|
||||||
|
|
||||||
this.comboBoxTimeRef.ItemsSource = BreCalLists.TimeRefs;
|
this.comboBoxTimeRef.ItemsSource = BreCalLists.TimeRefs;
|
||||||
|
this.comboBoxHarbour.ItemsSource = BreCalLists.Ports.Where(x => App.Participant.Ports.Contains(x.Id));
|
||||||
|
|
||||||
this.integerUpDownShiftingCount.Value = this.ShipcallModel.ShiftSequence;
|
this.integerUpDownShiftingCount.Value = this.ShipcallModel.ShiftSequence;
|
||||||
|
|
||||||
@ -188,10 +188,13 @@ namespace BreCalClient
|
|||||||
|
|
||||||
void CheckForCompletion()
|
void CheckForCompletion()
|
||||||
{
|
{
|
||||||
|
if (this.ShipcallModel.Shipcall?.Canceled ?? false) return; // Cancelled shipcall never clicks ok
|
||||||
|
|
||||||
bool isEnabled = true;
|
bool isEnabled = true;
|
||||||
|
|
||||||
isEnabled &= this.comboBoxShip.SelectedItem != null;
|
isEnabled &= this.comboBoxShip.SelectedItem != null;
|
||||||
isEnabled &= this.comboBoxCategories.SelectedItem != null;
|
isEnabled &= this.comboBoxCategories.SelectedItem != null;
|
||||||
|
isEnabled &= this.comboBoxHarbour.SelectedItem != null;
|
||||||
|
|
||||||
if (comboBoxCategories.SelectedItem == null)
|
if (comboBoxCategories.SelectedItem == null)
|
||||||
{
|
{
|
||||||
@ -309,7 +312,7 @@ namespace BreCalClient
|
|||||||
|
|
||||||
// set the time reference value (which point do all times refer to?)
|
// set the time reference value (which point do all times refer to?)
|
||||||
this.ShipcallModel.Shipcall.TimeRefPoint = this.comboBoxTimeRef.SelectedIndex;
|
this.ShipcallModel.Shipcall.TimeRefPoint = this.comboBoxTimeRef.SelectedIndex;
|
||||||
|
this.ShipcallModel.Shipcall.PortId = ((Port) this.comboBoxHarbour.SelectedItem).Id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,7 +325,7 @@ namespace BreCalClient
|
|||||||
this.comboBoxCategories.SelectedItem = new EnumToStringConverter().Convert(this.ShipcallModel.Shipcall.Type, typeof(ShipcallType), new object(), System.Globalization.CultureInfo.CurrentCulture);
|
this.comboBoxCategories.SelectedItem = new EnumToStringConverter().Convert(this.ShipcallModel.Shipcall.Type, typeof(ShipcallType), new object(), System.Globalization.CultureInfo.CurrentCulture);
|
||||||
if (this.ShipcallModel.Shipcall.Eta != DateTime.MinValue)
|
if (this.ShipcallModel.Shipcall.Eta != DateTime.MinValue)
|
||||||
this.datePickerETA.Value = this.ShipcallModel.Shipcall.Eta;
|
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;
|
||||||
if (BreCalLists.Ships.Find(x => x.Ship.Id == this.ShipcallModel.Shipcall.ShipId) != null)
|
if (BreCalLists.Ships.Find(x => x.Ship.Id == this.ShipcallModel.Shipcall.ShipId) != null)
|
||||||
{
|
{
|
||||||
@ -333,6 +336,16 @@ namespace BreCalClient
|
|||||||
}
|
}
|
||||||
this.checkBoxCancelled.IsChecked = this.ShipcallModel.Shipcall.Canceled ?? false;
|
this.checkBoxCancelled.IsChecked = this.ShipcallModel.Shipcall.Canceled ?? false;
|
||||||
|
|
||||||
|
if (BreCalLists.PortLookupDict.ContainsKey(this.ShipcallModel.Shipcall.PortId))
|
||||||
|
this.comboBoxHarbour.SelectedValue = this.ShipcallModel.Shipcall.PortId;
|
||||||
|
List<Berth> availableBerths = BreCalLists.GetBerthsByPort(this.ShipcallModel.Shipcall.PortId);
|
||||||
|
this.comboBoxArrivalBerth.ItemsSource = availableBerths;
|
||||||
|
this.comboBoxDepartureBerth.ItemsSource = availableBerths;
|
||||||
|
|
||||||
|
// Filter agency combobox by port
|
||||||
|
List<Participant> availableAgencies = BreCalLists.GetParticipants(this.ShipcallModel.Shipcall.PortId, ParticipantType.AGENCY);
|
||||||
|
this.comboBoxAgency.ItemsSource = availableAgencies;
|
||||||
|
|
||||||
if (this.ShipcallModel.Shipcall.Type != ShipcallType.Shifting) // incoming, outgoing
|
if (this.ShipcallModel.Shipcall.Type != ShipcallType.Shifting) // incoming, outgoing
|
||||||
{
|
{
|
||||||
this.comboBoxArrivalBerth.SelectedValue = this.ShipcallModel.Shipcall.ArrivalBerthId;
|
this.comboBoxArrivalBerth.SelectedValue = this.ShipcallModel.Shipcall.ArrivalBerthId;
|
||||||
@ -353,6 +366,10 @@ namespace BreCalClient
|
|||||||
this.comboBoxAgency.SelectedValue = this.ShipcallModel.AssignedParticipants[ParticipantType.AGENCY].ParticipantId;
|
this.comboBoxAgency.SelectedValue = this.ShipcallModel.AssignedParticipants[ParticipantType.AGENCY].ParticipantId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.comboBoxHarbour.SelectionChanged += this.comboBoxHarbour_SelectionChanged;
|
||||||
|
|
||||||
|
this.comboBoxHarbour.IsEnabled = this.ShipcallModel.AllowPortChange;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,6 +380,8 @@ namespace BreCalClient
|
|||||||
|
|
||||||
bool editRightGrantedForBSMD = false;
|
bool editRightGrantedForBSMD = false;
|
||||||
|
|
||||||
|
if (this.ShipcallModel.Shipcall?.Canceled ?? false) return; // do not allow edit on canceled shipcall
|
||||||
|
|
||||||
// Special case: Selected Agency allows BSMD to edit their fields
|
// Special case: Selected Agency allows BSMD to edit their fields
|
||||||
if (this.comboBoxAgency.SelectedIndex >= 0)
|
if (this.comboBoxAgency.SelectedIndex >= 0)
|
||||||
{
|
{
|
||||||
@ -386,6 +405,7 @@ namespace BreCalClient
|
|||||||
this.datePickerETD.IsEnabled = isAgency || isBsmd;
|
this.datePickerETD.IsEnabled = isAgency || isBsmd;
|
||||||
|
|
||||||
this.labelBSMDGranted.Visibility = editRightGrantedForBSMD ? Visibility.Visible : Visibility.Hidden;
|
this.labelBSMDGranted.Visibility = editRightGrantedForBSMD ? Visibility.Visible : Visibility.Hidden;
|
||||||
|
this.comboBoxHarbour.IsEnabled = this.IsCreate && this.ShipcallModel.AllowPortChange;
|
||||||
|
|
||||||
this.comboBoxCategories_SelectionChanged(null, null);
|
this.comboBoxCategories_SelectionChanged(null, null);
|
||||||
}
|
}
|
||||||
@ -428,6 +448,24 @@ namespace BreCalClient
|
|||||||
this.comboBoxShip.ItemsSource = BreCalLists.Ships;
|
this.comboBoxShip.ItemsSource = BreCalLists.Ships;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void comboBoxHarbour_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
Port port = (Port)this.comboBoxHarbour.SelectedItem;
|
||||||
|
if (port == null) return;
|
||||||
|
|
||||||
|
// Filter berth selection combobox by port
|
||||||
|
List<Berth> availableBerths = BreCalLists.GetBerthsByPort(port.Id);
|
||||||
|
this.comboBoxArrivalBerth.ItemsSource = null;
|
||||||
|
this.comboBoxArrivalBerth.ItemsSource = availableBerths;
|
||||||
|
this.comboBoxDepartureBerth.ItemsSource = null;
|
||||||
|
this.comboBoxDepartureBerth.ItemsSource = availableBerths;
|
||||||
|
|
||||||
|
// Filter agency combobox by port
|
||||||
|
List<Participant> availableAgencies = BreCalLists.GetParticipants(port.Id, ParticipantType.AGENCY);
|
||||||
|
this.comboBoxAgency.ItemsSource = null;
|
||||||
|
this.comboBoxAgency.ItemsSource = availableAgencies;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,19 +41,27 @@ namespace BreCalClient
|
|||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
this.comboBoxMooring.ItemsSource = BreCalLists.Participants_Mooring;
|
|
||||||
this.comboBoxPilot.ItemsSource = BreCalLists.Participants_Pilot;
|
|
||||||
this.comboBoxTug.ItemsSource = BreCalLists.Participants_Tug;
|
|
||||||
this.comboBoxTerminal.ItemsSource = BreCalLists.Participants_Terminal;
|
|
||||||
|
|
||||||
this.comboBoxArrivalBerth.ItemsSource = BreCalLists.Berths;
|
if ((this.ShipcallModel != null) && (this.ShipcallModel.Shipcall != null))
|
||||||
|
{
|
||||||
|
int portId = this.ShipcallModel.Shipcall.PortId;
|
||||||
|
this.comboBoxArrivalBerth.ItemsSource = BreCalLists.GetBerthsByPort(portId);
|
||||||
|
this.comboBoxMooring.ItemsSource = BreCalLists.GetParticipants(portId, ParticipantType.MOORING);
|
||||||
|
this.comboBoxPilot.ItemsSource = BreCalLists.GetParticipants(portId, ParticipantType.PILOT);
|
||||||
|
this.comboBoxTug.ItemsSource = BreCalLists.GetParticipants(portId, ParticipantType.TUG);
|
||||||
|
this.comboBoxTerminal.ItemsSource = BreCalLists.GetParticipants(portId, ParticipantType.TERMINAL);
|
||||||
|
}
|
||||||
|
|
||||||
this.CopyToControls();
|
this.CopyToControls();
|
||||||
|
|
||||||
this.Title = this.ShipcallModel.Title;
|
this.Title = this.ShipcallModel?.Title;
|
||||||
|
|
||||||
Participant? p = null;
|
Participant? p = null;
|
||||||
if(this.ShipcallModel.AssignedParticipants.ContainsKey(ParticipantType.AGENCY))
|
if (this.ShipcallModel != null)
|
||||||
p = BreCalLists.Participants.Find(x => x.Id == this.ShipcallModel.AssignedParticipants[ParticipantType.AGENCY].ParticipantId);
|
{
|
||||||
|
if (this.ShipcallModel.AssignedParticipants.ContainsKey(ParticipantType.AGENCY))
|
||||||
|
p = BreCalLists.Participants.Find(x => x.Id == this.ShipcallModel.AssignedParticipants[ParticipantType.AGENCY].ParticipantId);
|
||||||
|
}
|
||||||
|
|
||||||
bool allowBSMD = false;
|
bool allowBSMD = false;
|
||||||
if (p != null)
|
if (p != null)
|
||||||
@ -138,7 +146,8 @@ namespace BreCalClient
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((this.datePickerETA_End.Value.HasValue && !this.datePickerETA.Value.HasValue) || (this.datePickerTidalWindowTo.Value.HasValue && !this.datePickerTidalWindowFrom.Value.HasValue))
|
if((this.datePickerETA_End.Value.HasValue && !this.datePickerETA.Value.HasValue) ||
|
||||||
|
(this.datePickerTidalWindowTo.Value.HasValue && !this.datePickerTidalWindowFrom.Value.HasValue))
|
||||||
{
|
{
|
||||||
message = BreCalClient.Resources.Resources.textStartTimeMissing;
|
message = BreCalClient.Resources.Resources.textStartTimeMissing;
|
||||||
return false;
|
return false;
|
||||||
@ -357,7 +366,7 @@ namespace BreCalClient
|
|||||||
|
|
||||||
private void CheckOKButton()
|
private void CheckOKButton()
|
||||||
{
|
{
|
||||||
this.buttonOK.IsEnabled = _editing && RequiredFieldsSet();
|
this.buttonOK.IsEnabled = _editing && RequiredFieldsSet() && !(this.ShipcallModel.Shipcall?.Canceled ?? false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -42,20 +42,27 @@ namespace BreCalClient
|
|||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
this.comboBoxMooring.ItemsSource = BreCalLists.Participants_Mooring;
|
|
||||||
this.comboBoxPilot.ItemsSource = BreCalLists.Participants_Pilot;
|
|
||||||
this.comboBoxTug.ItemsSource = BreCalLists.Participants_Tug;
|
|
||||||
this.comboBoxTerminal.ItemsSource = BreCalLists.Participants_Terminal;
|
|
||||||
|
|
||||||
this.comboBoxDepartureBerth.ItemsSource = BreCalLists.Berths;
|
if ((this.ShipcallModel != null) && (this.ShipcallModel.Shipcall != null))
|
||||||
|
{
|
||||||
|
int portId = this.ShipcallModel.Shipcall.PortId;
|
||||||
|
this.comboBoxDepartureBerth.ItemsSource = BreCalLists.GetBerthsByPort(portId);
|
||||||
|
this.comboBoxMooring.ItemsSource = BreCalLists.GetParticipants(portId, ParticipantType.MOORING);
|
||||||
|
this.comboBoxPilot.ItemsSource = BreCalLists.GetParticipants(portId, ParticipantType.PILOT);
|
||||||
|
this.comboBoxTug.ItemsSource = BreCalLists.GetParticipants(portId, ParticipantType.TUG);
|
||||||
|
this.comboBoxTerminal.ItemsSource = BreCalLists.GetParticipants(portId, ParticipantType.TERMINAL);
|
||||||
|
}
|
||||||
|
|
||||||
this.CopyToControls();
|
this.CopyToControls();
|
||||||
|
|
||||||
this.Title = this.ShipcallModel.Title;
|
this.Title = this.ShipcallModel?.Title;
|
||||||
|
|
||||||
Participant? p = null;
|
Participant? p = null;
|
||||||
if (this.ShipcallModel.AssignedParticipants.ContainsKey(ParticipantType.AGENCY))
|
if (this.ShipcallModel != null)
|
||||||
p = BreCalLists.Participants.Find(x => x.Id == this.ShipcallModel.AssignedParticipants[ParticipantType.AGENCY].ParticipantId);
|
{
|
||||||
|
if (this.ShipcallModel.AssignedParticipants.ContainsKey(ParticipantType.AGENCY))
|
||||||
|
p = BreCalLists.Participants.Find(x => x.Id == this.ShipcallModel.AssignedParticipants[ParticipantType.AGENCY].ParticipantId);
|
||||||
|
}
|
||||||
bool allowBSMD = false;
|
bool allowBSMD = false;
|
||||||
if (p != null)
|
if (p != null)
|
||||||
{
|
{
|
||||||
@ -142,7 +149,8 @@ namespace BreCalClient
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((this.datePickerETD_End.Value.HasValue && !this.datePickerETD.Value.HasValue) || (this.datePickerTidalWindowTo.Value.HasValue && !this.datePickerTidalWindowFrom.Value.HasValue))
|
if((this.datePickerETD_End.Value.HasValue && !this.datePickerETD.Value.HasValue) ||
|
||||||
|
(this.datePickerTidalWindowTo.Value.HasValue && !this.datePickerTidalWindowFrom.Value.HasValue))
|
||||||
{
|
{
|
||||||
message = BreCalClient.Resources.Resources.textStartTimeMissing;
|
message = BreCalClient.Resources.Resources.textStartTimeMissing;
|
||||||
return false;
|
return false;
|
||||||
@ -348,7 +356,7 @@ namespace BreCalClient
|
|||||||
|
|
||||||
private void CheckOKButton()
|
private void CheckOKButton()
|
||||||
{
|
{
|
||||||
this.buttonOK.IsEnabled = _editing && RequiredFieldsSet();
|
this.buttonOK.IsEnabled = _editing && RequiredFieldsSet() && !(this.ShipcallModel.Shipcall?.Canceled ?? false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
using BreCalClient.misc.Model;
|
using BreCalClient.misc.Model;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using System.Windows.Documents;
|
||||||
using static BreCalClient.Extensions;
|
using static BreCalClient.Extensions;
|
||||||
|
|
||||||
namespace BreCalClient
|
namespace BreCalClient
|
||||||
@ -41,20 +43,29 @@ namespace BreCalClient
|
|||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
this.comboBoxMooring.ItemsSource = BreCalLists.Participants_Mooring;
|
|
||||||
this.comboBoxPilot.ItemsSource = BreCalLists.Participants_Pilot;
|
|
||||||
this.comboBoxTug.ItemsSource = BreCalLists.Participants_Tug;
|
|
||||||
this.comboBoxTerminal.ItemsSource = BreCalLists.Participants_Terminal;
|
|
||||||
|
|
||||||
this.comboBoxDepartureBerth.ItemsSource = BreCalLists.Berths;
|
if ((this.ShipcallModel != null) && (this.ShipcallModel.Shipcall != null))
|
||||||
this.comboBoxArrivalBerth.ItemsSource = BreCalLists.Berths;
|
{
|
||||||
|
int portId = this.ShipcallModel.Shipcall.PortId;
|
||||||
|
List<Berth> availableBerths = BreCalLists.GetBerthsByPort(portId);
|
||||||
|
this.comboBoxArrivalBerth.ItemsSource = availableBerths;
|
||||||
|
this.comboBoxDepartureBerth.ItemsSource = availableBerths;
|
||||||
|
this.comboBoxMooring.ItemsSource = BreCalLists.GetParticipants(portId, ParticipantType.MOORING);
|
||||||
|
this.comboBoxPilot.ItemsSource = BreCalLists.GetParticipants(portId, ParticipantType.PILOT);
|
||||||
|
this.comboBoxTug.ItemsSource = BreCalLists.GetParticipants(portId, ParticipantType.TUG);
|
||||||
|
this.comboBoxTerminal.ItemsSource = BreCalLists.GetParticipants(portId, ParticipantType.TERMINAL);
|
||||||
|
}
|
||||||
|
|
||||||
this.CopyToControls();
|
this.CopyToControls();
|
||||||
|
|
||||||
this.Title = this.ShipcallModel.Title;
|
|
||||||
|
|
||||||
Participant? p = null;
|
Participant? p = null;
|
||||||
if (this.ShipcallModel.AssignedParticipants.ContainsKey(ParticipantType.AGENCY))
|
|
||||||
p = BreCalLists.Participants.Find(x => x.Id == this.ShipcallModel.AssignedParticipants[ParticipantType.AGENCY].ParticipantId);
|
if (this.ShipcallModel != null)
|
||||||
|
{
|
||||||
|
this.Title = this.ShipcallModel.Title;
|
||||||
|
if (this.ShipcallModel.AssignedParticipants.ContainsKey(ParticipantType.AGENCY))
|
||||||
|
p = BreCalLists.Participants.Find(x => x.Id == this.ShipcallModel.AssignedParticipants[ParticipantType.AGENCY].ParticipantId);
|
||||||
|
}
|
||||||
|
|
||||||
bool allowBSMD = false;
|
bool allowBSMD = false;
|
||||||
if (p != null)
|
if (p != null)
|
||||||
@ -383,7 +394,7 @@ namespace BreCalClient
|
|||||||
|
|
||||||
private void CheckOKButton()
|
private void CheckOKButton()
|
||||||
{
|
{
|
||||||
this.buttonOK.IsEnabled = _editing && RequiredFieldsSet();
|
this.buttonOK.IsEnabled = _editing && RequiredFieldsSet() && !(this.ShipcallModel.Shipcall?.Canceled ?? false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -173,13 +173,13 @@ namespace BreCalClient
|
|||||||
{
|
{
|
||||||
this.textBoxRemarks.Text = this.Times.Remarks;
|
this.textBoxRemarks.Text = this.Times.Remarks;
|
||||||
this.datePickerETABerth.Value = this.Times.EtaBerth;
|
this.datePickerETABerth.Value = this.Times.EtaBerth;
|
||||||
if(this.datePickerETABerth.IsEnabled && (this.Times.EtaBerth == null) && (this.AgencyTimes?.EtaBerth != null) && (ShipcallModel.Shipcall?.Type == ShipcallType.Arrival) && (this.AgencyTimes?.EtaBerth > DateTime.Now))
|
if(this.datePickerETABerth.IsEnabled && (this.Times.EtaBerth == null) && (this.AgencyTimes?.EtaBerth != null) && (ShipcallModel.Shipcall?.Type == ShipcallType.Arrival) && (this.AgencyTimes?.EtaBerth > DateTime.Now.AddDays(-1)))
|
||||||
{
|
{
|
||||||
this.datePickerETABerth.Value = this.AgencyTimes.EtaBerth;
|
this.datePickerETABerth.Value = this.AgencyTimes.EtaBerth;
|
||||||
if (this.datePickerETABerth.Template.FindName("PART_TextBox", this.datePickerETABerth) is WatermarkTextBox tb) { tb.Focus(); tb.SelectAll(); }
|
if (this.datePickerETABerth.Template.FindName("PART_TextBox", this.datePickerETABerth) is WatermarkTextBox tb) { tb.Focus(); tb.SelectAll(); }
|
||||||
}
|
}
|
||||||
this.datePickerETDBerth.Value = this.Times.EtdBerth;
|
this.datePickerETDBerth.Value = this.Times.EtdBerth;
|
||||||
if(this.datePickerETDBerth.IsEnabled && (this.Times.EtdBerth == null) && (this.AgencyTimes?.EtdBerth != null) && ((ShipcallModel.Shipcall?.Type == ShipcallType.Departure) || (ShipcallModel.Shipcall?.Type == ShipcallType.Shifting)) && (this.AgencyTimes?.EtdBerth > DateTime.Now))
|
if(this.datePickerETDBerth.IsEnabled && (this.Times.EtdBerth == null) && (this.AgencyTimes?.EtdBerth != null) && ((ShipcallModel.Shipcall?.Type == ShipcallType.Departure) || (ShipcallModel.Shipcall?.Type == ShipcallType.Shifting)) && (this.AgencyTimes?.EtdBerth > DateTime.Now.AddDays(-1)))
|
||||||
{
|
{
|
||||||
this.datePickerETDBerth.Value = this.AgencyTimes.EtdBerth;
|
this.datePickerETDBerth.Value = this.AgencyTimes.EtdBerth;
|
||||||
if (this.datePickerETDBerth.Template.FindName("PART_TextBox", this.datePickerETDBerth) is WatermarkTextBox tb) tb.SelectAll();
|
if (this.datePickerETDBerth.Template.FindName("PART_TextBox", this.datePickerETDBerth) is WatermarkTextBox tb) tb.SelectAll();
|
||||||
@ -190,14 +190,14 @@ namespace BreCalClient
|
|||||||
this.datePickerATA.Value = this.Times.Ata;
|
this.datePickerATA.Value = this.Times.Ata;
|
||||||
this.datePickerATD.Value = this.Times.Atd;
|
this.datePickerATD.Value = this.Times.Atd;
|
||||||
this.datePickerETABerth_End.Value = this.Times.EtaIntervalEnd;
|
this.datePickerETABerth_End.Value = this.Times.EtaIntervalEnd;
|
||||||
if (this.datePickerETABerth_End.IsEnabled && (this.Times.EtaIntervalEnd == null) && (this.Times.EtaBerth == null) && (this.AgencyTimes?.EtaIntervalEnd != null) && (ShipcallModel.Shipcall?.Type == ShipcallType.Arrival))
|
if (this.datePickerETABerth_End.IsEnabled && (this.Times.EtaIntervalEnd == null) && (this.Times.EtaBerth == null) && (this.AgencyTimes?.EtaIntervalEnd != null) && (ShipcallModel.Shipcall?.Type == ShipcallType.Arrival) && (this.AgencyTimes?.EtaBerth > DateTime.Now.AddDays(-1)))
|
||||||
{
|
{
|
||||||
this.datePickerETABerth_End.Value = this.AgencyTimes.EtaIntervalEnd;
|
this.datePickerETABerth_End.Value = this.AgencyTimes.EtaIntervalEnd;
|
||||||
//if (this.datePickerETABerth_End.Template.FindName("PART_TextBox", this.datePickerETABerth_End) is WatermarkTextBox tb) { tb.Focus(); tb.SelectAll(); }
|
//if (this.datePickerETABerth_End.Template.FindName("PART_TextBox", this.datePickerETABerth_End) is WatermarkTextBox tb) { tb.Focus(); tb.SelectAll(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
this.datePickerETDBerth_End.Value = this.Times.EtdIntervalEnd;
|
this.datePickerETDBerth_End.Value = this.Times.EtdIntervalEnd;
|
||||||
if (this.datePickerETDBerth_End.IsEnabled && (this.Times.EtdIntervalEnd == null) && (this.Times.EtdBerth == null) && (this.AgencyTimes?.EtdIntervalEnd != null) && ((ShipcallModel.Shipcall?.Type == ShipcallType.Departure) || (ShipcallModel.Shipcall?.Type == ShipcallType.Shifting)))
|
if (this.datePickerETDBerth_End.IsEnabled && (this.Times.EtdIntervalEnd == null) && (this.Times.EtdBerth == null) && (this.AgencyTimes?.EtdIntervalEnd != null) && ((ShipcallModel.Shipcall?.Type == ShipcallType.Departure) || (ShipcallModel.Shipcall?.Type == ShipcallType.Shifting)) && (this.AgencyTimes?.EtdBerth > DateTime.Now.AddDays(-1)))
|
||||||
{
|
{
|
||||||
this.datePickerETDBerth_End.Value = this.AgencyTimes.EtdIntervalEnd;
|
this.datePickerETDBerth_End.Value = this.AgencyTimes.EtdIntervalEnd;
|
||||||
//if (this.datePickerETDBerth_End.Template.FindName("PART_TextBox", this.datePickerETDBerth_End) is WatermarkTextBox tb) { tb.Focus(); tb.SelectAll(); }
|
//if (this.datePickerETDBerth_End.Template.FindName("PART_TextBox", this.datePickerETDBerth_End) is WatermarkTextBox tb) { tb.Focus(); tb.SelectAll(); }
|
||||||
@ -259,7 +259,7 @@ namespace BreCalClient
|
|||||||
|
|
||||||
// setting en/dis-abled
|
// setting en/dis-abled
|
||||||
|
|
||||||
if (this.Times.ParticipantId != App.Participant.Id)
|
if ((this.Times.ParticipantId != App.Participant.Id) || (this.ShipcallModel.Shipcall?.Canceled ?? false))
|
||||||
{
|
{
|
||||||
this.buttonFixedOrder.IsEnabled = false;
|
this.buttonFixedOrder.IsEnabled = false;
|
||||||
this.buttonOK.IsEnabled = false;
|
this.buttonOK.IsEnabled = false;
|
||||||
|
|||||||
@ -30,7 +30,10 @@ namespace BreCalClient
|
|||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
this.comboBoxBerth.ItemsSource = BreCalLists.Berths;
|
if ((this.ShipcallModel != null) && (this.ShipcallModel.Shipcall != null))
|
||||||
|
this.comboBoxBerth.ItemsSource = BreCalLists.GetBerthsByPort(this.ShipcallModel.Shipcall.PortId);
|
||||||
|
else
|
||||||
|
this.comboBoxBerth.ItemsSource = BreCalLists.Berths;
|
||||||
this.CopyToControls();
|
this.CopyToControls();
|
||||||
this.EnableControls();
|
this.EnableControls();
|
||||||
}
|
}
|
||||||
@ -214,7 +217,7 @@ namespace BreCalClient
|
|||||||
|
|
||||||
private void EnableControls()
|
private void EnableControls()
|
||||||
{
|
{
|
||||||
if (this.Times.ParticipantId != App.Participant.Id)
|
if ((this.Times.ParticipantId != App.Participant.Id) || (this.ShipcallModel.Shipcall?.Canceled ?? false))
|
||||||
{
|
{
|
||||||
this.buttonOK.IsEnabled = false;
|
this.buttonOK.IsEnabled = false;
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -73,9 +73,19 @@
|
|||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Button Margin="2" Grid.Column="0" Content="{x:Static p:Resources.textNewDots}" x:Name="buttonNew" Visibility="Hidden" Click="buttonNew_Click" Background="Transparent"/>
|
<Button Margin="2" Grid.Column="0" Content="{x:Static p:Resources.textNewDots}" x:Name="buttonNew" Visibility="Hidden" Click="buttonNew_Click" Background="Transparent"/>
|
||||||
<Label Content="{x:Static p:Resources.textSortOrder}" Grid.Column="1" HorizontalContentAlignment="Right"/>
|
<Label Content="{x:Static p:Resources.textSortOrder}" Grid.Column="1" HorizontalContentAlignment="Right"/>
|
||||||
<ComboBox x:Name="comboBoxSortOrder" Margin="2" Grid.Column="2" SelectionChanged="comboBoxSortOrder_SelectionChanged" />
|
<Grid Grid.Column="2" Grid.Row="1">
|
||||||
<CheckBox x:Name="checkboxShowCancelledCalls" Grid.Column="3" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="2" Checked="checkboxShowCancelledCalls_Checked" Unchecked="checkboxShowCancelledCalls_Checked" />
|
<Grid.ColumnDefinitions>
|
||||||
<Label Content="{x:Static p:Resources.textShowCancelledShipcalls}" Grid.Column="4" />
|
<ColumnDefinition Width=".5*" />
|
||||||
|
<ColumnDefinition Width="30" />
|
||||||
|
<ColumnDefinition Width=".5*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<ComboBox x:Name="comboBoxSortOrder" Margin="2" Grid.Column="0" SelectionChanged="comboBoxSortOrder_SelectionChanged" />
|
||||||
|
<CheckBox x:Name="checkboxShowCancelledCalls" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="2" Checked="checkboxShowCancelledCalls_Checked" Unchecked="checkboxShowCancelledCalls_Checked" />
|
||||||
|
<Label Content="{x:Static p:Resources.textShowCancelledShipcalls}" Grid.Column="2" />
|
||||||
|
</Grid>
|
||||||
|
<Label Content="{x:Static p:Resources.textHarbour}" Grid.Column="3" HorizontalAlignment="Right" />
|
||||||
|
<xctk:CheckComboBox x:Name="comboBoxPorts" Margin="2" Grid.Column="4" ItemSelectionChanged="comboBoxPorts_ItemSelectionChanged" DisplayMemberPath="Name" />
|
||||||
|
|
||||||
<Button Margin="2" Grid.Column="6" Content="{x:Static p:Resources.textClearFilters}" x:Name="buttonClearFilter" Click="buttonClearFilter_Click" Background="Transparent" />
|
<Button Margin="2" Grid.Column="6" Content="{x:Static p:Resources.textClearFilters}" x:Name="buttonClearFilter" Click="buttonClearFilter_Click" Background="Transparent" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid Grid.Row="2">
|
<Grid Grid.Row="2">
|
||||||
|
|||||||
@ -25,6 +25,7 @@ using System.Net;
|
|||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
|
||||||
namespace BreCalClient
|
namespace BreCalClient
|
||||||
@ -168,14 +169,24 @@ namespace BreCalClient
|
|||||||
if (_loginResult.Id > 0)
|
if (_loginResult.Id > 0)
|
||||||
{
|
{
|
||||||
Mouse.OverrideCursor = Cursors.Wait;
|
Mouse.OverrideCursor = Cursors.Wait;
|
||||||
this.busyIndicator.IsBusy = false;
|
|
||||||
this._userApi.Configuration.ApiKey["Authorization"] = _loginResult.Token;
|
this._userApi.Configuration.ApiKey["Authorization"] = _loginResult.Token;
|
||||||
this._shipcallApi.Configuration.ApiKey["Authorization"] = _loginResult.Token;
|
this._shipcallApi.Configuration.ApiKey["Authorization"] = _loginResult.Token;
|
||||||
this._timesApi.Configuration.ApiKey["Authorization"] = _loginResult.Token;
|
this._timesApi.Configuration.ApiKey["Authorization"] = _loginResult.Token;
|
||||||
this._staticApi.Configuration.ApiKey["Authorization"] = _loginResult.Token;
|
this._staticApi.Configuration.ApiKey["Authorization"] = _loginResult.Token;
|
||||||
this._shipApi.Configuration.ApiKey["Authorization"] = _loginResult.Token;
|
this._shipApi.Configuration.ApiKey["Authorization"] = _loginResult.Token;
|
||||||
this.LoadStaticLists();
|
bool loadingSuccessful = await this.LoadStaticLists();
|
||||||
this.labelUsername.Text = $"{_loginResult.FirstName} {_loginResult.LastName}";
|
if (loadingSuccessful)
|
||||||
|
{
|
||||||
|
this.labelUsername.Text = $"{_loginResult.FirstName} {_loginResult.LastName}";
|
||||||
|
this.busyIndicator.IsBusy = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Mouse.OverrideCursor = null;
|
||||||
|
textUsername.Text = "";
|
||||||
|
textPassword.Password = "";
|
||||||
|
textUsername.Focus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
labelGeneralStatus.Text = $"Connection {ConnectionStatus.SUCCESSFUL}";
|
labelGeneralStatus.Text = $"Connection {ConnectionStatus.SUCCESSFUL}";
|
||||||
@ -184,10 +195,10 @@ namespace BreCalClient
|
|||||||
{
|
{
|
||||||
if ((ex.ErrorContent != null && ((string)ex.ErrorContent).StartsWith("{"))) {
|
if ((ex.ErrorContent != null && ((string)ex.ErrorContent).StartsWith("{"))) {
|
||||||
Error? anError = JsonConvert.DeserializeObject<Error>((string)ex.ErrorContent);
|
Error? anError = JsonConvert.DeserializeObject<Error>((string)ex.ErrorContent);
|
||||||
if ((anError != null) && anError.Message.Equals("invalid credentials"))
|
if ((anError != null) && anError.ErrorField.Equals("invalid credentials"))
|
||||||
this.labelLoginResult.Content = BreCalClient.Resources.Resources.textWrongCredentials;
|
this.labelLoginResult.Content = BreCalClient.Resources.Resources.textWrongCredentials;
|
||||||
else
|
else
|
||||||
this.labelLoginResult.Content = anError?.Message ?? ex.Message;
|
this.labelLoginResult.Content = anError?.ErrorField ?? ex.Message;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.labelLoginResult.Content = ex.Message;
|
this.labelLoginResult.Content = ex.Message;
|
||||||
@ -246,7 +257,8 @@ namespace BreCalClient
|
|||||||
EditShipcallControl esc = new()
|
EditShipcallControl esc = new()
|
||||||
{
|
{
|
||||||
ShipEditingEnabled = App.Participant.IsTypeFlagSet(Extensions.ParticipantType.BSMD),
|
ShipEditingEnabled = App.Participant.IsTypeFlagSet(Extensions.ParticipantType.BSMD),
|
||||||
ShipApi = _shipApi
|
ShipApi = _shipApi,
|
||||||
|
IsCreate = true
|
||||||
};
|
};
|
||||||
if (model != null)
|
if (model != null)
|
||||||
esc.ShipcallModel = model;
|
esc.ShipcallModel = model;
|
||||||
@ -287,7 +299,9 @@ namespace BreCalClient
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
scmOut.Shipcall.ShipId = esc.ShipcallModel.Shipcall.ShipId;
|
scmOut.Shipcall.ShipId = esc.ShipcallModel.Shipcall.ShipId;
|
||||||
|
scmOut.Shipcall.PortId = esc.ShipcallModel.Shipcall.PortId;
|
||||||
scmOut.Ship = esc.ShipcallModel.Ship;
|
scmOut.Ship = esc.ShipcallModel.Ship;
|
||||||
|
scmOut.AllowPortChange = false;
|
||||||
DateTime eta = esc.ShipcallModel.Shipcall?.Eta ?? DateTime.Now;
|
DateTime eta = esc.ShipcallModel.Shipcall?.Eta ?? DateTime.Now;
|
||||||
scmOut.Shipcall.Etd = eta.AddDays(2);
|
scmOut.Shipcall.Etd = eta.AddDays(2);
|
||||||
scmOut.Shipcall.DepartureBerthId = esc.ShipcallModel.Shipcall?.ArrivalBerthId;
|
scmOut.Shipcall.DepartureBerthId = esc.ShipcallModel.Shipcall?.ArrivalBerthId;
|
||||||
@ -349,6 +363,7 @@ namespace BreCalClient
|
|||||||
{
|
{
|
||||||
this.searchFilterControl.ClearFilters();
|
this.searchFilterControl.ClearFilters();
|
||||||
this.checkboxShowCancelledCalls.IsChecked = false;
|
this.checkboxShowCancelledCalls.IsChecked = false;
|
||||||
|
this.comboBoxPorts.UnSelectAll();
|
||||||
this.FilterShipcalls();
|
this.FilterShipcalls();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,6 +381,24 @@ namespace BreCalClient
|
|||||||
this.SearchFilterControl_SearchFilterChanged();
|
this.SearchFilterControl_SearchFilterChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void comboBoxPorts_ItemSelectionChanged(object sender, Xceed.Wpf.Toolkit.Primitives.ItemSelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
this.searchFilterControl.SearchFilter.Ports.Clear();
|
||||||
|
|
||||||
|
List<Berth> berths = new List<Berth>();
|
||||||
|
foreach (Port port in comboBoxPorts.SelectedItems)
|
||||||
|
{
|
||||||
|
this.searchFilterControl.SearchFilter.Ports.Add(port.Id);
|
||||||
|
berths.AddRange(BreCalLists.GetBerthsByPort(port.Id));
|
||||||
|
}
|
||||||
|
// create list of berths from selected port(s) or return all berths
|
||||||
|
if (berths.Count == 0)
|
||||||
|
berths = BreCalLists.AllBerths;
|
||||||
|
this.searchFilterControl.SetBerths(berths);
|
||||||
|
|
||||||
|
this.SearchFilterControl_SearchFilterChanged();
|
||||||
|
}
|
||||||
|
|
||||||
private async void comboBoxSortOrder_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
|
private async void comboBoxSortOrder_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
_sortOrder = (Extensions.SortOrder) this.comboBoxSortOrder.SelectedIndex;
|
_sortOrder = (Extensions.SortOrder) this.comboBoxSortOrder.SelectedIndex;
|
||||||
@ -405,14 +438,22 @@ namespace BreCalClient
|
|||||||
|
|
||||||
#region network operations
|
#region network operations
|
||||||
|
|
||||||
private async void LoadStaticLists()
|
private async Task<bool> LoadStaticLists()
|
||||||
{
|
{
|
||||||
if (_loginResult == null) return;
|
if (_loginResult == null) return false;
|
||||||
|
|
||||||
|
BreCalLists.InitializePorts(await _staticApi.GetPortsAsync());
|
||||||
BreCalLists.InitializeBerths(await _staticApi.BerthsGetAsync());
|
BreCalLists.InitializeBerths(await _staticApi.BerthsGetAsync());
|
||||||
BreCalLists.InitializeShips(await _shipApi.ShipsGetAsync());
|
BreCalLists.InitializeShips(await _shipApi.ShipsGetAsync());
|
||||||
BreCalLists.InitializeParticipants(await _staticApi.ParticipantsGetAsync());
|
BreCalLists.InitializeParticipants(await _staticApi.ParticipantsGetAsync());
|
||||||
|
|
||||||
|
if(BreCalLists.Participants.Count == 0)
|
||||||
|
{
|
||||||
|
MessageBox.Show(BreCalClient.Resources.Resources.textNoPortAssigned, BreCalClient.Resources.Resources.textError, MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
|
Mouse.OverrideCursor = Cursors.Wait;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
this.searchFilterControl.SetBerths(BreCalLists.Berths);
|
this.searchFilterControl.SetBerths(BreCalLists.Berths);
|
||||||
|
|
||||||
foreach (Participant participant in BreCalLists.Participants)
|
foreach (Participant participant in BreCalLists.Participants)
|
||||||
@ -448,11 +489,20 @@ namespace BreCalClient
|
|||||||
SearchFilterModel.filterMap[_loginResult.Id] = currentFilter;
|
SearchFilterModel.filterMap[_loginResult.Id] = currentFilter;
|
||||||
}
|
}
|
||||||
this.searchFilterControl.SetFilterFromModel(currentFilter);
|
this.searchFilterControl.SetFilterFromModel(currentFilter);
|
||||||
|
|
||||||
|
if ((currentFilter.Ports != null) && (this.comboBoxPorts.ItemsSource != null))
|
||||||
|
{
|
||||||
|
foreach (Port p in this.comboBoxPorts.ItemsSource)
|
||||||
|
{
|
||||||
|
if (currentFilter.Ports.Contains(p.Id)) this.comboBoxPorts.SelectedItems.Add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = Task.Run(() => RefreshShipcalls());
|
_ = Task.Run(() => RefreshShipcalls());
|
||||||
_ = Task.Run(() => RefreshShips());
|
_ = Task.Run(() => RefreshShips());
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -604,7 +654,7 @@ namespace BreCalClient
|
|||||||
{
|
{
|
||||||
ShipcallControl sc = new()
|
ShipcallControl sc = new()
|
||||||
{
|
{
|
||||||
Height = 135,
|
Height = 145,
|
||||||
ShipcallControlModel = scm
|
ShipcallControlModel = scm
|
||||||
};
|
};
|
||||||
sc.EditTimesRequested += Sc_EditTimesRequested;
|
sc.EditTimesRequested += Sc_EditTimesRequested;
|
||||||
@ -700,6 +750,11 @@ namespace BreCalClient
|
|||||||
_ = this._visibleControlModels.RemoveAll(x => { if (x.Shipcall == null) return false; else return !sfm.Categories.Contains(x.Shipcall.Type); });
|
_ = this._visibleControlModels.RemoveAll(x => { if (x.Shipcall == null) return false; else return !sfm.Categories.Contains(x.Shipcall.Type); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(sfm.Ports.Count > 0 )
|
||||||
|
{
|
||||||
|
_ = this._visibleControlModels.RemoveAll(x => { if(x.Shipcall == null) return false; else return !sfm.Ports.Contains(x.Shipcall.PortId); });
|
||||||
|
}
|
||||||
|
|
||||||
if(!string.IsNullOrEmpty(sfm.SearchString))
|
if(!string.IsNullOrEmpty(sfm.SearchString))
|
||||||
{
|
{
|
||||||
_ = this._visibleControlModels.RemoveAll(x => !(x.ContainsRemarkText(sfm.SearchString) || (x.Ship?.Name.Contains(sfm.SearchString, StringComparison.InvariantCultureIgnoreCase) ?? false)));
|
_ = this._visibleControlModels.RemoveAll(x => !(x.ContainsRemarkText(sfm.SearchString) || (x.Ship?.Name.Contains(sfm.SearchString, StringComparison.InvariantCultureIgnoreCase) ?? false)));
|
||||||
@ -1109,6 +1164,8 @@ namespace BreCalClient
|
|||||||
{
|
{
|
||||||
if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.BSMD))
|
if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.BSMD))
|
||||||
this.buttonNew.Visibility = Visibility.Visible;
|
this.buttonNew.Visibility = Visibility.Visible;
|
||||||
|
|
||||||
|
this.comboBoxPorts.ItemsSource = BreCalLists.AllPorts.Where(x => App.Participant.Ports.Contains(x.Id));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
|
private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
|
||||||
|
|||||||
@ -4,8 +4,8 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
|||||||
-->
|
-->
|
||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ApplicationRevision>1</ApplicationRevision>
|
<ApplicationRevision>2</ApplicationRevision>
|
||||||
<ApplicationVersion>1.4.1.0</ApplicationVersion>
|
<ApplicationVersion>1.6.0.4</ApplicationVersion>
|
||||||
<BootstrapperEnabled>True</BootstrapperEnabled>
|
<BootstrapperEnabled>True</BootstrapperEnabled>
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
<CreateDesktopShortcut>True</CreateDesktopShortcut>
|
<CreateDesktopShortcut>True</CreateDesktopShortcut>
|
||||||
@ -36,8 +36,10 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
|||||||
<TargetFramework>net6.0-windows</TargetFramework>
|
<TargetFramework>net6.0-windows</TargetFramework>
|
||||||
<UpdateEnabled>True</UpdateEnabled>
|
<UpdateEnabled>True</UpdateEnabled>
|
||||||
<UpdateMode>Foreground</UpdateMode>
|
<UpdateMode>Foreground</UpdateMode>
|
||||||
<UpdateRequired>False</UpdateRequired>
|
<UpdateRequired>True</UpdateRequired>
|
||||||
<WebPageFileName>Publish.html</WebPageFileName>
|
<WebPageFileName>Publish.html</WebPageFileName>
|
||||||
|
<MinimumRequiredVersion>1.6.0.4</MinimumRequiredVersion>
|
||||||
|
<SkipPublishVerification>false</SkipPublishVerification>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PublishFile Include="containership.ico">
|
<PublishFile Include="containership.ico">
|
||||||
|
|||||||
@ -4,8 +4,8 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
|||||||
-->
|
-->
|
||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ApplicationRevision>12</ApplicationRevision>
|
<ApplicationRevision>8</ApplicationRevision>
|
||||||
<ApplicationVersion>1.5.0.12</ApplicationVersion>
|
<ApplicationVersion>1.6.0.8</ApplicationVersion>
|
||||||
<BootstrapperEnabled>False</BootstrapperEnabled>
|
<BootstrapperEnabled>False</BootstrapperEnabled>
|
||||||
<Configuration>Release</Configuration>
|
<Configuration>Release</Configuration>
|
||||||
<CreateWebPageOnPublish>True</CreateWebPageOnPublish>
|
<CreateWebPageOnPublish>True</CreateWebPageOnPublish>
|
||||||
@ -30,7 +30,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
|||||||
<TargetFramework>net6.0-windows</TargetFramework>
|
<TargetFramework>net6.0-windows</TargetFramework>
|
||||||
<UpdateEnabled>True</UpdateEnabled>
|
<UpdateEnabled>True</UpdateEnabled>
|
||||||
<UpdateMode>Foreground</UpdateMode>
|
<UpdateMode>Foreground</UpdateMode>
|
||||||
<UpdateRequired>False</UpdateRequired>
|
<UpdateRequired>True</UpdateRequired>
|
||||||
<WebPageFileName>Publish.html</WebPageFileName>
|
<WebPageFileName>Publish.html</WebPageFileName>
|
||||||
<CreateDesktopShortcut>True</CreateDesktopShortcut>
|
<CreateDesktopShortcut>True</CreateDesktopShortcut>
|
||||||
<ErrorReportUrl>https://www.bsmd-emswe.eu/</ErrorReportUrl>
|
<ErrorReportUrl>https://www.bsmd-emswe.eu/</ErrorReportUrl>
|
||||||
@ -39,6 +39,8 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
|||||||
<SuiteName>Bremen calling client</SuiteName>
|
<SuiteName>Bremen calling client</SuiteName>
|
||||||
<SupportUrl>https://www.bsmd-emswe.eu/</SupportUrl>
|
<SupportUrl>https://www.bsmd-emswe.eu/</SupportUrl>
|
||||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
|
<SkipPublishVerification>false</SkipPublishVerification>
|
||||||
|
<MinimumRequiredVersion>1.6.0.8</MinimumRequiredVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PublishFile Include="containership.ico">
|
<PublishFile Include="containership.ico">
|
||||||
|
|||||||
@ -4,8 +4,8 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
|||||||
-->
|
-->
|
||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ApplicationRevision>8</ApplicationRevision>
|
<ApplicationRevision>6</ApplicationRevision>
|
||||||
<ApplicationVersion>1.5.0.8</ApplicationVersion>
|
<ApplicationVersion>1.6.0.8</ApplicationVersion>
|
||||||
<BootstrapperEnabled>True</BootstrapperEnabled>
|
<BootstrapperEnabled>True</BootstrapperEnabled>
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
<CreateDesktopShortcut>True</CreateDesktopShortcut>
|
<CreateDesktopShortcut>True</CreateDesktopShortcut>
|
||||||
@ -30,7 +30,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
|||||||
<TargetFramework>net6.0-windows</TargetFramework>
|
<TargetFramework>net6.0-windows</TargetFramework>
|
||||||
<UpdateEnabled>True</UpdateEnabled>
|
<UpdateEnabled>True</UpdateEnabled>
|
||||||
<UpdateMode>Foreground</UpdateMode>
|
<UpdateMode>Foreground</UpdateMode>
|
||||||
<UpdateRequired>False</UpdateRequired>
|
<UpdateRequired>True</UpdateRequired>
|
||||||
<WebPageFileName>Publish.html</WebPageFileName>
|
<WebPageFileName>Publish.html</WebPageFileName>
|
||||||
<CreateDesktopShortcut>True</CreateDesktopShortcut>
|
<CreateDesktopShortcut>True</CreateDesktopShortcut>
|
||||||
<ErrorReportUrl>https://www.bsmd-emswe.eu/</ErrorReportUrl>
|
<ErrorReportUrl>https://www.bsmd-emswe.eu/</ErrorReportUrl>
|
||||||
@ -41,6 +41,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
|||||||
<PublishDir>bin\Debug\net6.0-windows\win-x64\app.publish\</PublishDir>
|
<PublishDir>bin\Debug\net6.0-windows\win-x64\app.publish\</PublishDir>
|
||||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
<SkipPublishVerification>false</SkipPublishVerification>
|
<SkipPublishVerification>false</SkipPublishVerification>
|
||||||
|
<MinimumRequiredVersion>1.6.0.8</MinimumRequiredVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PublishFile Include="containership.ico">
|
<PublishFile Include="containership.ico">
|
||||||
|
|||||||
18
src/BreCalClient/Resources/Resources.Designer.cs
generated
18
src/BreCalClient/Resources/Resources.Designer.cs
generated
@ -749,6 +749,15 @@ namespace BreCalClient.Resources {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Harbour.
|
||||||
|
/// </summary>
|
||||||
|
public static string textHarbour {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("textHarbour", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Incoming.
|
/// Looks up a localized string similar to Incoming.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -866,6 +875,15 @@ namespace BreCalClient.Resources {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to No port assigned to this participant.
|
||||||
|
/// </summary>
|
||||||
|
public static string textNoPortAssigned {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("textNoPortAssigned", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Not rotated.
|
/// Looks up a localized string similar to Not rotated.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -286,6 +286,9 @@
|
|||||||
<data name="textFrom" xml:space="preserve">
|
<data name="textFrom" xml:space="preserve">
|
||||||
<value>von</value>
|
<value>von</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="textHarbour" xml:space="preserve">
|
||||||
|
<value>Hafen</value>
|
||||||
|
</data>
|
||||||
<data name="textIncoming" xml:space="preserve">
|
<data name="textIncoming" xml:space="preserve">
|
||||||
<value>Einkommend</value>
|
<value>Einkommend</value>
|
||||||
</data>
|
</data>
|
||||||
@ -550,4 +553,7 @@
|
|||||||
<data name="textStartTimeMissing" xml:space="preserve">
|
<data name="textStartTimeMissing" xml:space="preserve">
|
||||||
<value>Wenn eine Ende-Zeit angegeben wird, muss auch eine Start-Zeit angegeben werden</value>
|
<value>Wenn eine Ende-Zeit angegeben wird, muss auch eine Start-Zeit angegeben werden</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="textNoPortAssigned" xml:space="preserve">
|
||||||
|
<value>Es ist keine Hafenzuordnung vorhanden</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@ -328,6 +328,9 @@
|
|||||||
<data name="textFrom" xml:space="preserve">
|
<data name="textFrom" xml:space="preserve">
|
||||||
<value>from</value>
|
<value>from</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="textHarbour" xml:space="preserve">
|
||||||
|
<value>Harbour</value>
|
||||||
|
</data>
|
||||||
<data name="textIncoming" xml:space="preserve">
|
<data name="textIncoming" xml:space="preserve">
|
||||||
<value>Incoming</value>
|
<value>Incoming</value>
|
||||||
</data>
|
</data>
|
||||||
@ -598,4 +601,7 @@
|
|||||||
<data name="textStartTimeMissing" xml:space="preserve">
|
<data name="textStartTimeMissing" xml:space="preserve">
|
||||||
<value>If an end time is set, a start time is also required</value>
|
<value>If an end time is set, a start time is also required</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="textNoPortAssigned" xml:space="preserve">
|
||||||
|
<value>No port assigned to this participant</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@ -25,6 +25,8 @@ namespace BreCalClient
|
|||||||
|
|
||||||
public List<int> Berths { get; set; } = new();
|
public List<int> Berths { get; set; } = new();
|
||||||
|
|
||||||
|
public List<int> Ports { get; set; } = new();
|
||||||
|
|
||||||
public string? SearchString { get; set; }
|
public string? SearchString { get; set; }
|
||||||
|
|
||||||
public double? ShipLengthFrom { get; set; }
|
public double? ShipLengthFrom { get; set; }
|
||||||
|
|||||||
@ -20,12 +20,12 @@
|
|||||||
<ColumnDefinition Width=".15*" />
|
<ColumnDefinition Width=".15*" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="32" />
|
<RowDefinition Height="42" />
|
||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Grid Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" >
|
<Grid Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" >
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="32"/>
|
<RowDefinition Height="42"/>
|
||||||
<RowDefinition Height=".125*"/>
|
<RowDefinition Height=".125*"/>
|
||||||
<RowDefinition Height=".125*"/>
|
<RowDefinition Height=".125*"/>
|
||||||
<RowDefinition Height=".125*"/>
|
<RowDefinition Height=".125*"/>
|
||||||
@ -76,39 +76,76 @@
|
|||||||
<TextBlock x:Name="textBlockLengthWidth" Padding="0"/>
|
<TextBlock x:Name="textBlockLengthWidth" Padding="0"/>
|
||||||
</Viewbox>
|
</Viewbox>
|
||||||
<Viewbox Grid.Row="4" Grid.Column="0" HorizontalAlignment="Left">
|
<Viewbox Grid.Row="4" Grid.Column="0" HorizontalAlignment="Left">
|
||||||
<TextBlock Text="{x:Static p:Resources.textDraft}" Padding="0" />
|
|
||||||
</Viewbox>
|
|
||||||
<Viewbox Grid.Row="4" Grid.Column="1" HorizontalAlignment="Left">
|
|
||||||
<TextBlock x:Name="textBlockDraft" Padding="0"/>
|
|
||||||
</Viewbox>
|
|
||||||
<Viewbox Grid.Row="5" Grid.Column="0" HorizontalAlignment="Left">
|
|
||||||
<TextBlock Text="ETA" x:Name="labelETA"/>
|
<TextBlock Text="ETA" x:Name="labelETA"/>
|
||||||
</Viewbox>
|
</Viewbox>
|
||||||
<Viewbox Grid.Row="5" Grid.Column="1" HorizontalAlignment="Left">
|
<Viewbox Grid.Row="4" Grid.Column="1" HorizontalAlignment="Left">
|
||||||
<TextBlock x:Name="textBlockETA" Padding="0" FontWeight="DemiBold"/>
|
<TextBlock x:Name="textBlockETA" Padding="0" FontWeight="DemiBold"/>
|
||||||
</Viewbox>
|
</Viewbox>
|
||||||
<Viewbox Grid.Row="6" Grid.Column="0" HorizontalAlignment="Left">
|
<Viewbox Grid.Row="5" Grid.Column="0" HorizontalAlignment="Left">
|
||||||
<TextBlock Text="{x:Static p:Resources.textBerth}"/>
|
<TextBlock Text="{x:Static p:Resources.textBerth}"/>
|
||||||
</Viewbox>
|
</Viewbox>
|
||||||
<Viewbox Grid.Row="6" Grid.Column="1" HorizontalAlignment="Left">
|
<Viewbox Grid.Row="5" Grid.Column="1" HorizontalAlignment="Left">
|
||||||
<TextBlock x:Name="textBlockBerth" Padding="0" FontWeight="DemiBold" />
|
<TextBlock x:Name="textBlockBerth" Padding="0" FontWeight="DemiBold" />
|
||||||
</Viewbox>
|
</Viewbox>
|
||||||
|
<Viewbox Grid.Row="6" Grid.Column="0" Grid.ColumnSpan="2" HorizontalAlignment="Left">
|
||||||
|
<TextBlock x:Name="textBlockHarbour" Padding="0" FontWeight="DemiBold" />
|
||||||
|
</Viewbox>
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<Grid Grid.Row="0" Grid.Column="1">
|
||||||
<Label Grid.Row="0" Grid.Column="1" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
<RowDefinition Height="14" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Label Padding="0" Grid.Row="0" Grid.Column="0" Grid.RowSpan="1" FontSize="13" Content="- / -" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
||||||
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelAgent" PreviewMouseUp="labelAgent_PreviewMouseUp"/>
|
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelAgent" PreviewMouseUp="labelAgent_PreviewMouseUp"/>
|
||||||
<Label Grid.Row="0" Grid.Column="2" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
<Label Name="labelLastChangeAgency" FontSize="9" Padding="0" VerticalContentAlignment="Center" Grid.Row="1" Foreground="WhiteSmoke" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" HorizontalContentAlignment="Center" />
|
||||||
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelMooring" PreviewMouseUp="labelMooring_PreviewMouseUp"/>
|
</Grid>
|
||||||
<Label Grid.Row="0" Grid.Column="3" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
<Grid Grid.Row="0" Grid.Column="2">
|
||||||
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelPortAuthority" PreviewMouseUp="labelPortAuthority_PreviewMouseUp" />
|
<Grid.RowDefinitions>
|
||||||
<Label Grid.Row="0" Grid.Column="4" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
<RowDefinition Height="*" />
|
||||||
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelPilot" PreviewMouseUp="labelPilot_PreviewMouseUp"/>
|
<RowDefinition Height="14" />
|
||||||
<Label Grid.Row="0" Grid.Column="5" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
</Grid.RowDefinitions>
|
||||||
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelTug" PreviewMouseUp="labelTug_PreviewMouseUp"/>
|
<Label Padding="0" Grid.Row="0" Grid.Column="0" Grid.RowSpan="1" FontSize="13" Content="- / -" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
||||||
<Label Grid.Row="0" Grid.Column="6" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelMooring" PreviewMouseUp="labelMooring_PreviewMouseUp"/>
|
||||||
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelTerminal" PreviewMouseUp="labelTerminal_PreviewMouseUp" />
|
<Label Name="labelLastChangeMooring" FontSize="9" Padding="0" VerticalContentAlignment="Center" Grid.Row="1" Foreground="WhiteSmoke" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" HorizontalContentAlignment="Center" />
|
||||||
|
</Grid>
|
||||||
|
<Grid Grid.Row="0" Grid.Column="3">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
<RowDefinition Height="14" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Label Padding="0" Grid.Row="0" Grid.Column="0" Grid.RowSpan="1" FontSize="13" Content="- / -" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
||||||
|
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelPortAuthority" PreviewMouseUp="labelPortAuthority_PreviewMouseUp"/>
|
||||||
|
<Label Name="labelLastChangePortAuthority" FontSize="9" Padding="0" VerticalContentAlignment="Center" Grid.Row="1" Foreground="WhiteSmoke" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" HorizontalContentAlignment="Center" />
|
||||||
|
</Grid>
|
||||||
|
<Grid Grid.Row="0" Grid.Column="4">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
<RowDefinition Height="14" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Label Padding="0" Grid.Row="0" Grid.Column="0" Grid.RowSpan="1" FontSize="13" Content="- / -" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
||||||
|
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelPilot" PreviewMouseUp="labelPilot_PreviewMouseUp"/>
|
||||||
|
<Label Name="labelLastChangePilot" FontSize="9" Padding="0" VerticalContentAlignment="Center" Grid.Row="1" Foreground="WhiteSmoke" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" HorizontalContentAlignment="Center" />
|
||||||
|
</Grid>
|
||||||
|
<Grid Grid.Row="0" Grid.Column="5">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
<RowDefinition Height="14" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Label Padding="0" Grid.Row="0" Grid.Column="0" Grid.RowSpan="1" FontSize="13" Content="- / -" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
||||||
|
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelTug" PreviewMouseUp="labelTug_PreviewMouseUp"/>
|
||||||
|
<Label Name="labelLastChangeTug" FontSize="9" Padding="0" VerticalContentAlignment="Center" Grid.Row="1" Foreground="WhiteSmoke" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" HorizontalContentAlignment="Center" />
|
||||||
|
</Grid>
|
||||||
|
<Grid Grid.Row="0" Grid.Column="6">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
<RowDefinition Height="14" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Label Padding="0" Grid.Row="0" Grid.Column="0" Grid.RowSpan="1" FontSize="13" Content="- / -" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
||||||
|
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelTerminal" PreviewMouseUp="labelTerminal_PreviewMouseUp"/>
|
||||||
|
<Label Name="labelLastChangeTerminal" FontSize="9" Padding="0" VerticalContentAlignment="Center" Grid.Row="1" Foreground="WhiteSmoke" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" HorizontalContentAlignment="Center" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<!-- AGENCY -->
|
<!-- AGENCY -->
|
||||||
<Border Grid.Row="2" Grid.Column="1" BorderThickness="1, 0, 0, 0" BorderBrush="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" Padding="3,0,0,0">
|
<Border Grid.Row="2" Grid.Column="1" BorderThickness="1, 0, 0, 0" BorderBrush="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" Padding="3,0,0,0">
|
||||||
|
|||||||
@ -72,7 +72,7 @@ namespace BreCalClient
|
|||||||
|
|
||||||
string agentName = "";
|
string agentName = "";
|
||||||
string? name;
|
string? name;
|
||||||
_agency = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.AGENCY);
|
_agency = this.ShipcallControlModel?.GetParticipantForType(Extensions.ParticipantType.AGENCY);
|
||||||
name = _agency?.Name;
|
name = _agency?.Name;
|
||||||
if (name != null) agentName = name;
|
if (name != null) agentName = name;
|
||||||
this.labelAgent.Content = name ?? "- / -";
|
this.labelAgent.Content = name ?? "- / -";
|
||||||
@ -83,10 +83,9 @@ namespace BreCalClient
|
|||||||
this.labelAgencyETAETDValue.Content = "";
|
this.labelAgencyETAETDValue.Content = "";
|
||||||
this.textBlockAgencyRemarks.Text = "";
|
this.textBlockAgencyRemarks.Text = "";
|
||||||
this.textBlockAgencyBerthRemarks.Text = "";
|
this.textBlockAgencyBerthRemarks.Text = "";
|
||||||
this.textBlockDraft.Text = "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_mooring = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.MOORING);
|
_mooring = this.ShipcallControlModel?.GetParticipantForType(Extensions.ParticipantType.MOORING);
|
||||||
name = _mooring?.Name;
|
name = _mooring?.Name;
|
||||||
this.labelMooring.Content = name ?? "- / -";
|
this.labelMooring.Content = name ?? "- / -";
|
||||||
if(_mooring == null)
|
if(_mooring == null)
|
||||||
@ -95,7 +94,7 @@ namespace BreCalClient
|
|||||||
this.textBlockMooringRemarks.Text = "";
|
this.textBlockMooringRemarks.Text = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
_pilot = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.PILOT);
|
_pilot = this.ShipcallControlModel?.GetParticipantForType(Extensions.ParticipantType.PILOT);
|
||||||
name = _pilot?.Name;
|
name = _pilot?.Name;
|
||||||
this.labelPilot.Content = name ?? "- / - ";
|
this.labelPilot.Content = name ?? "- / - ";
|
||||||
if(_pilot == null)
|
if(_pilot == null)
|
||||||
@ -104,7 +103,7 @@ namespace BreCalClient
|
|||||||
this.textBlockPilotRemarks.Text = "";
|
this.textBlockPilotRemarks.Text = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
_tug = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.TUG);
|
_tug = this.ShipcallControlModel?.GetParticipantForType(Extensions.ParticipantType.TUG);
|
||||||
name = _tug?.Name;
|
name = _tug?.Name;
|
||||||
this.labelTug.Content = name ?? "- / - ";
|
this.labelTug.Content = name ?? "- / - ";
|
||||||
if(_tug == null)
|
if(_tug == null)
|
||||||
@ -113,7 +112,7 @@ namespace BreCalClient
|
|||||||
this.textBlockTugRemarks.Text = "";
|
this.textBlockTugRemarks.Text = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
_port_administration = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.PORT_ADMINISTRATION);
|
_port_administration = this.ShipcallControlModel?.GetParticipantForType(Extensions.ParticipantType.PORT_ADMINISTRATION);
|
||||||
name = _port_administration?.Name;
|
name = _port_administration?.Name;
|
||||||
this.labelPortAuthority.Content = name ?? "- / - ";
|
this.labelPortAuthority.Content = name ?? "- / - ";
|
||||||
if(_port_administration == null)
|
if(_port_administration == null)
|
||||||
@ -122,7 +121,7 @@ namespace BreCalClient
|
|||||||
this.textBlockPortAuthorityRemarks.Text = "";
|
this.textBlockPortAuthorityRemarks.Text = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
_terminal = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.TERMINAL);
|
_terminal = this.ShipcallControlModel?.GetParticipantForType(Extensions.ParticipantType.TERMINAL);
|
||||||
name = _terminal?.Name;
|
name = _terminal?.Name;
|
||||||
this.labelTerminal.Content = name ?? "- / - ";
|
this.labelTerminal.Content = name ?? "- / - ";
|
||||||
if(_terminal == null)
|
if(_terminal == null)
|
||||||
@ -269,22 +268,9 @@ namespace BreCalClient
|
|||||||
else
|
else
|
||||||
this.imageEvaluation.ToolTip = null;
|
this.imageEvaluation.ToolTip = null;
|
||||||
|
|
||||||
//Times? bsmdTimes = this.ShipcallControlModel?.GetTimesForParticipantType(Extensions.ParticipantType.BSMD);
|
this.textBlockBerth.Text = this.ShipcallControlModel?.GetBerthText(null);
|
||||||
//if (bsmdTimes != null)
|
|
||||||
this.textBlockBerth.Text = this.ShipcallControlModel?.GetBerthText(null);
|
|
||||||
//else
|
|
||||||
// this.textBlockBerth.Text = this.ShipcallControlModel?.Berth;
|
|
||||||
|
|
||||||
this.textBlockCallsign.Text = this.ShipcallControlModel?.Ship?.Callsign;
|
this.textBlockCallsign.Text = this.ShipcallControlModel?.Ship?.Callsign;
|
||||||
if (this.ShipcallControlModel?.Shipcall?.Type == ShipcallType.Arrival)
|
this.textBlockETA.Text = this.ShipcallControlModel?.GetETAETD(true);
|
||||||
{
|
|
||||||
this.textBlockETA.Text = this.ShipcallControlModel?.Shipcall?.Eta?.ToString("dd.MM. HH:mm");
|
|
||||||
}
|
|
||||||
if ((this.ShipcallControlModel?.Shipcall?.Type == ShipcallType.Departure) || (this.ShipcallControlModel?.Shipcall?.Type == ShipcallType.Shifting))
|
|
||||||
{
|
|
||||||
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.textBlockIMO.Text = this.ShipcallControlModel?.Ship?.Imo.ToString();
|
||||||
this.textBlockLengthWidth.Text = $"{this.ShipcallControlModel?.Ship?.Length} / {this.ShipcallControlModel?.Ship?.Width}";
|
this.textBlockLengthWidth.Text = $"{this.ShipcallControlModel?.Ship?.Length} / {this.ShipcallControlModel?.Ship?.Width}";
|
||||||
@ -294,6 +280,7 @@ namespace BreCalClient
|
|||||||
|
|
||||||
if (this.ShipcallControlModel?.Shipcall?.Type != ShipcallType.Arrival)
|
if (this.ShipcallControlModel?.Shipcall?.Type != ShipcallType.Arrival)
|
||||||
{
|
{
|
||||||
|
this.labelETA.Text = "ETD";
|
||||||
this.labelETAETDAgent.Content = "ETD";
|
this.labelETAETDAgent.Content = "ETD";
|
||||||
this.labelETAETDMooring.Content = "ETD";
|
this.labelETAETDMooring.Content = "ETD";
|
||||||
this.labelETAETDPilot.Content = "ETD";
|
this.labelETAETDPilot.Content = "ETD";
|
||||||
@ -315,6 +302,9 @@ namespace BreCalClient
|
|||||||
|
|
||||||
if (this.ShipcallControlModel != null)
|
if (this.ShipcallControlModel != null)
|
||||||
{
|
{
|
||||||
|
this.textBlockHarbour.Text = ((ShipcallControlModel != null) && (ShipcallControlModel.Shipcall != null) && BreCalLists.PortLookupDict.ContainsKey(ShipcallControlModel.Shipcall.PortId)) ?
|
||||||
|
BreCalLists.PortLookupDict[ShipcallControlModel.Shipcall.PortId].Name : "";
|
||||||
|
Extensions.ParticipantType? lastToUpdate = this.ShipcallControlModel?.LastParticipantTypeToUpdate();
|
||||||
|
|
||||||
Times? agencyTimes = this.ShipcallControlModel?.GetTimesForParticipantType(Extensions.ParticipantType.AGENCY);
|
Times? agencyTimes = this.ShipcallControlModel?.GetTimesForParticipantType(Extensions.ParticipantType.AGENCY);
|
||||||
if (agencyTimes != null)
|
if (agencyTimes != null)
|
||||||
@ -323,7 +313,19 @@ namespace BreCalClient
|
|||||||
this.labelAgencyETAETDValue.Content = agencyTimes.DisplayTime(this.ShipcallControlModel?.Shipcall?.Type == ShipcallType.Arrival);
|
this.labelAgencyETAETDValue.Content = agencyTimes.DisplayTime(this.ShipcallControlModel?.Shipcall?.Type == ShipcallType.Arrival);
|
||||||
this.textBlockAgencyRemarks.Text = agencyTimes.Remarks.TruncateDots(50);
|
this.textBlockAgencyRemarks.Text = agencyTimes.Remarks.TruncateDots(50);
|
||||||
this.textBlockAgencyBerthRemarks.Text = agencyTimes.BerthInfo.TruncateDots(50);
|
this.textBlockAgencyBerthRemarks.Text = agencyTimes.BerthInfo.TruncateDots(50);
|
||||||
this.textBlockDraft.Text = ShipcallControlModel?.Shipcall?.Draft?.ToString("N2");
|
DateTime? lc = this.ShipcallControlModel?.GetLastChangeForType(Extensions.ParticipantType.AGENCY);
|
||||||
|
this.labelLastChangeAgency.Content = lc.HasValue ? lc.Value.ToString("dd.MM.yyyy HH:mm") : string.Empty;
|
||||||
|
Grid.SetRowSpan(this.labelAgent, 1);
|
||||||
|
if(lastToUpdate == Extensions.ParticipantType.AGENCY)
|
||||||
|
{
|
||||||
|
this.labelLastChangeAgency.Foreground = Brushes.White;
|
||||||
|
this.labelLastChangeAgency.FontWeight = FontWeights.DemiBold;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.labelLastChangeAgency.Foreground = Brushes.LightGray;
|
||||||
|
this.labelLastChangeAgency.FontWeight = FontWeights.Normal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -332,7 +334,7 @@ namespace BreCalClient
|
|||||||
this.labelAgencyETAETDValue.Content = "- / -";
|
this.labelAgencyETAETDValue.Content = "- / -";
|
||||||
this.textBlockAgencyRemarks.Text = "";
|
this.textBlockAgencyRemarks.Text = "";
|
||||||
this.textBlockAgencyBerthRemarks.Text = "";
|
this.textBlockAgencyBerthRemarks.Text = "";
|
||||||
this.textBlockDraft.Text = "";
|
Grid.SetRowSpan(this.labelAgent, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
Times? mooringTimes = this.ShipcallControlModel?.GetTimesForParticipantType(Extensions.ParticipantType.MOORING);
|
Times? mooringTimes = this.ShipcallControlModel?.GetTimesForParticipantType(Extensions.ParticipantType.MOORING);
|
||||||
@ -356,12 +358,26 @@ namespace BreCalClient
|
|||||||
labelTimesMooringATD.Content = mooringTimes.Atd.Value.ToString("dd.MM.yyyy HH:mm");
|
labelTimesMooringATD.Content = mooringTimes.Atd.Value.ToString("dd.MM.yyyy HH:mm");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DateTime? lc = this.ShipcallControlModel?.GetLastChangeForType(Extensions.ParticipantType.MOORING);
|
||||||
|
this.labelLastChangeMooring.Content = lc.HasValue ? lc.Value.ToString("dd.MM.yyyy HH:mm") : string.Empty;
|
||||||
|
Grid.SetRowSpan(this.labelMooring, 1);
|
||||||
|
if (lastToUpdate == Extensions.ParticipantType.MOORING)
|
||||||
|
{
|
||||||
|
this.labelLastChangeMooring.Foreground = Brushes.White;
|
||||||
|
this.labelLastChangeMooring.FontWeight = FontWeights.DemiBold;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.labelLastChangeMooring.Foreground = Brushes.LightGray;
|
||||||
|
this.labelLastChangeMooring.FontWeight = FontWeights.Normal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.labelMooringETAETDValue.Content = "- / ";
|
this.labelMooringETAETDValue.Content = "- / ";
|
||||||
this.textBlockMooringRemarks.Text = "";
|
this.textBlockMooringRemarks.Text = "";
|
||||||
this.imageMooringLocked.Visibility = Visibility.Hidden;
|
this.imageMooringLocked.Visibility = Visibility.Hidden;
|
||||||
|
Grid.SetRowSpan(this.labelMooring, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
Times? portAuthorityTimes = this.ShipcallControlModel?.GetTimesForParticipantType(Extensions.ParticipantType.PORT_ADMINISTRATION);
|
Times? portAuthorityTimes = this.ShipcallControlModel?.GetTimesForParticipantType(Extensions.ParticipantType.PORT_ADMINISTRATION);
|
||||||
@ -375,12 +391,27 @@ namespace BreCalClient
|
|||||||
{
|
{
|
||||||
labelPortAuthorityLockTime.Content = portAuthorityTimes.LockTime.Value.ToString("dd.MM.yyyy HH:mm");
|
labelPortAuthorityLockTime.Content = portAuthorityTimes.LockTime.Value.ToString("dd.MM.yyyy HH:mm");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DateTime? lc = this.ShipcallControlModel?.GetLastChangeForType(Extensions.ParticipantType.PORT_ADMINISTRATION);
|
||||||
|
this.labelLastChangePortAuthority.Content = lc.HasValue ? lc.Value.ToString("dd.MM.yyyy HH:mm") : string.Empty;
|
||||||
|
Grid.SetRowSpan(this.labelPortAuthority, 1);
|
||||||
|
if (lastToUpdate == Extensions.ParticipantType.PORT_ADMINISTRATION)
|
||||||
|
{
|
||||||
|
this.labelLastChangePortAuthority.Foreground = Brushes.White;
|
||||||
|
this.labelLastChangePortAuthority.FontWeight = FontWeights.DemiBold;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.labelLastChangePortAuthority.Foreground = Brushes.LightGray;
|
||||||
|
this.labelLastChangePortAuthority.FontWeight = FontWeights.Normal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.labelPortAuthorityETAETDValue.Content = "- / -";
|
this.labelPortAuthorityETAETDValue.Content = "- / -";
|
||||||
this.textBlockPortAuthorityRemarks.Text = "";
|
this.textBlockPortAuthorityRemarks.Text = "";
|
||||||
this.imagePortAuthorityLocked.Visibility = Visibility.Hidden;
|
this.imagePortAuthorityLocked.Visibility = Visibility.Hidden;
|
||||||
|
Grid.SetRowSpan(this.labelPortAuthority, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
Times? pilotTimes = this.ShipcallControlModel?.GetTimesForParticipantType(Extensions.ParticipantType.PILOT);
|
Times? pilotTimes = this.ShipcallControlModel?.GetTimesForParticipantType(Extensions.ParticipantType.PILOT);
|
||||||
@ -389,12 +420,27 @@ namespace BreCalClient
|
|||||||
this.labelPilotETAETDValue.Content = pilotTimes.DisplayTime(this.ShipcallControlModel?.Shipcall?.Type == ShipcallType.Arrival);
|
this.labelPilotETAETDValue.Content = pilotTimes.DisplayTime(this.ShipcallControlModel?.Shipcall?.Type == ShipcallType.Arrival);
|
||||||
this.textBlockPilotRemarks.Text = pilotTimes.Remarks.TruncateDots(50);
|
this.textBlockPilotRemarks.Text = pilotTimes.Remarks.TruncateDots(50);
|
||||||
this.imagePilotLocked.Visibility = (pilotTimes.EtaBerthFixed ?? false) ? Visibility.Visible : Visibility.Hidden;
|
this.imagePilotLocked.Visibility = (pilotTimes.EtaBerthFixed ?? false) ? Visibility.Visible : Visibility.Hidden;
|
||||||
|
|
||||||
|
DateTime? lc = this.ShipcallControlModel?.GetLastChangeForType(Extensions.ParticipantType.PILOT);
|
||||||
|
this.labelLastChangePilot.Content = lc.HasValue ? lc.Value.ToString("dd.MM.yyyy HH:mm") : string.Empty;
|
||||||
|
Grid.SetRowSpan(this.labelPilot, 1);
|
||||||
|
if (lastToUpdate == Extensions.ParticipantType.PILOT)
|
||||||
|
{
|
||||||
|
this.labelLastChangePilot.Foreground = Brushes.White;
|
||||||
|
this.labelLastChangePilot.FontWeight = FontWeights.DemiBold;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.labelLastChangePilot.Foreground = Brushes.LightGray;
|
||||||
|
this.labelLastChangePilot.FontWeight = FontWeights.Normal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.labelPilotETAETDValue.Content = "- / -";
|
this.labelPilotETAETDValue.Content = "- / -";
|
||||||
this.textBlockPilotRemarks.Text = "";
|
this.textBlockPilotRemarks.Text = "";
|
||||||
this.imagePilotLocked.Visibility = Visibility.Hidden;
|
this.imagePilotLocked.Visibility = Visibility.Hidden;
|
||||||
|
Grid.SetRowSpan(this.labelPilot, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
Times? tugTimes = this.ShipcallControlModel?.GetTimesForParticipantType(Extensions.ParticipantType.TUG);
|
Times? tugTimes = this.ShipcallControlModel?.GetTimesForParticipantType(Extensions.ParticipantType.TUG);
|
||||||
@ -403,12 +449,27 @@ namespace BreCalClient
|
|||||||
this.labelTugETAETDValue.Content = tugTimes.DisplayTime(this.ShipcallControlModel?.Shipcall?.Type == ShipcallType.Arrival);
|
this.labelTugETAETDValue.Content = tugTimes.DisplayTime(this.ShipcallControlModel?.Shipcall?.Type == ShipcallType.Arrival);
|
||||||
this.textBlockTugRemarks.Text = tugTimes.Remarks.TruncateDots(50);
|
this.textBlockTugRemarks.Text = tugTimes.Remarks.TruncateDots(50);
|
||||||
this.imageTugLocked.Visibility = (tugTimes.EtaBerthFixed ?? false) ? Visibility.Visible : Visibility.Hidden;
|
this.imageTugLocked.Visibility = (tugTimes.EtaBerthFixed ?? false) ? Visibility.Visible : Visibility.Hidden;
|
||||||
|
|
||||||
|
DateTime? lc = this.ShipcallControlModel?.GetLastChangeForType(Extensions.ParticipantType.TUG);
|
||||||
|
this.labelLastChangeTug.Content = lc.HasValue ? lc.Value.ToString("dd.MM.yyyy HH:mm") : string.Empty;
|
||||||
|
Grid.SetRowSpan(this.labelTug, 1);
|
||||||
|
if (lastToUpdate == Extensions.ParticipantType.TUG)
|
||||||
|
{
|
||||||
|
this.labelLastChangeTug.Foreground = Brushes.White;
|
||||||
|
this.labelLastChangeTug.FontWeight = FontWeights.DemiBold;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.labelLastChangeTug.Foreground = Brushes.LightGray;
|
||||||
|
this.labelLastChangeTug.FontWeight = FontWeights.Normal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.labelTugETAETDValue.Content = "- / -";
|
this.labelTugETAETDValue.Content = "- / -";
|
||||||
this.textBlockTugRemarks.Text = "";
|
this.textBlockTugRemarks.Text = "";
|
||||||
this.imageTugLocked.Visibility = Visibility.Hidden;
|
this.imageTugLocked.Visibility = Visibility.Hidden;
|
||||||
|
Grid.SetRowSpan(this.labelTug, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.rowDefinitionTerminalBerth.Height = (this.ShipcallControlModel?.Shipcall?.Type == ShipcallType.Arrival) ? new(14) : new(0);
|
this.rowDefinitionTerminalBerth.Height = (this.ShipcallControlModel?.Shipcall?.Type == ShipcallType.Arrival) ? new(14) : new(0);
|
||||||
@ -422,6 +483,19 @@ namespace BreCalClient
|
|||||||
this.labelOperationsStart.Content = terminalTimes.DisplayTime(this.ShipcallControlModel?.Shipcall?.Type == ShipcallType.Arrival);
|
this.labelOperationsStart.Content = terminalTimes.DisplayTime(this.ShipcallControlModel?.Shipcall?.Type == ShipcallType.Arrival);
|
||||||
this.textBlockTerminalRemarks.Text = terminalTimes.Remarks.TruncateDots(40);
|
this.textBlockTerminalRemarks.Text = terminalTimes.Remarks.TruncateDots(40);
|
||||||
this.textBlockTerminalBerthRemarks.Text = terminalTimes.BerthInfo.TruncateDots(40);
|
this.textBlockTerminalBerthRemarks.Text = terminalTimes.BerthInfo.TruncateDots(40);
|
||||||
|
DateTime? lc = this.ShipcallControlModel?.GetLastChangeForType(Extensions.ParticipantType.TERMINAL);
|
||||||
|
this.labelLastChangeTerminal.Content = lc.HasValue ? lc.Value.ToString("dd.MM.yyyy HH:mm") : string.Empty;
|
||||||
|
Grid.SetRowSpan(this.labelTerminal, 1);
|
||||||
|
if (lastToUpdate == Extensions.ParticipantType.TERMINAL)
|
||||||
|
{
|
||||||
|
this.labelLastChangeTerminal.Foreground = Brushes.White;
|
||||||
|
this.labelLastChangeTerminal.FontWeight = FontWeights.DemiBold;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.labelLastChangeTerminal.Foreground = Brushes.LightGray;
|
||||||
|
this.labelLastChangeTerminal.FontWeight = FontWeights.Normal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -429,6 +503,7 @@ namespace BreCalClient
|
|||||||
this.labelOperationsStart.Content = "";
|
this.labelOperationsStart.Content = "";
|
||||||
this.textBlockTerminalRemarks.Text = "";
|
this.textBlockTerminalRemarks.Text = "";
|
||||||
this.textBlockTerminalBerthRemarks.Text = "";
|
this.textBlockTerminalBerthRemarks.Text = "";
|
||||||
|
Grid.SetRowSpan(this.labelTerminal, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -118,6 +118,8 @@ namespace BreCalClient
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool AllowPortChange { get; set; } = true;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region public methods
|
#region public methods
|
||||||
@ -217,7 +219,7 @@ namespace BreCalClient
|
|||||||
return berthText;
|
return berthText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetETAETD()
|
public string GetETAETD(bool useShortVersion = false)
|
||||||
{
|
{
|
||||||
DateTime theDate = DateTime.Now;
|
DateTime theDate = DateTime.Now;
|
||||||
if(this.Shipcall != null)
|
if(this.Shipcall != null)
|
||||||
@ -241,6 +243,8 @@ namespace BreCalClient
|
|||||||
theDate = agentTimes.EtdBerth.Value;
|
theDate = agentTimes.EtdBerth.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(useShortVersion)
|
||||||
|
return theDate.ToString("dd.MM. HH:mm");
|
||||||
return theDate.ToString();
|
return theDate.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,6 +313,42 @@ namespace BreCalClient
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DateTime? GetLastChangeForType(Extensions.ParticipantType type)
|
||||||
|
{
|
||||||
|
DateTime? lastChange = null;
|
||||||
|
Times? times = GetTimesForParticipantType(type);
|
||||||
|
if(times != null)
|
||||||
|
{
|
||||||
|
if (times.Modified.HasValue) lastChange = times.Modified.Value;
|
||||||
|
else lastChange = times.Created;
|
||||||
|
}
|
||||||
|
return lastChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Extensions.ParticipantType? LastParticipantTypeToUpdate()
|
||||||
|
{
|
||||||
|
Extensions.ParticipantType? last = null;
|
||||||
|
DateTime min = DateTime.MinValue;
|
||||||
|
foreach(Times times in this.Times)
|
||||||
|
{
|
||||||
|
if (times.Modified.HasValue)
|
||||||
|
{
|
||||||
|
if (times.Modified.Value > min)
|
||||||
|
{
|
||||||
|
min = times.Modified.Value;
|
||||||
|
last = (Extensions.ParticipantType)times.ParticipantType;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(times.Created > min)
|
||||||
|
{
|
||||||
|
min = times.Created;
|
||||||
|
last = (Extensions.ParticipantType)times.ParticipantType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return last;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region helper
|
#region helper
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:local="clr-namespace:RoleEditor"
|
xmlns:local="clr-namespace:RoleEditor"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="Edit berth" Height="188" Width="450" Loaded="Window_Loaded">
|
Title="Edit berth" Height="216" Width="450" Loaded="Window_Loaded">
|
||||||
<Grid x:Name="berthGrid">
|
<Grid x:Name="berthGrid">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width=".3*" />
|
<ColumnDefinition Width=".3*" />
|
||||||
@ -16,6 +16,7 @@
|
|||||||
<RowDefinition Height="28" />
|
<RowDefinition Height="28" />
|
||||||
<RowDefinition Height="28" />
|
<RowDefinition Height="28" />
|
||||||
<RowDefinition Height="28" />
|
<RowDefinition Height="28" />
|
||||||
|
<RowDefinition Height="28" />
|
||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" />
|
||||||
<RowDefinition Height="28" />
|
<RowDefinition Height="28" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
@ -45,7 +46,9 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
<Label Content="Uses lock" HorizontalAlignment="Right" Grid.Row="3" />
|
<Label Content="Uses lock" HorizontalAlignment="Right" Grid.Row="3" />
|
||||||
<CheckBox x:Name="checkBoxLock" Grid.Row="3" Grid.Column="1" VerticalAlignment="Center" Margin="2" IsChecked="{Binding Path=Lock, Mode=OneWay}"/>
|
<CheckBox x:Name="checkBoxLock" Grid.Row="3" Grid.Column="1" VerticalAlignment="Center" Margin="2" IsChecked="{Binding Path=Lock, Mode=OneWay}"/>
|
||||||
<StackPanel Grid.Column="1" Grid.Row="5" Orientation="Horizontal" FlowDirection="RightToLeft">
|
<Label Content="Port" HorizontalAlignment="Right" Grid.Row="4" />
|
||||||
|
<ComboBox Name="comboBoxPorts" Margin="2" Grid.Column="1" Grid.Row="4" SelectedItem="{Binding Port, Mode=OneWay}" />
|
||||||
|
<StackPanel Grid.Column="1" Grid.Row="6" Orientation="Horizontal" FlowDirection="RightToLeft">
|
||||||
<Button x:Name="buttonCancel" Width="80" Content="Cancel" Margin="2" Click="buttonCancel_Click" />
|
<Button x:Name="buttonCancel" Width="80" Content="Cancel" Margin="2" Click="buttonCancel_Click" />
|
||||||
<Button x:Name="buttonOK" Width="80" Content="OK" Margin="2" Click="buttonOK_Click"/>
|
<Button x:Name="buttonOK" Width="80" Content="OK" Margin="2" Click="buttonOK_Click"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|||||||
@ -20,6 +20,8 @@ namespace RoleEditor
|
|||||||
|
|
||||||
public List<Participant> Authorities { get; } = new List<Participant>();
|
public List<Participant> Authorities { get; } = new List<Participant>();
|
||||||
|
|
||||||
|
public List<Port> Ports { get; } = new List<Port>();
|
||||||
|
|
||||||
private void buttonCancel_Click(object sender, RoutedEventArgs e)
|
private void buttonCancel_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
this.DialogResult = false;
|
this.DialogResult = false;
|
||||||
@ -43,6 +45,12 @@ namespace RoleEditor
|
|||||||
else
|
else
|
||||||
this.Berth.Authority_Id = null;
|
this.Berth.Authority_Id = null;
|
||||||
|
|
||||||
|
this.Berth.Port = this.comboBoxPorts.SelectedItem as Port;
|
||||||
|
if (this.Berth.Port != null)
|
||||||
|
this.Berth.Port_Id = this.Berth.Port.Id;
|
||||||
|
else
|
||||||
|
this.Berth.Port_Id = null;
|
||||||
|
|
||||||
this.DialogResult = true;
|
this.DialogResult = true;
|
||||||
this.Close();
|
this.Close();
|
||||||
}
|
}
|
||||||
@ -52,6 +60,7 @@ namespace RoleEditor
|
|||||||
this.DataContext = this.Berth;
|
this.DataContext = this.Berth;
|
||||||
this.comboBoxParticipants.ItemsSource = this.Owners;
|
this.comboBoxParticipants.ItemsSource = this.Owners;
|
||||||
this.comboBoxAuthorities.ItemsSource = this.Authorities;
|
this.comboBoxAuthorities.ItemsSource = this.Authorities;
|
||||||
|
this.comboBoxPorts.ItemsSource = this.Ports;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buttonResetParticipant_Click(object sender, RoutedEventArgs e)
|
private void buttonResetParticipant_Click(object sender, RoutedEventArgs e)
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
xmlns:local="clr-namespace:RoleEditor"
|
xmlns:local="clr-namespace:RoleEditor"
|
||||||
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="Bremen calling admin editor" Height="670" Width="800" Icon="Resources/lock_preferences.ico" Loaded="Window_Loaded">
|
Title="Bremen calling admin editor" Height="670" Width="1024" Icon="Resources/lock_preferences.ico" Loaded="Window_Loaded">
|
||||||
<Grid>
|
<Grid>
|
||||||
<TabControl>
|
<TabControl>
|
||||||
<TabItem Header="Participant, users and roles">
|
<TabItem Header="Participant, users and roles">
|
||||||
@ -16,8 +16,9 @@
|
|||||||
<RowDefinition Height=".5*" />
|
<RowDefinition Height=".5*" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width=".5*" />
|
<ColumnDefinition Width=".4*" />
|
||||||
<ColumnDefinition Width=".5*" />
|
<ColumnDefinition Width=".3*" />
|
||||||
|
<ColumnDefinition Width=".3*" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<GroupBox Header="Participant" Margin="2">
|
<GroupBox Header="Participant" Margin="2">
|
||||||
<Grid>
|
<Grid>
|
||||||
@ -82,6 +83,69 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
<GroupBox Header="Port Assignment" Margin="2" Grid.Row="0" Grid.Column="1">
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="28" />
|
||||||
|
<RowDefinition Height="28" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="60" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<ListBox x:Name="listBoxPortAssignment" Margin="2" Grid.Row="0" Grid.Column="0" Grid.RowSpan="3" />
|
||||||
|
<Button x:Name="buttonAddPortAssignment" Margin="2" Grid.Row="0" Grid.Column="1" Click="buttonAddPortAssignment_Click">
|
||||||
|
<Image Source="./Resources/arrow_left_green.png"/>
|
||||||
|
</Button>
|
||||||
|
<Button x:Name="buttonRemovePortAssignment" Margin="2" Grid.Row="1" Grid.Column="1" Click="buttonRemovePortAssignment_Click">
|
||||||
|
<Image Source="./Resources/delete2.png"/>
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
</GroupBox>
|
||||||
|
<GroupBox Header="Ports" Margin="2" Grid.Row="0" Grid.Column="2">
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="28"/>
|
||||||
|
<RowDefinition Height="28"/>
|
||||||
|
<RowDefinition Height="28"/>
|
||||||
|
<RowDefinition Height="*"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="160" />
|
||||||
|
<ColumnDefinition Width=".38*" />
|
||||||
|
<ColumnDefinition Width=".62*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<ListBox x:Name="listBoxPort" Margin="2" Grid.RowSpan="4" SelectionChanged="listBoxPort_SelectionChanged">
|
||||||
|
<ListBox.ContextMenu>
|
||||||
|
<ContextMenu>
|
||||||
|
<MenuItem x:Name="menuItemNewPort" Header="New.." Click="menuItemNewPort_Click">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<Image Source="Resources/add.png" />
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem x:Name="menuItemDeletePort" Header="Delete" Click="menuItemDeletePort_Click">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<Image Source="Resources/delete2.png" />
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
|
</ContextMenu>
|
||||||
|
</ListBox.ContextMenu>
|
||||||
|
</ListBox>
|
||||||
|
<Label Grid.Row="0" Grid.Column="1" Content="Name" HorizontalAlignment="Right"/>
|
||||||
|
<Label Grid.Row="1" Grid.Column="1" Content="Locode" HorizontalAlignment="Right"/>
|
||||||
|
<TextBox x:Name="textBoxPortName" Grid.Row="0" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" MaxLength="128"/>
|
||||||
|
<TextBox x:Name="textBoxPortLocode" Grid.Row="1" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" MaxLength="5" />
|
||||||
|
|
||||||
|
<Button x:Name="buttonPortSave" Grid.Row="2" Grid.Column="2" Click="buttonPortSave_Click" Margin="2">
|
||||||
|
<DockPanel>
|
||||||
|
<Image Source="./Resources/disk_blue.png" Margin="0,0,5,0" Height="24" DockPanel.Dock="Left" Width="16"/>
|
||||||
|
<TextBlock Text="Save" VerticalAlignment="Center" DockPanel.Dock="Right"/>
|
||||||
|
</DockPanel>
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</GroupBox>
|
||||||
<GroupBox Header="User" Margin="2" Grid.Row="1">
|
<GroupBox Header="User" Margin="2" Grid.Row="1">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
@ -145,7 +209,7 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
<GroupBox Header="Role" Margin="2" Grid.Column="1">
|
<GroupBox Header="Role" Margin="2" Grid.Column="1" Grid.Row="1">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="28"/>
|
<RowDefinition Height="28"/>
|
||||||
@ -199,7 +263,7 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
<GroupBox Header="Securable" Margin="2" Grid.Row="1" Grid.Column="1">
|
<GroupBox Header="Securable" Margin="2" Grid.Row="1" Grid.Column="2">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="28"/>
|
<RowDefinition Height="28"/>
|
||||||
@ -276,6 +340,7 @@
|
|||||||
<DataGridCheckBoxColumn Header="Lock" Binding="{Binding Path=Lock}" IsReadOnly="True"/>
|
<DataGridCheckBoxColumn Header="Lock" Binding="{Binding Path=Lock}" IsReadOnly="True"/>
|
||||||
<DataGridTextColumn Header="Terminal" Binding="{Binding Path=Terminal, Mode=OneWay}" IsReadOnly="True"/>
|
<DataGridTextColumn Header="Terminal" Binding="{Binding Path=Terminal, Mode=OneWay}" IsReadOnly="True"/>
|
||||||
<DataGridTextColumn Header="Authority" Binding="{Binding Path=Authority_Text, Mode=OneWay}" IsReadOnly="True" />
|
<DataGridTextColumn Header="Authority" Binding="{Binding Path=Authority_Text, Mode=OneWay}" IsReadOnly="True" />
|
||||||
|
<DataGridTextColumn Header="Port" Binding="{Binding Path=Port}" IsReadOnly="True" />
|
||||||
<DataGridTextColumn Header="Deleted" Binding="{Binding Path=Deleted, Mode=OneWay}" IsReadOnly="True" />
|
<DataGridTextColumn Header="Deleted" Binding="{Binding Path=Deleted, Mode=OneWay}" IsReadOnly="True" />
|
||||||
</DataGrid.Columns>
|
</DataGrid.Columns>
|
||||||
</local:ENIDataGrid>
|
</local:ENIDataGrid>
|
||||||
|
|||||||
@ -38,6 +38,8 @@ namespace RoleEditor
|
|||||||
private readonly ObservableCollection<SecurableAssignment> _assignedSecurables = new ObservableCollection<SecurableAssignment>();
|
private readonly ObservableCollection<SecurableAssignment> _assignedSecurables = new ObservableCollection<SecurableAssignment>();
|
||||||
private readonly ObservableCollection<Berth> _berths = new ObservableCollection<Berth>();
|
private readonly ObservableCollection<Berth> _berths = new ObservableCollection<Berth>();
|
||||||
private readonly ObservableCollection<Ship> _ships = new ObservableCollection<Ship>();
|
private readonly ObservableCollection<Ship> _ships = new ObservableCollection<Ship>();
|
||||||
|
private readonly ObservableCollection<Port> _ports = new ObservableCollection<Port>();
|
||||||
|
private readonly ObservableCollection<PortAssignment> _assignedPorts = new ObservableCollection<PortAssignment>();
|
||||||
private DBManager _dbManager;
|
private DBManager _dbManager;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -77,6 +79,10 @@ namespace RoleEditor
|
|||||||
_securables.Add(s);
|
_securables.Add(s);
|
||||||
this.listBoxSecurables.ItemsSource = _securables;
|
this.listBoxSecurables.ItemsSource = _securables;
|
||||||
|
|
||||||
|
// load all ports
|
||||||
|
foreach (Port port in await Port.LoadAll(_dbManager)) _ports.Add(port);
|
||||||
|
this.listBoxPort.ItemsSource = _ports;
|
||||||
|
|
||||||
// load all berths
|
// load all berths
|
||||||
foreach (Berth b in await Berth.LoadAll(_dbManager))
|
foreach (Berth b in await Berth.LoadAll(_dbManager))
|
||||||
{
|
{
|
||||||
@ -89,6 +95,10 @@ namespace RoleEditor
|
|||||||
{
|
{
|
||||||
b.Authority = participants.Where(p => p.Id == b.Authority_Id).FirstOrDefault();
|
b.Authority = participants.Where(p => p.Id == b.Authority_Id).FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
if (b.Port_Id != null)
|
||||||
|
{
|
||||||
|
b.Port = _ports.Where(p => p.Id == b.Port_Id).FirstOrDefault();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.dataGridBerths.Initialize();
|
this.dataGridBerths.Initialize();
|
||||||
this.dataGridBerths.ItemsSource = _berths;
|
this.dataGridBerths.ItemsSource = _berths;
|
||||||
@ -114,10 +124,12 @@ namespace RoleEditor
|
|||||||
this.dataGridShips.EditRequested += DataGridShips_EditRequested;
|
this.dataGridShips.EditRequested += DataGridShips_EditRequested;
|
||||||
this.dataGridShips.DeleteRequested += DataGridShips_DeleteRequested;
|
this.dataGridShips.DeleteRequested += DataGridShips_DeleteRequested;
|
||||||
|
|
||||||
|
|
||||||
// set other item sources (filled later after selection)
|
// set other item sources (filled later after selection)
|
||||||
this.listBoxUser.ItemsSource = _users;
|
this.listBoxUser.ItemsSource = _users;
|
||||||
this.listBoxRoleSecurables.ItemsSource = _assignedSecurables;
|
this.listBoxRoleSecurables.ItemsSource = _assignedSecurables;
|
||||||
this.listBoxUserRoles.ItemsSource = _assignedRoles;
|
this.listBoxUserRoles.ItemsSource = _assignedRoles;
|
||||||
|
this.listBoxPortAssignment.ItemsSource = _assignedPorts;
|
||||||
|
|
||||||
this.comboBoxParticipantType.ItemsSource = EnumHelper.GetAllValuesAndDescription(typeof(Participant.ParticipantType));
|
this.comboBoxParticipantType.ItemsSource = EnumHelper.GetAllValuesAndDescription(typeof(Participant.ParticipantType));
|
||||||
|
|
||||||
@ -192,6 +204,7 @@ namespace RoleEditor
|
|||||||
ebd.Berth = b;
|
ebd.Berth = b;
|
||||||
ebd.Owners.AddRange(this._terminals);
|
ebd.Owners.AddRange(this._terminals);
|
||||||
ebd.Authorities.AddRange(this._authorities);
|
ebd.Authorities.AddRange(this._authorities);
|
||||||
|
ebd.Ports.AddRange(this._ports.Where(p => !p.IsDeleted));
|
||||||
if (ebd.ShowDialog() ?? false)
|
if (ebd.ShowDialog() ?? false)
|
||||||
{
|
{
|
||||||
await b.Save(_dbManager);
|
await b.Save(_dbManager);
|
||||||
@ -208,6 +221,7 @@ namespace RoleEditor
|
|||||||
ebd.Berth = b;
|
ebd.Berth = b;
|
||||||
ebd.Owners.AddRange(this._terminals);
|
ebd.Owners.AddRange(this._terminals);
|
||||||
ebd.Authorities.AddRange(this._authorities);
|
ebd.Authorities.AddRange(this._authorities);
|
||||||
|
ebd.Ports.AddRange(_ports.Where(p => !p.IsDeleted));
|
||||||
if (ebd.ShowDialog() ?? false)
|
if (ebd.ShowDialog() ?? false)
|
||||||
{
|
{
|
||||||
_berths.Add(b);
|
_berths.Add(b);
|
||||||
@ -386,6 +400,59 @@ namespace RoleEditor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void buttonPortSave_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
Port? p = this.listBoxPort.SelectedItem as Port;
|
||||||
|
if (p != null)
|
||||||
|
{
|
||||||
|
p.Name = this.textBoxPortName.Text.Trim();
|
||||||
|
p.Locode = this.textBoxPortLocode.Text.Trim();
|
||||||
|
await p.Save(_dbManager);
|
||||||
|
this.listBoxPort.ItemsSource = null;
|
||||||
|
this.listBoxPort.ItemsSource = _ports;
|
||||||
|
this.listBoxPort.SelectedItem = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void buttonAddPortAssignment_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if ((this.listBoxPort.SelectedItem is Port p) && (this.listBoxParticipant.SelectedItem is Participant pa))
|
||||||
|
{
|
||||||
|
// test if assignment is already present
|
||||||
|
bool foundMatchingAssignment = false;
|
||||||
|
foreach (PortAssignment portAssignment in _assignedPorts)
|
||||||
|
{
|
||||||
|
if ((portAssignment.PortId == p.Id) && (portAssignment.ParticipantId == pa.Id))
|
||||||
|
{
|
||||||
|
foundMatchingAssignment = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundMatchingAssignment)
|
||||||
|
{
|
||||||
|
PortAssignment portAssignment = new PortAssignment();
|
||||||
|
portAssignment.PortId = (int)p.Id;
|
||||||
|
portAssignment.ParticipantId = (int)pa.Id;
|
||||||
|
portAssignment.AssignedParticipant = pa;
|
||||||
|
portAssignment.AssignedPort = p;
|
||||||
|
await portAssignment.Save(_dbManager);
|
||||||
|
_assignedPorts.Add(portAssignment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void buttonRemovePortAssignment_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
PortAssignment? pa = this.listBoxPortAssignment.SelectedItem as PortAssignment;
|
||||||
|
if (pa != null)
|
||||||
|
{
|
||||||
|
await pa.Delete(_dbManager);
|
||||||
|
if (_assignedPorts.Contains(pa))
|
||||||
|
_assignedPorts.Remove(pa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region listbox selection callbacks
|
#region listbox selection callbacks
|
||||||
@ -430,6 +497,19 @@ namespace RoleEditor
|
|||||||
foreach (User u in await User.LoadForParticipant(p, _dbManager))
|
foreach (User u in await User.LoadForParticipant(p, _dbManager))
|
||||||
_users.Add(u);
|
_users.Add(u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -> load port assignments for this participant selection
|
||||||
|
this._assignedPorts.Clear();
|
||||||
|
if(p != null)
|
||||||
|
{
|
||||||
|
foreach (PortAssignment pa in await PortAssignment.LoadForParticipant(p, this._dbManager))
|
||||||
|
{
|
||||||
|
foreach (Port port in this._ports)
|
||||||
|
if (pa.PortId == port.Id)
|
||||||
|
pa.AssignedPort = port;
|
||||||
|
_assignedPorts.Add(pa);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void listBoxRoles_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
private async void listBoxRoles_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
@ -496,6 +576,13 @@ namespace RoleEditor
|
|||||||
this.textBoxSecurableName.Text = (s != null) ? s.Name : string.Empty;
|
this.textBoxSecurableName.Text = (s != null) ? s.Name : string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void listBoxPort_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
Port? p = this.listBoxPort.SelectedItem as Port;
|
||||||
|
this.textBoxPortName.Text = (p != null) ? p.Name : string.Empty;
|
||||||
|
this.textBoxPortLocode.Text = (p != null) ? p.Locode : string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region menuitem callbacks
|
#region menuitem callbacks
|
||||||
@ -597,6 +684,29 @@ namespace RoleEditor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void menuItemNewPort_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
Port p = new();
|
||||||
|
this._ports.Add(p);
|
||||||
|
this.listBoxPort.SelectedItem = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void menuItemDeletePort_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (this.listBoxPort.SelectedItem is Port p)
|
||||||
|
{
|
||||||
|
await p.Delete(_dbManager);
|
||||||
|
this._ports.Remove(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Excel import
|
#region Excel import
|
||||||
@ -634,7 +744,7 @@ namespace RoleEditor
|
|||||||
{
|
{
|
||||||
if (reader.FieldCount < 2)
|
if (reader.FieldCount < 2)
|
||||||
{
|
{
|
||||||
throw new InvalidDataException("Sheet must have at least 2 Columns of data");
|
throw new InvalidDataException("Sheet must have at least 3 Columns of data");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reader.IsDBNull(0) && reader.IsDBNull(1)) continue;
|
if (reader.IsDBNull(0) && reader.IsDBNull(1)) continue;
|
||||||
@ -649,8 +759,20 @@ namespace RoleEditor
|
|||||||
if (_berths.Any(predicate: x => (x.Name != null) && x.Name.Equals(berth_name, StringComparison.OrdinalIgnoreCase)))
|
if (_berths.Any(predicate: x => (x.Name != null) && x.Name.Equals(berth_name, StringComparison.OrdinalIgnoreCase)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
string port_name = "";
|
||||||
|
if (!reader.IsDBNull(2)) port_name = reader.GetString(2);
|
||||||
|
|
||||||
|
// find port in list
|
||||||
|
if(!_ports.Any(x => (x.Name != null) && x.Name.Equals(port_name, StringComparison.OrdinalIgnoreCase)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Port port = _ports.First(x => (x.Name != null) && x.Name.Equals(port_name, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
Berth b = new Berth();
|
Berth b = new Berth();
|
||||||
b.Name = berth_name;
|
b.Name = berth_name;
|
||||||
|
b.Port = port;
|
||||||
|
b.Port_Id = port.Id;
|
||||||
|
|
||||||
bool found_participant = false;
|
bool found_participant = false;
|
||||||
|
|
||||||
foreach(Participant p in this._participants)
|
foreach(Participant p in this._participants)
|
||||||
|
|||||||
6
src/RoleEditor/Properties/Settings.Designer.cs
generated
6
src/RoleEditor/Properties/Settings.Designer.cs
generated
@ -12,7 +12,7 @@ namespace RoleEditor.Properties {
|
|||||||
|
|
||||||
|
|
||||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.5.0.0")]
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.10.0.0")]
|
||||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||||
|
|
||||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||||
@ -25,8 +25,8 @@ namespace RoleEditor.Properties {
|
|||||||
|
|
||||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
[global::System.Configuration.DefaultSettingValueAttribute("Server=localhost;User ID=ds;Password=HalloWach_2323XXL!!;Database=bremen_calling;" +
|
[global::System.Configuration.DefaultSettingValueAttribute("Server=localhost;User ID=ds;Password=HalloWach_2323XXL!!;Database=bremen_calling_" +
|
||||||
"Port=33306")]
|
"test;Port=33306")]
|
||||||
public string ConnectionString {
|
public string ConnectionString {
|
||||||
get {
|
get {
|
||||||
return ((string)(this["ConnectionString"]));
|
return ((string)(this["ConnectionString"]));
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<Profiles />
|
<Profiles />
|
||||||
<Settings>
|
<Settings>
|
||||||
<Setting Name="ConnectionString" Type="System.String" Scope="Application">
|
<Setting Name="ConnectionString" Type="System.String" Scope="Application">
|
||||||
<Value Profile="(Default)">Server=localhost;User ID=ds;Password=HalloWach_2323XXL!!;Database=bremen_calling;Port=33306</Value>
|
<Value Profile="(Default)">Server=localhost;User ID=ds;Password=HalloWach_2323XXL!!;Database=bremen_calling_test;Port=33306</Value>
|
||||||
</Setting>
|
</Setting>
|
||||||
</Settings>
|
</Settings>
|
||||||
</SettingsFile>
|
</SettingsFile>
|
||||||
@ -6,6 +6,8 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
<ApplicationIcon>Resources\lock_preferences.ico</ApplicationIcon>
|
<ApplicationIcon>Resources\lock_preferences.ico</ApplicationIcon>
|
||||||
|
<FileVersion>1.6.0.4</FileVersion>
|
||||||
|
<AssemblyVersion>1.6.0.4</AssemblyVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@ -1,12 +1,7 @@
|
|||||||
// Copyright (c) 2023- schick Informatik
|
// Copyright (c) 2023- schick Informatik
|
||||||
// Description: Model class for berth entity
|
// Description: Model class for berth entity
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace brecal.model
|
namespace brecal.model
|
||||||
{
|
{
|
||||||
@ -23,10 +18,14 @@ namespace brecal.model
|
|||||||
|
|
||||||
public uint? Authority_Id { get; set; }
|
public uint? Authority_Id { get; set; }
|
||||||
|
|
||||||
|
public uint? Port_Id { get; set; }
|
||||||
|
|
||||||
public Participant? Owner { get; set; }
|
public Participant? Owner { get; set; }
|
||||||
|
|
||||||
public Participant? Authority { get; set; }
|
public Participant? Authority { get; set; }
|
||||||
|
|
||||||
|
public Port? Port { get; set; }
|
||||||
|
|
||||||
public string? Terminal { get { if (Owner != null) return Owner.Name; else return "n/a"; } }
|
public string? Terminal { get { if (Owner != null) return Owner.Name; else return "n/a"; } }
|
||||||
|
|
||||||
public string? Authority_Text { get { if (Authority != null) return Authority.Name; else return "n/a"; } }
|
public string? Authority_Text { get { if (Authority != null) return Authority.Name; else return "n/a"; } }
|
||||||
@ -48,12 +47,12 @@ namespace brecal.model
|
|||||||
|
|
||||||
public static void SetLoadQuery(IDbCommand cmd, params object?[] list)
|
public static void SetLoadQuery(IDbCommand cmd, params object?[] list)
|
||||||
{
|
{
|
||||||
cmd.CommandText = "SELECT id, name, owner_id, authority_id, `lock`, created, modified, deleted FROM berth";
|
cmd.CommandText = "SELECT id, name, owner_id, authority_id, port_id, `lock`, created, modified, deleted FROM berth";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<DbEntity> LoadElems(IDataReader reader)
|
public static List<DbEntity> LoadElems(IDataReader reader)
|
||||||
{
|
{
|
||||||
List<DbEntity> result = new List<DbEntity>();
|
List<DbEntity> result = new();
|
||||||
while (reader.Read())
|
while (reader.Read())
|
||||||
{
|
{
|
||||||
Berth b = new();
|
Berth b = new();
|
||||||
@ -61,10 +60,11 @@ namespace brecal.model
|
|||||||
if (!reader.IsDBNull(1)) b.Name = reader.GetString(1);
|
if (!reader.IsDBNull(1)) b.Name = reader.GetString(1);
|
||||||
if (!reader.IsDBNull(2)) b.Owner_Id = (uint) reader.GetInt32(2);
|
if (!reader.IsDBNull(2)) b.Owner_Id = (uint) reader.GetInt32(2);
|
||||||
if (!reader.IsDBNull(3)) b.Authority_Id = (uint) reader.GetInt32(3);
|
if (!reader.IsDBNull(3)) b.Authority_Id = (uint) reader.GetInt32(3);
|
||||||
if (!reader.IsDBNull(4)) b.Lock = reader.GetBoolean(4);
|
if (!reader.IsDBNull(4)) b.Port_Id = (uint) reader.GetInt32(4);
|
||||||
if (!reader.IsDBNull(5)) b.Created = reader.GetDateTime(5);
|
if (!reader.IsDBNull(5)) b.Lock = reader.GetBoolean(5);
|
||||||
if (!reader.IsDBNull(6)) b.Modified = reader.GetDateTime(6);
|
if (!reader.IsDBNull(6)) b.Created = reader.GetDateTime(6);
|
||||||
if (!reader.IsDBNull(7)) b.Deleted = reader.GetInt16(7);
|
if (!reader.IsDBNull(7)) b.Modified = reader.GetDateTime(7);
|
||||||
|
if (!reader.IsDBNull(8)) b.Deleted = reader.GetInt16(8);
|
||||||
result.Add(b);
|
result.Add(b);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -76,7 +76,7 @@ namespace brecal.model
|
|||||||
|
|
||||||
public override void SetCreate(IDbCommand cmd)
|
public override void SetCreate(IDbCommand cmd)
|
||||||
{
|
{
|
||||||
cmd.CommandText = "INSERT INTO berth (owner_id, authority_id, name, `lock`) VALUES ( @PID, @AID, @NAME, @LOCK)";
|
cmd.CommandText = "INSERT INTO berth (owner_id, authority_id, port_id, name, `lock`) VALUES ( @PID, @AID, @PO_ID, @NAME, @LOCK)";
|
||||||
this.SetParameters(cmd);
|
this.SetParameters(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ namespace brecal.model
|
|||||||
|
|
||||||
public override void SetUpdate(IDbCommand cmd)
|
public override void SetUpdate(IDbCommand cmd)
|
||||||
{
|
{
|
||||||
cmd.CommandText = "UPDATE berth SET name = @NAME, owner_id = @PID, authority_id = @AID, `lock` = @LOCK WHERE id = @ID";
|
cmd.CommandText = "UPDATE berth SET name = @NAME, owner_id = @PID, authority_id = @AID, port_id = @PO_ID, `lock` = @LOCK WHERE id = @ID";
|
||||||
this.SetParameters(cmd);
|
this.SetParameters(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,14 +109,19 @@ namespace brecal.model
|
|||||||
|
|
||||||
IDbDataParameter pid = cmd.CreateParameter();
|
IDbDataParameter pid = cmd.CreateParameter();
|
||||||
pid.ParameterName = "PID";
|
pid.ParameterName = "PID";
|
||||||
pid.Value = this.Owner_Id;
|
pid.Value = this.Owner_Id.HasValue ? this.Owner_Id.Value : DBNull.Value;
|
||||||
cmd.Parameters.Add(pid);
|
cmd.Parameters.Add(pid);
|
||||||
|
|
||||||
IDbDataParameter aid = cmd.CreateParameter();
|
IDbDataParameter aid = cmd.CreateParameter();
|
||||||
aid.ParameterName = "AID";
|
aid.ParameterName = "AID";
|
||||||
aid.Value = this.Authority_Id;
|
aid.Value = this.Authority_Id.HasValue ? this.Authority_Id.Value : DBNull.Value;
|
||||||
cmd.Parameters.Add(aid);
|
cmd.Parameters.Add(aid);
|
||||||
|
|
||||||
|
IDbDataParameter poid = cmd.CreateParameter();
|
||||||
|
poid.ParameterName = "PO_ID";
|
||||||
|
poid.Value = this.Port_Id.HasValue ? this.Port_Id.Value : DBNull.Value;
|
||||||
|
cmd.Parameters.Add(poid);
|
||||||
|
|
||||||
IDbDataParameter name = cmd.CreateParameter();
|
IDbDataParameter name = cmd.CreateParameter();
|
||||||
name.ParameterName = "NAME";
|
name.ParameterName = "NAME";
|
||||||
name.Value = this.Name;
|
name.Value = this.Name;
|
||||||
|
|||||||
@ -70,7 +70,7 @@ namespace brecal.model
|
|||||||
|
|
||||||
public static List<DbEntity> LoadElems(IDataReader reader)
|
public static List<DbEntity> LoadElems(IDataReader reader)
|
||||||
{
|
{
|
||||||
List<DbEntity> result = new List<DbEntity>();
|
List<DbEntity> result = new();
|
||||||
while (reader.Read())
|
while (reader.Read())
|
||||||
{
|
{
|
||||||
Participant p = new();
|
Participant p = new();
|
||||||
|
|||||||
115
src/brecal.model/Port.cs
Normal file
115
src/brecal.model/Port.cs
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
// Copyright (c) 2023- schick Informatik
|
||||||
|
// Description: Port entity
|
||||||
|
|
||||||
|
using System.Data;
|
||||||
|
|
||||||
|
namespace brecal.model
|
||||||
|
{
|
||||||
|
public class Port : DbEntity
|
||||||
|
{
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
public string? Name { get; set; }
|
||||||
|
|
||||||
|
public string? Locode { get; set; }
|
||||||
|
|
||||||
|
public bool IsDeleted { get; set; } = false;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region overrides
|
||||||
|
|
||||||
|
public override void SetCreate(IDbCommand cmd)
|
||||||
|
{
|
||||||
|
cmd.CommandText = "INSERT INTO port (name, locode) VALUES ( @NAME, @LOCODE)";
|
||||||
|
this.SetParameters(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetDelete(IDbCommand cmd)
|
||||||
|
{
|
||||||
|
cmd.CommandText = "UPDATE port SET deleted = 1 WHERE id = @ID";
|
||||||
|
IDataParameter idParam = cmd.CreateParameter();
|
||||||
|
idParam.ParameterName = "ID";
|
||||||
|
idParam.Value = this.Id;
|
||||||
|
cmd.Parameters.Add(idParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetUpdate(IDbCommand cmd)
|
||||||
|
{
|
||||||
|
cmd.CommandText = "UPDATE port set name = @NAME, locode = @LOCODE WHERE id = @ID";
|
||||||
|
this.SetParameters(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region public static methods
|
||||||
|
|
||||||
|
public static async Task<List<Port>> LoadAll(IDBManager manager)
|
||||||
|
{
|
||||||
|
List<DbEntity> loadResultList = await manager.Load(SetLoadQuery, LoadElems);
|
||||||
|
List<Port> result = new();
|
||||||
|
foreach (Port p in loadResultList.Cast<Port>())
|
||||||
|
result.Add(p);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetLoadQuery(IDbCommand cmd, params object?[] list)
|
||||||
|
{
|
||||||
|
cmd.CommandText = "SELECT id, name, locode, created, modified, deleted FROM port WHERE deleted = 0";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<DbEntity> LoadElems(IDataReader reader)
|
||||||
|
{
|
||||||
|
List<DbEntity> result = new();
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
Port p = new();
|
||||||
|
p.Id = (uint)reader.GetInt32(0);
|
||||||
|
if (!reader.IsDBNull(1)) p.Name = reader.GetString(1);
|
||||||
|
if (!reader.IsDBNull(2)) p.Locode = reader.GetString(2);
|
||||||
|
if (!reader.IsDBNull(3)) p.Created = reader.GetDateTime(3);
|
||||||
|
if (!reader.IsDBNull(4)) p.Modified = reader.GetDateTime(4);
|
||||||
|
if (!reader.IsDBNull(5)) p.IsDeleted = reader.GetBoolean(5);
|
||||||
|
result.Add(p);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region private methods
|
||||||
|
|
||||||
|
private void SetParameters(IDbCommand cmd)
|
||||||
|
{
|
||||||
|
IDbDataParameter name = cmd.CreateParameter();
|
||||||
|
name.ParameterName = "NAME";
|
||||||
|
name.Value = this.Name;
|
||||||
|
cmd.Parameters.Add(name);
|
||||||
|
|
||||||
|
IDbDataParameter desc = cmd.CreateParameter();
|
||||||
|
desc.ParameterName = "LOCODE";
|
||||||
|
desc.Value = this.Locode;
|
||||||
|
cmd.Parameters.Add(desc);
|
||||||
|
|
||||||
|
IDataParameter idParam = cmd.CreateParameter();
|
||||||
|
idParam.ParameterName = "ID";
|
||||||
|
idParam.Value = this.Id;
|
||||||
|
cmd.Parameters.Add(idParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region overrides
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"{Name} ({Locode})";
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
111
src/brecal.model/PortAssignment.cs
Normal file
111
src/brecal.model/PortAssignment.cs
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
// Copyright (c) 2023- schick Informatik
|
||||||
|
// Description: Participant Port Map Entity
|
||||||
|
|
||||||
|
using System.Data;
|
||||||
|
|
||||||
|
namespace brecal.model
|
||||||
|
{
|
||||||
|
public class PortAssignment : DbEntity
|
||||||
|
{
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
public int? ParticipantId { get; set; }
|
||||||
|
|
||||||
|
public int? PortId { get; set; }
|
||||||
|
|
||||||
|
public Participant? AssignedParticipant { get; set; }
|
||||||
|
|
||||||
|
public Port? AssignedPort { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region public static methods
|
||||||
|
|
||||||
|
public static async Task<List<PortAssignment>> LoadForParticipant(Participant? p, IDBManager manager)
|
||||||
|
{
|
||||||
|
List<DbEntity> loadResultList = await manager.Load(SetLoadQuery, LoadElems, args: p);
|
||||||
|
List<PortAssignment> result = new();
|
||||||
|
foreach (PortAssignment pa in loadResultList.Cast<PortAssignment>())
|
||||||
|
{
|
||||||
|
pa.AssignedParticipant = p;
|
||||||
|
result.Add(pa);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetLoadQuery(IDbCommand cmd, params object?[] args)
|
||||||
|
{
|
||||||
|
cmd.CommandText = "SELECT id, participant_id, port_id FROM participant_port_map WHERE participant_id = @PID";
|
||||||
|
if (args.Length != 1 || args[0] is not Participant)
|
||||||
|
throw new ArgumentException("loader needs single participant as argument");
|
||||||
|
IDataParameter pid = cmd.CreateParameter();
|
||||||
|
pid.ParameterName = "PID";
|
||||||
|
if (args[0] is Participant p)
|
||||||
|
pid.Value = p.Id;
|
||||||
|
cmd.Parameters.Add(pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<DbEntity> LoadElems(IDataReader reader)
|
||||||
|
{
|
||||||
|
List<DbEntity> result = new();
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
PortAssignment ra = new();
|
||||||
|
ra.Id = (uint)reader.GetInt32(0);
|
||||||
|
if (!reader.IsDBNull(1)) ra.ParticipantId = reader.GetInt32(1);
|
||||||
|
if (!reader.IsDBNull(2)) ra.PortId = reader.GetInt32(2);
|
||||||
|
result.Add(ra);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region overrides
|
||||||
|
|
||||||
|
public override void SetUpdate(IDbCommand cmd)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetCreate(IDbCommand cmd)
|
||||||
|
{
|
||||||
|
cmd.CommandText = "INSERT INTO participant_port_map (participant_id, port_id) VALUES (@PID, @PORTID)";
|
||||||
|
|
||||||
|
IDbDataParameter participantId = cmd.CreateParameter();
|
||||||
|
participantId.ParameterName = "pID";
|
||||||
|
participantId.Value = this.ParticipantId;
|
||||||
|
cmd.Parameters.Add(participantId);
|
||||||
|
|
||||||
|
IDbDataParameter portId = cmd.CreateParameter();
|
||||||
|
portId.ParameterName = "PORTID";
|
||||||
|
portId.Value = this.PortId;
|
||||||
|
cmd.Parameters.Add(portId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetDelete(IDbCommand cmd)
|
||||||
|
{
|
||||||
|
cmd.CommandText = "DELETE FROM participant_port_map WHERE id = @ID";
|
||||||
|
|
||||||
|
IDataParameter idParam = cmd.CreateParameter();
|
||||||
|
idParam.ParameterName = "ID";
|
||||||
|
idParam.Value = this.Id;
|
||||||
|
cmd.Parameters.Add(idParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
if (this.AssignedPort == null)
|
||||||
|
{
|
||||||
|
return $"{Id}: <defunct port>";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return AssignedPort.Name ?? AssignedPort.Id.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,9 +1,7 @@
|
|||||||
using System;
|
// Copyright (c) 2023- schick Informatik
|
||||||
using System.Collections.Generic;
|
// Description: Role Entity
|
||||||
|
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace brecal.model
|
namespace brecal.model
|
||||||
{
|
{
|
||||||
|
|||||||
@ -17,7 +17,7 @@ namespace brecal.mysql
|
|||||||
|
|
||||||
public async Task<List<DbEntity>> Load(QueryFunc prepareAction, LoadFunc<IDataReader> loadAction, params object?[] args)
|
public async Task<List<DbEntity>> Load(QueryFunc prepareAction, LoadFunc<IDataReader> loadAction, params object?[] args)
|
||||||
{
|
{
|
||||||
await using MySqlConnection connection = new MySqlConnection(_connectionString);
|
await using MySqlConnection connection = new(_connectionString);
|
||||||
await connection.OpenAsync();
|
await connection.OpenAsync();
|
||||||
|
|
||||||
using MySqlCommand cmd = new();
|
using MySqlCommand cmd = new();
|
||||||
@ -31,7 +31,7 @@ namespace brecal.mysql
|
|||||||
|
|
||||||
public async Task<object?> ExecuteScalar(Action<IDbCommand> prepareAction)
|
public async Task<object?> ExecuteScalar(Action<IDbCommand> prepareAction)
|
||||||
{
|
{
|
||||||
await using MySqlConnection connection = new MySqlConnection(_connectionString);
|
await using MySqlConnection connection = new(_connectionString);
|
||||||
await connection.OpenAsync();
|
await connection.OpenAsync();
|
||||||
|
|
||||||
using MySqlCommand cmd = new();
|
using MySqlCommand cmd = new();
|
||||||
|
|||||||
@ -13,6 +13,7 @@ from .api import ships
|
|||||||
from .api import login
|
from .api import login
|
||||||
from .api import user
|
from .api import user
|
||||||
from .api import history
|
from .api import history
|
||||||
|
from .api import ports
|
||||||
|
|
||||||
from BreCal.brecal_utils.file_handling import get_project_root, ensure_path
|
from BreCal.brecal_utils.file_handling import get_project_root, ensure_path
|
||||||
from BreCal.brecal_utils.test_handling import execute_test_with_pytest, execute_coverage_test
|
from BreCal.brecal_utils.test_handling import execute_test_with_pytest, execute_coverage_test
|
||||||
@ -66,6 +67,7 @@ def create_app(test_config=None, instance_path=None):
|
|||||||
app.register_blueprint(login.bp)
|
app.register_blueprint(login.bp)
|
||||||
app.register_blueprint(user.bp)
|
app.register_blueprint(user.bp)
|
||||||
app.register_blueprint(history.bp)
|
app.register_blueprint(history.bp)
|
||||||
|
app.register_blueprint(ports.bp)
|
||||||
|
|
||||||
logging.basicConfig(filename='brecal.log', level=logging.DEBUG, format='%(asctime)s | %(name)s | %(levelname)s | %(message)s')
|
logging.basicConfig(filename='brecal.log', level=logging.DEBUG, format='%(asctime)s | %(name)s | %(levelname)s | %(message)s')
|
||||||
local_db.initPool(os.path.dirname(app.instance_path))
|
local_db.initPool(os.path.dirname(app.instance_path))
|
||||||
|
|||||||
@ -3,6 +3,7 @@ from flask import Blueprint, request
|
|||||||
from webargs.flaskparser import parser
|
from webargs.flaskparser import parser
|
||||||
from .. import impl
|
from .. import impl
|
||||||
from ..services.auth_guard import auth_guard
|
from ..services.auth_guard import auth_guard
|
||||||
|
from ..services.jwt_handler import decode_jwt
|
||||||
import json
|
import json
|
||||||
from BreCal.validators.validation_error import create_dynamic_exception_response
|
from BreCal.validators.validation_error import create_dynamic_exception_response
|
||||||
|
|
||||||
@ -16,7 +17,10 @@ def GetBerths():
|
|||||||
try:
|
try:
|
||||||
if 'Authorization' in request.headers:
|
if 'Authorization' in request.headers:
|
||||||
token = request.headers.get('Authorization')
|
token = request.headers.get('Authorization')
|
||||||
return impl.berths.GetBerths(token)
|
payload = decode_jwt(token.split("Bearer ")[-1])
|
||||||
|
options = {}
|
||||||
|
options["participant_id"] = payload["participant_id"]
|
||||||
|
return impl.berths.GetBerths(options)
|
||||||
else:
|
else:
|
||||||
return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated")
|
return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated")
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import logging
|
|||||||
from flask import Blueprint, request
|
from flask import Blueprint, request
|
||||||
from .. import impl
|
from .. import impl
|
||||||
from ..services.auth_guard import auth_guard
|
from ..services.auth_guard import auth_guard
|
||||||
|
from ..services.jwt_handler import decode_jwt
|
||||||
import json
|
import json
|
||||||
from BreCal.validators.validation_error import create_dynamic_exception_response
|
from BreCal.validators.validation_error import create_dynamic_exception_response
|
||||||
|
|
||||||
@ -13,9 +14,14 @@ def GetParticipant():
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
if 'Authorization' in request.headers:
|
if 'Authorization' in request.headers:
|
||||||
token = request.headers.get('Authorization')
|
payload = decode_jwt(request.headers.get("Authorization").split("Bearer ")[-1])
|
||||||
options = {}
|
options = {}
|
||||||
options["user_id"] = request.args.get("user_id")
|
options["user_id"] = request.args.get("user_id")
|
||||||
|
if "participant_id" in payload:
|
||||||
|
options["participant_id"] = payload["participant_id"]
|
||||||
|
else:
|
||||||
|
return create_dynamic_exception_response(ex=None, status_code=403, message="not authorized")
|
||||||
|
|
||||||
return impl.participant.GetParticipant(options)
|
return impl.participant.GetParticipant(options)
|
||||||
else:
|
else:
|
||||||
return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated")
|
return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated")
|
||||||
|
|||||||
24
src/server/BreCal/api/ports.py
Normal file
24
src/server/BreCal/api/ports.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import logging
|
||||||
|
from flask import Blueprint, request
|
||||||
|
from webargs.flaskparser import parser
|
||||||
|
from .. import impl
|
||||||
|
from ..services.auth_guard import auth_guard
|
||||||
|
import json
|
||||||
|
from BreCal.validators.validation_error import create_dynamic_exception_response
|
||||||
|
|
||||||
|
bp = Blueprint('ports', __name__)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/ports', methods=['get'])
|
||||||
|
@auth_guard() # no restriction by role
|
||||||
|
def GetPorts():
|
||||||
|
|
||||||
|
try:
|
||||||
|
if 'Authorization' in request.headers:
|
||||||
|
token = request.headers.get('Authorization')
|
||||||
|
return impl.ports.GetPorts(token)
|
||||||
|
else:
|
||||||
|
return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated")
|
||||||
|
|
||||||
|
except Exception as ex:
|
||||||
|
return create_dynamic_exception_response(ex=ex, status_code=400)
|
||||||
@ -7,6 +7,7 @@ from ..services.auth_guard import auth_guard, check_jwt
|
|||||||
from BreCal.validators.input_validation import validate_posted_shipcall_data, check_if_user_is_bsmd_type
|
from BreCal.validators.input_validation import validate_posted_shipcall_data, check_if_user_is_bsmd_type
|
||||||
from BreCal.validators.input_validation_shipcall import InputValidationShipcall
|
from BreCal.validators.input_validation_shipcall import InputValidationShipcall
|
||||||
from BreCal.database.sql_handler import execute_sql_query_standalone
|
from BreCal.database.sql_handler import execute_sql_query_standalone
|
||||||
|
from BreCal.services.jwt_handler import decode_jwt
|
||||||
from BreCal.validators.validation_error import create_validation_error_response, create_werkzeug_error_response, create_dynamic_exception_response
|
from BreCal.validators.validation_error import create_validation_error_response, create_werkzeug_error_response, create_dynamic_exception_response
|
||||||
from . import verify_if_request_is_json
|
from . import verify_if_request_is_json
|
||||||
|
|
||||||
@ -32,9 +33,10 @@ def GetShipcalls():
|
|||||||
# oneline:
|
# oneline:
|
||||||
payload = decode_jwt(request.headers.get("Authorization").split("Bearer ")[-1])
|
payload = decode_jwt(request.headers.get("Authorization").split("Bearer ")[-1])
|
||||||
"""
|
"""
|
||||||
|
payload = decode_jwt(request.headers.get("Authorization").split("Bearer ")[-1])
|
||||||
options = {}
|
options = {}
|
||||||
options["participant_id"] = request.args.get("participant_id")
|
|
||||||
options["past_days"] = request.args.get("past_days", default=1, type=int)
|
options["past_days"] = request.args.get("past_days", default=1, type=int)
|
||||||
|
options["participant_id"] = payload["participant_id"]
|
||||||
|
|
||||||
return impl.shipcalls.GetShipcalls(options)
|
return impl.shipcalls.GetShipcalls(options)
|
||||||
else:
|
else:
|
||||||
@ -83,6 +85,9 @@ def PutShipcalls():
|
|||||||
# read the user data from the JWT token (set when login is performed)
|
# read the user data from the JWT token (set when login is performed)
|
||||||
user_data = check_jwt()
|
user_data = check_jwt()
|
||||||
|
|
||||||
|
if not InputValidationShipcall.exists_shipcall_by_id(loadedModel.get("id")):
|
||||||
|
return create_dynamic_exception_response(ex=None, status_code=404, message="no shipcall found with the provided id")
|
||||||
|
|
||||||
# validate the PUT shipcall data and the user's authority
|
# validate the PUT shipcall data and the user's authority
|
||||||
InputValidationShipcall.evaluate_put_data(user_data, loadedModel, content)
|
InputValidationShipcall.evaluate_put_data(user_data, loadedModel, content)
|
||||||
return impl.shipcalls.PutShipcalls(loadedModel)
|
return impl.shipcalls.PutShipcalls(loadedModel)
|
||||||
|
|||||||
@ -71,6 +71,9 @@ def PutShip():
|
|||||||
content = request.get_json(force=True)
|
content = request.get_json(force=True)
|
||||||
loadedModel = model.ShipSchema().load(data=content, many=False, partial=True, unknown=EXCLUDE)
|
loadedModel = model.ShipSchema().load(data=content, many=False, partial=True, unknown=EXCLUDE)
|
||||||
|
|
||||||
|
if not InputValidationShip.exists_ship_by_dict(model=loadedModel):
|
||||||
|
return create_dynamic_exception_response(ex=None, status_code=404, message="no ship found with the provided id")
|
||||||
|
|
||||||
# validate the request data & user permissions
|
# validate the request data & user permissions
|
||||||
InputValidationShip.evaluate_put_data(user_data, loadedModel, content)
|
InputValidationShip.evaluate_put_data(user_data, loadedModel, content)
|
||||||
return impl.ships.PutShip(loadedModel)
|
return impl.ships.PutShip(loadedModel)
|
||||||
@ -100,6 +103,10 @@ def DeleteShip():
|
|||||||
|
|
||||||
# validate the request data & user permissions
|
# validate the request data & user permissions
|
||||||
ship_id = request.args.get("id")
|
ship_id = request.args.get("id")
|
||||||
|
|
||||||
|
if not InputValidationShip.exists_ship_by_id(id=ship_id):
|
||||||
|
return create_dynamic_exception_response(ex=None, status_code=404, message="no ship found with the provided id")
|
||||||
|
|
||||||
InputValidationShip.evaluate_delete_data(user_data, ship_id)
|
InputValidationShip.evaluate_delete_data(user_data, ship_id)
|
||||||
return impl.ships.DeleteShip(options)
|
return impl.ships.DeleteShip(options)
|
||||||
|
|
||||||
|
|||||||
@ -67,6 +67,9 @@ def PutTimes():
|
|||||||
# read the user data from the JWT token (set when login is performed)
|
# read the user data from the JWT token (set when login is performed)
|
||||||
user_data = check_jwt()
|
user_data = check_jwt()
|
||||||
|
|
||||||
|
if not InputValidationTimes.exists_times_by_id(loadedModel.get("id")):
|
||||||
|
return create_dynamic_exception_response(ex=None, status_code=404, message="no times found with the provided id")
|
||||||
|
|
||||||
# validate the request
|
# validate the request
|
||||||
InputValidationTimes.evaluate_put_data(user_data, loadedModel, content)
|
InputValidationTimes.evaluate_put_data(user_data, loadedModel, content)
|
||||||
return impl.times.PutTimes(loadedModel)
|
return impl.times.PutTimes(loadedModel)
|
||||||
@ -91,6 +94,9 @@ def DeleteTimes():
|
|||||||
# read the user data from the JWT token (set when login is performed)
|
# read the user data from the JWT token (set when login is performed)
|
||||||
user_data = check_jwt()
|
user_data = check_jwt()
|
||||||
|
|
||||||
|
if not InputValidationTimes.exists_times_by_id(options["id"]):
|
||||||
|
return create_dynamic_exception_response(ex=None, status_code=404, message="no times found with the provided id")
|
||||||
|
|
||||||
# validate the request
|
# validate the request
|
||||||
InputValidationTimes.evaluate_delete_data(user_data, times_id = request.args.get("id"))
|
InputValidationTimes.evaluate_delete_data(user_data, times_id = request.args.get("id"))
|
||||||
|
|
||||||
|
|||||||
@ -94,7 +94,7 @@ class RequestCode_HTTP_403_FORBIDDEN(RequestStatusCode):
|
|||||||
|
|
||||||
def response(self, message="invalid credentials"):
|
def response(self, message="invalid credentials"):
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = message
|
result["error_field"] = message
|
||||||
return json.dumps(result)
|
return json.dumps(result)
|
||||||
|
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ class RequestCode_HTTP_404_NOT_FOUND(RequestStatusCode):
|
|||||||
|
|
||||||
def response(self, message="no such record"):
|
def response(self, message="no such record"):
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = message
|
result["error_field"] = message
|
||||||
return json.dumps(result)
|
return json.dumps(result)
|
||||||
|
|
||||||
|
|
||||||
@ -126,6 +126,6 @@ class RequestCode_HTTP_500_INTERNAL_SERVER_ERROR(RequestStatusCode):
|
|||||||
|
|
||||||
def response(self, message="credential lookup mismatch"):
|
def response(self, message="credential lookup mismatch"):
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = message
|
result["error_field"] = message
|
||||||
return json.dumps(result)
|
return json.dumps(result)
|
||||||
|
|
||||||
|
|||||||
@ -10,20 +10,38 @@ def create_sql_query_shipcall_get(options:dict)->str:
|
|||||||
options : dict. A dictionary, which must contains the 'past_days' key (int). Determines the range
|
options : dict. A dictionary, which must contains the 'past_days' key (int). Determines the range
|
||||||
by which shipcalls are filtered.
|
by which shipcalls are filtered.
|
||||||
"""
|
"""
|
||||||
query = ("SELECT s.id as id, ship_id, type, eta, voyage, etd, arrival_berth_id, departure_berth_id, tug_required, pilot_required, " +
|
if "participant_id" not in options: # if no participant_id is given, all shipcalls are selected
|
||||||
"flags, s.pier_side, bunkering, replenishing_terminal, replenishing_lock, draft, tidal_window_from, " +
|
query = ("SELECT s.id as id, ship_id, port_id, type, eta, voyage, etd, arrival_berth_id, departure_berth_id, tug_required, pilot_required, " +
|
||||||
"tidal_window_to, rain_sensitive_cargo, recommended_tugs, anchored, moored_lock, canceled, evaluation, " +
|
"flags, s.pier_side, bunkering, replenishing_terminal, replenishing_lock, draft, tidal_window_from, " +
|
||||||
"evaluation_message, evaluation_time, evaluation_notifications_sent, s.created as created, s.modified as modified, time_ref_point " +
|
"tidal_window_to, rain_sensitive_cargo, recommended_tugs, anchored, moored_lock, canceled, evaluation, " +
|
||||||
"FROM shipcall s " +
|
"evaluation_message, evaluation_time, evaluation_notifications_sent, s.created as created, s.modified as modified, time_ref_point " +
|
||||||
"LEFT JOIN times t ON t.shipcall_id = s.id AND t.participant_type = 8 " +
|
"FROM shipcall s " +
|
||||||
"WHERE " +
|
"LEFT JOIN times t ON t.shipcall_id = s.id AND t.participant_type = 8 " +
|
||||||
"(type = 1 AND " +
|
"WHERE " +
|
||||||
"((t.id IS NOT NULL AND t.eta_berth >= DATE(NOW() - INTERVAL %d DAY)) OR " +
|
"(type = 1 AND " +
|
||||||
"(eta >= DATE(NOW() - INTERVAL %d DAY)))) OR " +
|
"((t.id IS NOT NULL AND t.eta_berth >= DATE(NOW() - INTERVAL %d DAY)) OR " +
|
||||||
"((type = 2 OR type = 3) AND " +
|
"(eta >= DATE(NOW() - INTERVAL %d DAY)))) OR " +
|
||||||
"((t.id IS NOT NULL AND t.etd_berth >= DATE(NOW() - INTERVAL %d DAY)) OR " +
|
"((type = 2 OR type = 3) AND " +
|
||||||
"(etd >= DATE(NOW() - INTERVAL %d DAY)))) " +
|
"((t.id IS NOT NULL AND t.etd_berth >= DATE(NOW() - INTERVAL %d DAY)) OR " +
|
||||||
"ORDER BY eta") % (options["past_days"], options["past_days"], options["past_days"], options["past_days"])
|
"(etd >= DATE(NOW() - INTERVAL %d DAY)))) " +
|
||||||
|
"ORDER BY eta") % (options["past_days"], options["past_days"], options["past_days"], options["past_days"])
|
||||||
|
else:
|
||||||
|
query = ("SELECT s.id as id, ship_id, port_id, type, eta, voyage, etd, arrival_berth_id, departure_berth_id, tug_required, pilot_required, " +
|
||||||
|
"flags, s.pier_side, bunkering, replenishing_terminal, replenishing_lock, draft, tidal_window_from, " +
|
||||||
|
"tidal_window_to, rain_sensitive_cargo, recommended_tugs, anchored, moored_lock, canceled, evaluation, " +
|
||||||
|
"evaluation_message, evaluation_time, evaluation_notifications_sent, s.created as created, s.modified as modified, time_ref_point " +
|
||||||
|
"FROM shipcall s " +
|
||||||
|
"LEFT JOIN times t ON t.shipcall_id = s.id AND t.participant_type = 8 " +
|
||||||
|
"WHERE " +
|
||||||
|
"port_id in (SELECT port_id FROM participant_port_map WHERE participant_id = %d)" +
|
||||||
|
" AND (" +
|
||||||
|
"(type = 1 AND " +
|
||||||
|
"((t.id IS NOT NULL AND t.eta_berth >= DATE(NOW() - INTERVAL %d DAY)) OR " +
|
||||||
|
"(eta >= DATE(NOW() - INTERVAL %d DAY)))) OR " +
|
||||||
|
"((type = 2 OR type = 3) AND " +
|
||||||
|
"((t.id IS NOT NULL AND t.etd_berth >= DATE(NOW() - INTERVAL %d DAY)) OR " +
|
||||||
|
"(etd >= DATE(NOW() - INTERVAL %d DAY))))) " +
|
||||||
|
"ORDER BY eta") % (options["participant_id"], options["past_days"], options["past_days"], options["past_days"], options["past_days"])
|
||||||
|
|
||||||
return query
|
return query
|
||||||
|
|
||||||
|
|||||||
@ -4,19 +4,33 @@ import datetime
|
|||||||
def get_user_data_for_id(user_id:int, expiration_time:int=90):
|
def get_user_data_for_id(user_id:int, expiration_time:int=90):
|
||||||
"""debugging function, which is useful to pull user_data from the database, which may be used to create stub data and unit tests"""
|
"""debugging function, which is useful to pull user_data from the database, which may be used to create stub data and unit tests"""
|
||||||
query = "SELECT * FROM user where id = ?id?"
|
query = "SELECT * FROM user where id = ?id?"
|
||||||
pdata = execute_sql_query_standalone(query=query, param={"id":user_id})
|
pdata = execute_sql_query_standalone(query=query, param={"id":user_id}, command_type="single_or_none")
|
||||||
pdata = pdata[0] if len(pdata)>0 else None
|
|
||||||
assert pdata is not None, f"could not find user with id {user_id}"
|
assert pdata is not None, f"could not find user with id {user_id}"
|
||||||
|
|
||||||
user_data = {k:v for k,v in pdata.items() if k in ['id','participant_id','first_name','last_name','user_name','user_phone','user_email']}
|
user_data = {k:v for k,v in pdata.items() if k in ['id','participant_id','first_name','last_name','user_name','user_phone','user_email']}
|
||||||
user_data["exp"] = (datetime.datetime.now()+datetime.timedelta(minutes=expiration_time)).timestamp()
|
user_data["exp"] = (datetime.datetime.now()+datetime.timedelta(minutes=expiration_time)).timestamp()
|
||||||
return user_data
|
return user_data
|
||||||
|
|
||||||
|
|
||||||
def get_times_data_for_id(times_id:int):
|
def get_times_data_for_id(times_id:int):
|
||||||
"""helper function to load previous times data from the database"""
|
"""helper function to load previous times data from the database"""
|
||||||
query = "SELECT * FROM times where id = ?id?"
|
query = "SELECT * FROM times where id = ?id?"
|
||||||
pdata = execute_sql_query_standalone(query=query, param={"id":times_id})
|
pdata = execute_sql_query_standalone(query=query, param={"id":times_id}, command_type="single_or_none")
|
||||||
pdata = pdata[0] if len(pdata)>0 else None
|
return pdata
|
||||||
assert pdata is not None, f"could not find times with id {times_id}"
|
|
||||||
|
def get_ship_data_for_id(ship_id:int):
|
||||||
|
"""helper function to load previous ship data from the database"""
|
||||||
|
query = "SELECT * FROM ship where id = ?id?"
|
||||||
|
pdata = execute_sql_query_standalone(query=query, param={"id":ship_id}, command_type="single_or_none")
|
||||||
|
return pdata
|
||||||
|
|
||||||
|
def get_shipcall_data_for_id(shipcall_id:int):
|
||||||
|
"""helper function to load previous shipcall data from the database"""
|
||||||
|
query = "SELECT * FROM shipcall where id = ?id?"
|
||||||
|
pdata = execute_sql_query_standalone(query=query, param={"id":shipcall_id}, command_type="single_or_none")
|
||||||
|
return pdata
|
||||||
|
|
||||||
|
def get_port_ids_for_participant_id(participant_id:int):
|
||||||
|
"""helper function to load all port ids for a participant"""
|
||||||
|
query = "SELECT port_id FROM participant_port_map where participant_id = ?participant_id?"
|
||||||
|
pdata = execute_sql_query_standalone(query=query, param={"participant_id":participant_id})
|
||||||
return pdata
|
return pdata
|
||||||
@ -7,3 +7,4 @@ from . import ships
|
|||||||
from . import login
|
from . import login
|
||||||
from . import user
|
from . import user
|
||||||
from . import history
|
from . import history
|
||||||
|
from . import ports
|
||||||
@ -4,9 +4,8 @@ import pydapper
|
|||||||
|
|
||||||
from ..schemas import model
|
from ..schemas import model
|
||||||
from .. import local_db
|
from .. import local_db
|
||||||
from BreCal.database.sql_queries import SQLQuery
|
|
||||||
|
|
||||||
def GetBerths(token):
|
def GetBerths(options):
|
||||||
"""
|
"""
|
||||||
No parameters, gets all entries
|
No parameters, gets all entries
|
||||||
"""
|
"""
|
||||||
@ -14,16 +13,25 @@ def GetBerths(token):
|
|||||||
try:
|
try:
|
||||||
pooledConnection = local_db.getPoolConnection()
|
pooledConnection = local_db.getPoolConnection()
|
||||||
commands = pydapper.using(pooledConnection)
|
commands = pydapper.using(pooledConnection)
|
||||||
# query = SQLQuery.get_berth()
|
|
||||||
# data = commands.query(query, model=model.Berth)
|
# only load berths to ports that the participant is assigned to
|
||||||
data = commands.query("SELECT id, name, `lock`, owner_id, authority_id, created, modified, deleted FROM berth WHERE deleted = 0 ORDER BY name", model=model.Berth)
|
if "participant_id" in options:
|
||||||
|
query = ("SELECT id, name, `lock`, owner_id, port_id, authority_id, created, modified, deleted FROM berth WHERE " +
|
||||||
|
"deleted = 0 AND + "
|
||||||
|
"port_id IN (SELECT port_id FROM participant_port_map WHERE participant_id = %d) " +
|
||||||
|
"ORDER BY name") % (options["participant_id"])
|
||||||
|
else:
|
||||||
|
query = ("SELECT id, name, `lock`, owner_id, port_id, authority_id, created, modified, deleted FROM berth WHERE " +
|
||||||
|
"deleted = 0 ORDER BY name")
|
||||||
|
|
||||||
|
data = commands.query(query, model=model.Berth)
|
||||||
return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logging.error(ex)
|
logging.error(ex)
|
||||||
print(ex)
|
print(ex)
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = "call failed"
|
result["error_field"] = "call failed"
|
||||||
return json.dumps(result), 500
|
return json.dumps(result), 500
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
|
|||||||
@ -35,7 +35,7 @@ def GetHistory(options):
|
|||||||
logging.error(ex)
|
logging.error(ex)
|
||||||
print(ex)
|
print(ex)
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = "call failed"
|
result["error_field"] = "call failed"
|
||||||
return json.dumps("call failed"), 500
|
return json.dumps("call failed"), 500
|
||||||
|
|
||||||
return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|||||||
@ -39,18 +39,19 @@ def GetUser(options):
|
|||||||
|
|
||||||
if len(data) > 1:
|
if len(data) > 1:
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = "credential lookup mismatch"
|
result["error_field"] = "credential lookup mismatch"
|
||||||
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = "invalid credentials"
|
result["error_field"] = "invalid credentials"
|
||||||
return json.dumps(result), 403, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps(result), 403, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logging.error(ex)
|
logging.error(ex)
|
||||||
print(ex)
|
print(ex)
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = "call failed: " + str(ex)
|
result["error_field"] = "call failed"
|
||||||
|
result["error_description"] = str(ex)
|
||||||
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
|
|||||||
@ -27,7 +27,7 @@ def GetNotifications(options):
|
|||||||
logging.error(ex)
|
logging.error(ex)
|
||||||
print(ex)
|
print(ex)
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = "call failed"
|
result["error_field"] = "call failed"
|
||||||
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|
||||||
return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|||||||
@ -10,7 +10,6 @@ def GetParticipant(options):
|
|||||||
"""
|
"""
|
||||||
:param options: A dictionary containing all the paramters for the Operations
|
:param options: A dictionary containing all the paramters for the Operations
|
||||||
options["user_id"]: **Id of user**. *Example: 2*. User id returned by login call.
|
options["user_id"]: **Id of user**. *Example: 2*. User id returned by login call.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -18,10 +17,39 @@ def GetParticipant(options):
|
|||||||
commands = pydapper.using(pooledConnection)
|
commands = pydapper.using(pooledConnection)
|
||||||
if "user_id" in options and options["user_id"]:
|
if "user_id" in options and options["user_id"]:
|
||||||
# query = SQLQuery.get_participant_by_user_id()
|
# query = SQLQuery.get_participant_by_user_id()
|
||||||
data = commands.query("SELECT p.id as id, p.name as name, p.street as street, p.postal_code as postal_code, p.city as city, p.type as type, p.flags as flags, p.created as created, p.modified as modified, p.deleted as deleted FROM participant p INNER JOIN user u WHERE u.participant_id = p.id and u.id = ?userid?", model=model.Participant, param={"userid" : options["user_id"]})
|
query = ("SELECT p.id as id, p.name as name, p.street as street, p.postal_code as postal_code, p.city as city, p.type as type, p.flags as flags, " +
|
||||||
|
"p.created as created, p.modified as modified, p.deleted as deleted FROM participant p " +
|
||||||
|
"INNER JOIN user u WHERE u.participant_id = p.id and u.id = %s") % options["user_id"]
|
||||||
|
data = commands.query(query, model=model.Participant)
|
||||||
|
for participant in data:
|
||||||
|
port_query = "SELECT port_id FROM participant_port_map WHERE participant_id=?id?"
|
||||||
|
for record in commands.query(port_query, model=model.Port_Assignment, param={"id" : participant.id}, buffered=False):
|
||||||
|
pa = model.Port_Assignment(record.port_id)
|
||||||
|
participant.ports.append(pa.port_id)
|
||||||
else:
|
else:
|
||||||
# query = SQLQuery.get_participants()
|
# query = SQLQuery.get_participants()
|
||||||
data = commands.query("SELECT id, name, street, postal_code, city, type, flags, created, modified, deleted FROM participant p ORDER BY p.name", model=model.Participant)
|
if "participant_id" in options:
|
||||||
|
# list only participants that are assigned to the same ports than participant of caller
|
||||||
|
query = ("SELECT p.id as id, name, street, postal_code, city, type, flags, p.created, p.modified, p.deleted " +
|
||||||
|
"FROM participant p " +
|
||||||
|
"JOIN participant_port_map ON p.id = participant_port_map.participant_id " +
|
||||||
|
"WHERE participant_port_map.port_id IN " +
|
||||||
|
"(SELECT port_id FROM participant_port_map where participant_id = %s) " +
|
||||||
|
"GROUP BY id " +
|
||||||
|
"ORDER BY p.name") % options["participant_id"]
|
||||||
|
else:
|
||||||
|
query = ("SELECT p.id as id, name, street, postal_code, city, type, flags, p.created, p.modified, p.deleted " +
|
||||||
|
"FROM participant p " +
|
||||||
|
"JOIN participant_port_map ON p.id = participant_port_map.participant_id " +
|
||||||
|
"GROUP BY id " +
|
||||||
|
"ORDER BY p.name")
|
||||||
|
|
||||||
|
data = commands.query(query, model=model.Participant)
|
||||||
|
for participant in data:
|
||||||
|
port_query = "SELECT port_id FROM participant_port_map WHERE participant_id=?id?"
|
||||||
|
for record in commands.query(port_query, model=model.Port_Assignment, param={"id" : participant.id}, buffered=False):
|
||||||
|
pa = model.Port_Assignment(record.port_id)
|
||||||
|
participant.ports.append(pa.port_id)
|
||||||
|
|
||||||
return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|
||||||
@ -29,7 +57,7 @@ def GetParticipant(options):
|
|||||||
logging.error(ex)
|
logging.error(ex)
|
||||||
print(ex)
|
print(ex)
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = "call failed"
|
result["error_field"] = "call failed"
|
||||||
return json.dumps("call failed"), 500
|
return json.dumps("call failed"), 500
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
|
|||||||
33
src/server/BreCal/impl/ports.py
Normal file
33
src/server/BreCal/impl/ports.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import json
|
||||||
|
import logging
|
||||||
|
import pydapper
|
||||||
|
|
||||||
|
from ..schemas import model
|
||||||
|
from .. import local_db
|
||||||
|
from BreCal.database.sql_queries import SQLQuery
|
||||||
|
|
||||||
|
def GetPorts(token):
|
||||||
|
"""
|
||||||
|
No parameters, gets all entries
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
pooledConnection = local_db.getPoolConnection()
|
||||||
|
commands = pydapper.using(pooledConnection)
|
||||||
|
data = commands.query("SELECT id, name, locode, created, modified, deleted FROM port ORDER BY name", model=model.Port)
|
||||||
|
return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|
||||||
|
except Exception as ex:
|
||||||
|
logging.error(ex)
|
||||||
|
print(ex)
|
||||||
|
result = {}
|
||||||
|
result["error_field"] = "call failed"
|
||||||
|
return json.dumps(result), 500
|
||||||
|
|
||||||
|
finally:
|
||||||
|
if pooledConnection is not None:
|
||||||
|
pooledConnection.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ def GetShipcalls(options):
|
|||||||
logging.error(ex)
|
logging.error(ex)
|
||||||
print(ex)
|
print(ex)
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = "call failed"
|
result["error_field"] = "call failed"
|
||||||
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
@ -160,7 +160,7 @@ def PostShipcalls(schemaModel):
|
|||||||
logging.error(ex)
|
logging.error(ex)
|
||||||
print(ex)
|
print(ex)
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = "call failed"
|
result["error_field"] = "call failed"
|
||||||
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
@ -271,7 +271,7 @@ def PutShipcalls(schemaModel):
|
|||||||
logging.error(ex)
|
logging.error(ex)
|
||||||
print(ex)
|
print(ex)
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = "call failed"
|
result["error_field"] = "call failed"
|
||||||
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
|
|||||||
@ -25,7 +25,7 @@ def GetShips(token):
|
|||||||
logging.error(ex)
|
logging.error(ex)
|
||||||
print(ex)
|
print(ex)
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = "call failed"
|
result["error_field"] = "call failed"
|
||||||
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
@ -91,7 +91,7 @@ def PostShip(schemaModel):
|
|||||||
logging.error(ex)
|
logging.error(ex)
|
||||||
print(ex)
|
print(ex)
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = "call failed"
|
result["error_field"] = "call failed"
|
||||||
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ def PutShip(schemaModel):
|
|||||||
logging.error(ex)
|
logging.error(ex)
|
||||||
print(ex)
|
print(ex)
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = "call failed"
|
result["error_field"] = "call failed"
|
||||||
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|
||||||
|
|
||||||
@ -157,12 +157,12 @@ def DeleteShip(options):
|
|||||||
return json.dumps({"id" : options["id"]}), 200, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps({"id" : options["id"]}), 200, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = "no such record"
|
result["error_field"] = "no such record"
|
||||||
return json.dumps(result), 404, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps(result), 404, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logging.error(ex)
|
logging.error(ex)
|
||||||
print(ex)
|
print(ex)
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = "call failed"
|
result["error_field"] = "call failed"
|
||||||
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
@ -35,7 +35,7 @@ def GetTimes(options):
|
|||||||
logging.error(ex)
|
logging.error(ex)
|
||||||
print(ex)
|
print(ex)
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = "call failed"
|
result["error_field"] = "call failed"
|
||||||
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|
||||||
return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
@ -104,7 +104,7 @@ def PostTimes(schemaModel):
|
|||||||
logging.error(ex)
|
logging.error(ex)
|
||||||
print(ex)
|
print(ex)
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = "call failed"
|
result["error_field"] = "call failed"
|
||||||
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
@ -164,7 +164,7 @@ def PutTimes(schemaModel):
|
|||||||
logging.error(ex)
|
logging.error(ex)
|
||||||
print(ex)
|
print(ex)
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = "call failed"
|
result["error_field"] = "call failed"
|
||||||
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
@ -195,14 +195,14 @@ def DeleteTimes(options):
|
|||||||
return json.dumps({"id" : options["id"]}), 200, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps({"id" : options["id"]}), 200, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = "no such record"
|
result["error_field"] = "no such record"
|
||||||
return json.dumps(result), 404, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps(result), 404, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logging.error(ex)
|
logging.error(ex)
|
||||||
print(ex)
|
print(ex)
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = "call failed"
|
result["error_field"] = "call failed"
|
||||||
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
|
|||||||
@ -63,7 +63,7 @@ def PutUser(schemaModel):
|
|||||||
commands.execute(query, param={"password_hash" : password_hash, "id" : schemaModel["id"]})
|
commands.execute(query, param={"password_hash" : password_hash, "id" : schemaModel["id"]})
|
||||||
else:
|
else:
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = "old password invalid"
|
result["error_field"] = "old password invalid"
|
||||||
return json.dumps(result), 400, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps(result), 400, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|
||||||
return json.dumps({"id" : schemaModel["id"]}), 200
|
return json.dumps({"id" : schemaModel["id"]}), 200
|
||||||
@ -72,7 +72,7 @@ def PutUser(schemaModel):
|
|||||||
logging.error(ex)
|
logging.error(ex)
|
||||||
print(ex)
|
print(ex)
|
||||||
result = {}
|
result = {}
|
||||||
result["message"] = "call failed"
|
result["error_field"] = "call failed"
|
||||||
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
|
|||||||
@ -29,6 +29,16 @@ class Berth(Schema):
|
|||||||
lock: bool
|
lock: bool
|
||||||
owner_id: int
|
owner_id: int
|
||||||
authority_id: int
|
authority_id: int
|
||||||
|
port_id: int
|
||||||
|
created: datetime
|
||||||
|
modified: datetime
|
||||||
|
deleted: bool
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Port(Schema):
|
||||||
|
id: int
|
||||||
|
name: str
|
||||||
|
locode: str
|
||||||
created: datetime
|
created: datetime
|
||||||
modified: datetime
|
modified: datetime
|
||||||
deleted: bool
|
deleted: bool
|
||||||
@ -168,6 +178,7 @@ class Participant(Schema):
|
|||||||
created: datetime
|
created: datetime
|
||||||
modified: datetime
|
modified: datetime
|
||||||
deleted: bool
|
deleted: bool
|
||||||
|
ports: List[int] = field(default_factory=list)
|
||||||
|
|
||||||
@validates("type")
|
@validates("type")
|
||||||
def validate_type(self, value):
|
def validate_type(self, value):
|
||||||
@ -205,6 +216,7 @@ class ShipcallSchema(Schema):
|
|||||||
|
|
||||||
id = fields.Integer(required=True)
|
id = fields.Integer(required=True)
|
||||||
ship_id = fields.Integer(required=True)
|
ship_id = fields.Integer(required=True)
|
||||||
|
port_id = fields.Integer(required=True)
|
||||||
type = fields.Enum(ShipcallType, default=ShipcallType.undefined)
|
type = fields.Enum(ShipcallType, default=ShipcallType.undefined)
|
||||||
eta = fields.DateTime(required=False, allow_none=True)
|
eta = fields.DateTime(required=False, allow_none=True)
|
||||||
voyage = fields.String(allow_none=True, required=False, validate=[validate.Length(max=16)])
|
voyage = fields.String(allow_none=True, required=False, validate=[validate.Length(max=16)])
|
||||||
@ -269,6 +281,16 @@ class Participant_Assignment:
|
|||||||
def to_json(self):
|
def to_json(self):
|
||||||
return self.__dict__
|
return self.__dict__
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Port_Assignment:
|
||||||
|
def __init__(self, port_id):
|
||||||
|
self.port_id = port_id
|
||||||
|
pass
|
||||||
|
|
||||||
|
port_id: int
|
||||||
|
|
||||||
|
def to_json(self):
|
||||||
|
return self.__dict__
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Shipcall:
|
class Shipcall:
|
||||||
@ -301,6 +323,7 @@ class Shipcall:
|
|||||||
evaluation_time: datetime
|
evaluation_time: datetime
|
||||||
evaluation_notifications_sent: bool
|
evaluation_notifications_sent: bool
|
||||||
time_ref_point: int
|
time_ref_point: int
|
||||||
|
port_id: int
|
||||||
created: datetime
|
created: datetime
|
||||||
modified: datetime
|
modified: datetime
|
||||||
participants: List[Participant_Assignment] = field(default_factory=list)
|
participants: List[Participant_Assignment] = field(default_factory=list)
|
||||||
@ -335,6 +358,7 @@ class Shipcall:
|
|||||||
"evaluation_time": self.evaluation_time.isoformat() if self.evaluation_time else "",
|
"evaluation_time": self.evaluation_time.isoformat() if self.evaluation_time else "",
|
||||||
"evaluation_notifications_sent": self.evaluation_notifications_sent,
|
"evaluation_notifications_sent": self.evaluation_notifications_sent,
|
||||||
"time_ref_point": self.time_ref_point,
|
"time_ref_point": self.time_ref_point,
|
||||||
|
"port_id": self.port_id,
|
||||||
"created": self.created.isoformat() if self.created else "",
|
"created": self.created.isoformat() if self.created else "",
|
||||||
"modified": self.modified.isoformat() if self.modified else "",
|
"modified": self.modified.isoformat() if self.modified else "",
|
||||||
"participants": [participant.__dict__ for participant in self.participants]
|
"participants": [participant.__dict__ for participant in self.participants]
|
||||||
@ -343,8 +367,8 @@ class Shipcall:
|
|||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_query_row(self, id, ship_id, type, eta, voyage, etd, arrival_berth_id, departure_berth_id, tug_required, pilot_required, flags, pier_side, bunkering, replenishing_terminal, replenishing_lock, draft, tidal_window_from, tidal_window_to, rain_sensitive_cargo, recommended_tugs, anchored, moored_lock, canceled, evaluation, evaluation_message, evaluation_time, evaluation_notifications_sent, time_ref_point, created, modified):
|
def from_query_row(self, id, ship_id, type, eta, voyage, etd, arrival_berth_id, departure_berth_id, tug_required, pilot_required, flags, pier_side, bunkering, replenishing_terminal, replenishing_lock, draft, tidal_window_from, tidal_window_to, rain_sensitive_cargo, recommended_tugs, anchored, moored_lock, canceled, evaluation, evaluation_message, evaluation_time, evaluation_notifications_sent, time_ref_point, port_id, created, modified):
|
||||||
return self(id, ship_id, ShipcallType(type), eta, voyage, etd, arrival_berth_id, departure_berth_id, tug_required, pilot_required, flags, pier_side, bunkering, replenishing_terminal, replenishing_lock, draft, tidal_window_from, tidal_window_to, rain_sensitive_cargo, recommended_tugs, anchored, moored_lock, canceled, EvaluationType(evaluation), evaluation_message, evaluation_time, evaluation_notifications_sent, time_ref_point, created, modified)
|
return self(id, ship_id, ShipcallType(type), eta, voyage, etd, arrival_berth_id, departure_berth_id, tug_required, pilot_required, flags, pier_side, bunkering, replenishing_terminal, replenishing_lock, draft, tidal_window_from, tidal_window_to, rain_sensitive_cargo, recommended_tugs, anchored, moored_lock, canceled, EvaluationType(evaluation), evaluation_message, evaluation_time, evaluation_notifications_sent, time_ref_point, port_id, created, modified)
|
||||||
|
|
||||||
class ShipcallId(Schema):
|
class ShipcallId(Schema):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@ -25,9 +25,9 @@ def auth_guard(role=None):
|
|||||||
try:
|
try:
|
||||||
user_data = check_jwt()
|
user_data = check_jwt()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return json.dumps({"message" : f'{e}', "status": 401}), 401
|
return json.dumps({"error_field" : f'{e}', "status": 401}), 401
|
||||||
if role and role not in user_data['roles']:
|
if role and role not in user_data['roles']:
|
||||||
return json.dumps({"message": 'Authorization required.', "status" : 403}), 403
|
return json.dumps({"error_field": 'Authorization required.', "status" : 403}), 403
|
||||||
# get on to original route
|
# get on to original route
|
||||||
return route_function(*args, **kwargs)
|
return route_function(*args, **kwargs)
|
||||||
decorated_function.__name__ = route_function.__name__
|
decorated_function.__name__ = route_function.__name__
|
||||||
|
|||||||
@ -8,6 +8,7 @@ from string import ascii_letters, digits
|
|||||||
from BreCal.schemas.model import Ship, Shipcall, Berth, User, Participant, ShipcallType
|
from BreCal.schemas.model import Ship, Shipcall, Berth, User, Participant, ShipcallType
|
||||||
from BreCal.database.sql_handler import execute_sql_query_standalone
|
from BreCal.database.sql_handler import execute_sql_query_standalone
|
||||||
from BreCal.database.sql_queries import SQLQuery
|
from BreCal.database.sql_queries import SQLQuery
|
||||||
|
from BreCal.database.sql_utils import get_ship_data_for_id
|
||||||
from BreCal.impl.participant import GetParticipant
|
from BreCal.impl.participant import GetParticipant
|
||||||
from BreCal.impl.ships import GetShips
|
from BreCal.impl.ships import GetShips
|
||||||
from BreCal.impl.berths import GetBerths
|
from BreCal.impl.berths import GetBerths
|
||||||
@ -17,6 +18,7 @@ from BreCal.validators.input_validation_utils import check_if_user_is_bsmd_type,
|
|||||||
from BreCal.database.sql_handler import execute_sql_query_standalone
|
from BreCal.database.sql_handler import execute_sql_query_standalone
|
||||||
from BreCal.validators.validation_base_utils import check_if_int_is_valid_flag
|
from BreCal.validators.validation_base_utils import check_if_int_is_valid_flag
|
||||||
from BreCal.validators.validation_base_utils import check_if_string_has_special_characters
|
from BreCal.validators.validation_base_utils import check_if_string_has_special_characters
|
||||||
|
|
||||||
import werkzeug
|
import werkzeug
|
||||||
|
|
||||||
class InputValidationShip():
|
class InputValidationShip():
|
||||||
@ -32,6 +34,17 @@ class InputValidationShip():
|
|||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def exists_ship_by_dict(model:dict):
|
||||||
|
ship_id = model.get("id")
|
||||||
|
if(ship_id is not None):
|
||||||
|
return get_ship_data_for_id(ship_id) is not None
|
||||||
|
return False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def exists_ship_by_id(id:int):
|
||||||
|
return get_ship_data_for_id(id) is not None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def evaluate_post_data(user_data:dict, loadedModel:dict, content:dict):
|
def evaluate_post_data(user_data:dict, loadedModel:dict, content:dict):
|
||||||
# 1.) Only users of type BSMD are allowed to POST
|
# 1.) Only users of type BSMD are allowed to POST
|
||||||
|
|||||||
@ -11,6 +11,7 @@ from BreCal.impl.ships import GetShips
|
|||||||
from BreCal.impl.berths import GetBerths
|
from BreCal.impl.berths import GetBerths
|
||||||
|
|
||||||
from BreCal.database.enums import ParticipantType, ParticipantFlag
|
from BreCal.database.enums import ParticipantType, ParticipantFlag
|
||||||
|
from BreCal.database.sql_utils import get_shipcall_data_for_id
|
||||||
from BreCal.validators.input_validation_utils import check_if_user_is_bsmd_type, check_if_ship_id_is_valid, check_if_berth_id_is_valid, check_if_participant_ids_are_valid, check_if_participant_ids_and_types_are_valid, get_shipcall_id_dictionary, get_participant_type_from_user_data
|
from BreCal.validators.input_validation_utils import check_if_user_is_bsmd_type, check_if_ship_id_is_valid, check_if_berth_id_is_valid, check_if_participant_ids_are_valid, check_if_participant_ids_and_types_are_valid, get_shipcall_id_dictionary, get_participant_type_from_user_data
|
||||||
from BreCal.database.sql_handler import get_assigned_participant_of_type
|
from BreCal.database.sql_handler import get_assigned_participant_of_type
|
||||||
from BreCal.database.sql_handler import execute_sql_query_standalone
|
from BreCal.database.sql_handler import execute_sql_query_standalone
|
||||||
@ -98,6 +99,10 @@ class InputValidationShipcall():
|
|||||||
InputValidationShipcall.check_shipcall_is_canceled(loadedModel, content)
|
InputValidationShipcall.check_shipcall_is_canceled(loadedModel, content)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def exists_shipcall_by_id(id:int):
|
||||||
|
return get_shipcall_data_for_id(id) is not None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def check_shipcall_values(loadedModel:dict, content:dict, forbidden_keys:list=["evaluation", "evaluation_message"], is_put_data:bool=False):
|
def check_shipcall_values(loadedModel:dict, content:dict, forbidden_keys:list=["evaluation", "evaluation_message"], is_put_data:bool=False):
|
||||||
"""
|
"""
|
||||||
@ -235,21 +240,22 @@ class InputValidationShipcall():
|
|||||||
ship_id = loadedModel.get("ship_id", None)
|
ship_id = loadedModel.get("ship_id", None)
|
||||||
arrival_berth_id = loadedModel.get("arrival_berth_id", None)
|
arrival_berth_id = loadedModel.get("arrival_berth_id", None)
|
||||||
departure_berth_id = loadedModel.get("departure_berth_id", None)
|
departure_berth_id = loadedModel.get("departure_berth_id", None)
|
||||||
|
port_id = loadedModel.get("port_id", None)
|
||||||
participants = loadedModel.get("participants",[])
|
participants = loadedModel.get("participants",[])
|
||||||
|
|
||||||
valid_ship_id = check_if_ship_id_is_valid(ship_id=ship_id)
|
valid_ship_id = check_if_ship_id_is_valid(ship_id=ship_id)
|
||||||
if not valid_ship_id:
|
if not valid_ship_id:
|
||||||
raise ValidationError({"ship_id":f"provided an invalid ship id, which is not found in the database: {ship_id}"})
|
raise ValidationError({"ship_id":f"provided an invalid ship id, which is not found in the database: {ship_id}"})
|
||||||
|
|
||||||
valid_arrival_berth_id = check_if_berth_id_is_valid(berth_id=arrival_berth_id)
|
valid_arrival_berth_id = check_if_berth_id_is_valid(berth_id=arrival_berth_id, port_id=port_id)
|
||||||
if not valid_arrival_berth_id:
|
if not valid_arrival_berth_id:
|
||||||
raise ValidationError({"arrival_berth_id":f"provided an invalid arrival berth id, which is not found in the database: {arrival_berth_id}"})
|
raise ValidationError({"arrival_berth_id":f"provided an invalid arrival berth id, which is not found in the database: {arrival_berth_id}, or the berth is not assigned to the port: {port_id}"})
|
||||||
|
|
||||||
valid_departure_berth_id = check_if_berth_id_is_valid(berth_id=departure_berth_id)
|
valid_departure_berth_id = check_if_berth_id_is_valid(berth_id=departure_berth_id, port_id=port_id)
|
||||||
if not valid_departure_berth_id:
|
if not valid_departure_berth_id:
|
||||||
raise ValidationError({"departure_berth_id":f"provided an invalid departure berth id, which is not found in the database: {departure_berth_id}"})
|
raise ValidationError({"departure_berth_id":f"provided an invalid departure berth id, which is not found in the database: {departure_berth_id}, or the berth is not assigned to the port: {port_id}"})
|
||||||
|
|
||||||
valid_participant_ids = check_if_participant_ids_are_valid(participants=participants)
|
valid_participant_ids = check_if_participant_ids_are_valid(participants=participants, port_id=port_id)
|
||||||
if not valid_participant_ids:
|
if not valid_participant_ids:
|
||||||
raise ValidationError({"participants":f"one of the provided participant ids is invalid. Could not find one of these in the database: {participants}"})
|
raise ValidationError({"participants":f"one of the provided participant ids is invalid. Could not find one of these in the database: {participants}"})
|
||||||
|
|
||||||
@ -332,7 +338,7 @@ class InputValidationShipcall():
|
|||||||
def check_times_are_in_future(loadedModel:dict, content:dict, existing_shipcall:object):
|
def check_times_are_in_future(loadedModel:dict, content:dict, existing_shipcall:object):
|
||||||
"""
|
"""
|
||||||
Dates should be in the future. Depending on the ShipcallType, specific values should be checked
|
Dates should be in the future. Depending on the ShipcallType, specific values should be checked
|
||||||
Performs datetime checks in the loadedModel (datetime.datetime objects).
|
Perfornms datetime checks in the loadedModel (datetime.datetime objects).
|
||||||
"""
|
"""
|
||||||
# obtain the current datetime to check, whether the provided values are after ref time
|
# obtain the current datetime to check, whether the provided values are after ref time
|
||||||
time_ref = datetime.datetime.now() - datetime.timedelta(days=1)
|
time_ref = datetime.datetime.now() - datetime.timedelta(days=1)
|
||||||
@ -445,15 +451,16 @@ class InputValidationShipcall():
|
|||||||
def check_tidal_window_in_future(type_, time_ref, tidal_window_from, tidal_window_to):
|
def check_tidal_window_in_future(type_, time_ref, tidal_window_from, tidal_window_to):
|
||||||
|
|
||||||
time_in_a_year = datetime.datetime.now().replace(datetime.datetime.now().year + 1)
|
time_in_a_year = datetime.datetime.now().replace(datetime.datetime.now().year + 1)
|
||||||
|
|
||||||
if tidal_window_to is not None:
|
if tidal_window_to is not None:
|
||||||
if not tidal_window_to >= time_ref:
|
if not tidal_window_to >= time_ref:
|
||||||
raise ValidationError({"tidal_window_to":f"'tidal_window_to' is too far in the past. Incorrect datetime provided."})
|
raise ValidationError({"tidal_window_to":f"'tidal_window_to' must be in the future. Incorrect datetime provided."})
|
||||||
if tidal_window_to > time_in_a_year:
|
if tidal_window_to > time_in_a_year:
|
||||||
raise ValidationError({"tidal_window_to":f"'tidal_window_to' is more than a year in the future. Found: {tidal_window_to}."})
|
raise ValidationError({"tidal_window_to":f"'tidal_window_to' is more than a year in the future. Found: {tidal_window_to}."})
|
||||||
|
|
||||||
if tidal_window_from is not None:
|
if tidal_window_from is not None:
|
||||||
if not tidal_window_from >= time_ref:
|
if not tidal_window_from >= time_ref:
|
||||||
raise ValidationError({"tidal_window_from":f"'tidal_window_from' is too far in the past. Incorrect datetime provided."})
|
raise ValidationError({"tidal_window_from":f"'tidal_window_from' must be in the future. Incorrect datetime provided."})
|
||||||
if tidal_window_from > time_in_a_year:
|
if tidal_window_from > time_in_a_year:
|
||||||
raise ValidationError({"tidal_window_from":f"'tidal_window_from' is more than a year in the future. Found: {tidal_window_from}."})
|
raise ValidationError({"tidal_window_from":f"'tidal_window_from' is more than a year in the future. Found: {tidal_window_from}."})
|
||||||
|
|
||||||
@ -491,7 +498,7 @@ class InputValidationShipcall():
|
|||||||
|
|
||||||
# if the *existing* shipcall in the database is canceled, it may not be changed
|
# if the *existing* shipcall in the database is canceled, it may not be changed
|
||||||
if shipcall.get("canceled", False):
|
if shipcall.get("canceled", False):
|
||||||
raise ValidationError({"canceled":f"The shipcall with id 'shipcall_id' is canceled. A canceled shipcall may not be changed."})
|
raise ValidationError({"canceled":f"The shipcall with id {shipcall_id} is canceled. A canceled shipcall may not be changed."})
|
||||||
return
|
return
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|||||||
@ -128,6 +128,10 @@ class InputValidationTimes():
|
|||||||
InputValidationTimes.check_user_belongs_to_same_group_as_dataset_determines(user_data, loadedModel=None, times_id=times_id)
|
InputValidationTimes.check_user_belongs_to_same_group_as_dataset_determines(user_data, loadedModel=None, times_id=times_id)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def exists_times_by_id(id:int):
|
||||||
|
return get_times_data_for_id(id) is not None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def check_if_entry_is_already_deleted(times_id:int):
|
def check_if_entry_is_already_deleted(times_id:int):
|
||||||
"""
|
"""
|
||||||
@ -195,10 +199,11 @@ class InputValidationTimes():
|
|||||||
"""
|
"""
|
||||||
# extract the IDs
|
# extract the IDs
|
||||||
berth_id, shipcall_id, participant_id = content.get("berth_id"), content.get("shipcall_id"), content.get("participant_id")
|
berth_id, shipcall_id, participant_id = content.get("berth_id"), content.get("shipcall_id"), content.get("participant_id")
|
||||||
|
port_id = content.get("port_id", None)
|
||||||
|
|
||||||
valid_berth_id_reference = check_if_berth_id_is_valid(berth_id)
|
valid_berth_id_reference = check_if_berth_id_is_valid(berth_id, port_id)
|
||||||
if not valid_berth_id_reference:
|
if not valid_berth_id_reference:
|
||||||
raise ValidationError({"berth_id":f"The referenced berth_id '{berth_id}' does not exist in the database."})
|
raise ValidationError({"berth_id":f"The referenced berth_id '{berth_id}' does not exist in the database or is not assigned to the port '{port_id}'."})
|
||||||
|
|
||||||
valid_shipcall_id_reference = check_if_shipcall_id_is_valid(shipcall_id)
|
valid_shipcall_id_reference = check_if_shipcall_id_is_valid(shipcall_id)
|
||||||
if not valid_shipcall_id_reference:
|
if not valid_shipcall_id_reference:
|
||||||
|
|||||||
@ -8,6 +8,7 @@ from BreCal.impl.berths import GetBerths
|
|||||||
from BreCal.impl.shipcalls import GetShipcalls
|
from BreCal.impl.shipcalls import GetShipcalls
|
||||||
|
|
||||||
from BreCal.database.enums import ParticipantType
|
from BreCal.database.enums import ParticipantType
|
||||||
|
from BreCal.database.sql_utils import get_port_ids_for_participant_id
|
||||||
from marshmallow import ValidationError
|
from marshmallow import ValidationError
|
||||||
|
|
||||||
def get_participant_id_dictionary():
|
def get_participant_id_dictionary():
|
||||||
@ -26,7 +27,7 @@ def get_participant_id_dictionary():
|
|||||||
|
|
||||||
def get_berth_id_dictionary():
|
def get_berth_id_dictionary():
|
||||||
# get all berths
|
# get all berths
|
||||||
response,status_code,header = GetBerths(token=None)
|
response,status_code,header = GetBerths(options={})
|
||||||
|
|
||||||
# build a dictionary of id:item pairs, so one can select the respective participant
|
# build a dictionary of id:item pairs, so one can select the respective participant
|
||||||
berths = json.loads(response)
|
berths = json.loads(response)
|
||||||
@ -120,7 +121,7 @@ def check_if_ship_id_is_valid(ship_id):
|
|||||||
ship_id_is_valid = ship_id in list(ships.keys())
|
ship_id_is_valid = ship_id in list(ships.keys())
|
||||||
return ship_id_is_valid
|
return ship_id_is_valid
|
||||||
|
|
||||||
def check_if_berth_id_is_valid(berth_id):
|
def check_if_berth_id_is_valid(berth_id, port_id=None):
|
||||||
"""check, whether the provided ID is valid. If it is 'None', it will be considered valid. This is, because a shipcall POST-request, does not have to include all IDs at once"""
|
"""check, whether the provided ID is valid. If it is 'None', it will be considered valid. This is, because a shipcall POST-request, does not have to include all IDs at once"""
|
||||||
if berth_id is None:
|
if berth_id is None:
|
||||||
return True
|
return True
|
||||||
@ -130,6 +131,12 @@ def check_if_berth_id_is_valid(berth_id):
|
|||||||
|
|
||||||
# boolean check
|
# boolean check
|
||||||
berth_id_is_valid = berth_id in list(berths.keys())
|
berth_id_is_valid = berth_id in list(berths.keys())
|
||||||
|
|
||||||
|
if port_id is not None:
|
||||||
|
# check, whether the berth is assigned to the respective port
|
||||||
|
berth_is_assigned_to_port = berths.get(berth_id,{}).get("port_id") == port_id
|
||||||
|
berth_id_is_valid = berth_id_is_valid and berth_is_assigned_to_port
|
||||||
|
|
||||||
return berth_id_is_valid
|
return berth_id_is_valid
|
||||||
|
|
||||||
def check_if_shipcall_id_is_valid(shipcall_id:int):
|
def check_if_shipcall_id_is_valid(shipcall_id:int):
|
||||||
@ -173,7 +180,7 @@ def check_if_participant_id_is_valid_standalone(participant_id:int, participant_
|
|||||||
# when the participant_type is not provided, only evaluate the ID
|
# when the participant_type is not provided, only evaluate the ID
|
||||||
return participant_id_is_valid
|
return participant_id_is_valid
|
||||||
|
|
||||||
def check_if_participant_id_is_valid(participant:dict):
|
def check_if_participant_id_is_valid(participant:dict, port_id=None):
|
||||||
"""
|
"""
|
||||||
check, whether the provided ID is valid. If it is 'None', it will be considered valid. This is, because a shipcall POST-request, does not have to include all IDs at once
|
check, whether the provided ID is valid. If it is 'None', it will be considered valid. This is, because a shipcall POST-request, does not have to include all IDs at once
|
||||||
|
|
||||||
@ -185,9 +192,14 @@ def check_if_participant_id_is_valid(participant:dict):
|
|||||||
participant_id = participant.get("participant_id", None)
|
participant_id = participant.get("participant_id", None)
|
||||||
participant_type = ParticipantType(int(participant.get("type", ParticipantType.undefined)))
|
participant_type = ParticipantType(int(participant.get("type", ParticipantType.undefined)))
|
||||||
participant_id_is_valid = check_if_participant_id_is_valid_standalone(participant_id, participant_type)
|
participant_id_is_valid = check_if_participant_id_is_valid_standalone(participant_id, participant_type)
|
||||||
|
if participant_id_is_valid and port_id is not None:
|
||||||
|
# check, whether the participant is assigned to the respective port
|
||||||
|
participant_is_assigned_to_port = any(p.get('port_id', None) == port_id for p in get_port_ids_for_participant_id(participant_id))
|
||||||
|
participant_id_is_valid &= participant_is_assigned_to_port
|
||||||
|
|
||||||
return participant_id_is_valid
|
return participant_id_is_valid
|
||||||
|
|
||||||
def check_if_participant_ids_are_valid(participants:list[dict]):
|
def check_if_participant_ids_are_valid(participants:list[dict], port_id=None):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
args:
|
args:
|
||||||
@ -201,7 +213,7 @@ def check_if_participant_ids_are_valid(participants:list[dict]):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
# check each participant id individually
|
# check each participant id individually
|
||||||
valid_participant_ids = [check_if_participant_id_is_valid(participant) for participant in participants]
|
valid_participant_ids = [check_if_participant_id_is_valid(participant, port_id) for participant in participants]
|
||||||
|
|
||||||
# boolean check, whether all participant ids are valid
|
# boolean check, whether all participant ids are valid
|
||||||
return all(valid_participant_ids)
|
return all(valid_participant_ids)
|
||||||
|
|||||||
@ -77,7 +77,7 @@ def create_werkzeug_error_response(ex:Forbidden, status_code:int=403, create_log
|
|||||||
def create_dynamic_exception_response(ex, status_code:int=400, message:typing.Optional[str]=None, create_log:bool=True):
|
def create_dynamic_exception_response(ex, status_code:int=400, message:typing.Optional[str]=None, create_log:bool=True):
|
||||||
message = repr(ex) if message is None else message
|
message = repr(ex) if message is None else message
|
||||||
json_response = create_default_json_response_format(error_field="Exception", error_description=message)
|
json_response = create_default_json_response_format(error_field="Exception", error_description=message)
|
||||||
json_response["message"] = "call failed"
|
json_response["error_field"] = "call failed"
|
||||||
|
|
||||||
serialized_response = json.dumps(json_response, default=str)
|
serialized_response = json.dumps(json_response, default=str)
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@ from setuptools import find_packages, setup
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='BreCal',
|
name='BreCal',
|
||||||
version='1.5.0',
|
version='1.6.0',
|
||||||
packages=find_packages(),
|
packages=find_packages(),
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
|
|||||||
Reference in New Issue
Block a user