merging branches and resolving conflicts (always accepting incoming for files, where Daniel worked exclusively).

This commit is contained in:
max_metz 2023-10-06 07:26:16 +02:00
commit 0c474839b0
54 changed files with 4036 additions and 969 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
openapi: "3.0.0"
info:
version: "0.3.0"
version: "0.6.0"
title: "Bremen calling API"
description: Administer DEBRE ship calls, times and notifications
termsOfService: "https://www.bsmd.de/" # url to terms page
@ -14,7 +14,7 @@ info:
servers:
# tutorial: https://idratherbewriting.com/learnapidoc/pubapis_openapi_step3_servers_object.html
- url: "https://brecal.bsmd-emswe.eu/"
- url: "https://brecaltest.bsmd-emswe.eu/"
description: "Test server hosted on vcup"
paths:
@ -100,6 +100,8 @@ paths:
schema:
$ref: "#/components/schemas/shipcall"
responses:
201:
$ref: "#/components/responses/201"
400:
$ref: "#/components/responses/400"
401:
@ -119,6 +121,8 @@ paths:
schema:
$ref: "#/components/schemas/shipcall"
responses:
200:
$ref: "#/components/responses/200"
400:
$ref: "#/components/responses/400"
401:
@ -210,6 +214,8 @@ paths:
schema:
$ref: "#/components/schemas/times"
responses:
201:
$ref: "#/components/responses/201"
400:
$ref: "#/components/responses/400"
401:
@ -229,6 +235,8 @@ paths:
schema:
$ref: "#/components/schemas/times"
responses:
200:
$ref: "#/components/responses/200"
400:
$ref: "#/components/responses/400"
401:
@ -404,6 +412,12 @@ components:
canceled:
type: boolean
nullable: true
evaluation:
type: integer
nullable: true
evaluation_message:
type: string
nullable: true
participants:
type: array
items:
@ -475,6 +489,18 @@ components:
type: integer
participant_id:
type: integer
berth_id:
type: integer
nullable: true
berth_info:
type: string
nullable: true
pier_side:
type: boolean
nullable: true
participant_type:
type: integer
nullable: true
created:
type: string
format: date-time
@ -622,6 +648,9 @@ components:
maxLength: 64
type:
type: integer
flags:
type: integer
nullable: true
created:
type: string
format: date-time
@ -681,7 +710,12 @@ components:
user_phone:
type: string
nullable: true
Id:
type: object
description: A unique identifier for an entity
properties:
id:
type: integer
Error:
type: object
required:
@ -697,6 +731,18 @@ components:
in: header
name: Authorization
responses:
200:
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/Id"
201:
description: Created
content:
application/json:
schema:
$ref: "#/components/schemas/Id"
400:
description: Invalid input
content:

View File

@ -1,18 +1,30 @@
-- --------------------------------------------------------
-- Host: 127.0.0.1
-- Server Version: 8.0.34-0ubuntu0.22.04.1 - (Ubuntu)
-- Server Betriebssystem: Linux
-- HeidiSQL Version: 10.2.0.5599
-- --------------------------------------------------------
CREATE DATABASE IF NOT EXISTS `bremen_calling` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */;
USE `bremen_calling`;
-- MySQL dump 10.13 Distrib 8.0.33, for Win64 (x86_64)
--
-- Host: localhost Database: bremen_calling
-- ------------------------------------------------------
-- Server version 8.0.34-0ubuntu0.22.04.1
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET NAMES utf8 */;
/*!50503 SET NAMES utf8mb4 */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
-- Exportiere Struktur von Tabelle bremen_calling.berth
CREATE TABLE IF NOT EXISTS `berth` (
--
-- Table structure for table `berth`
--
DROP TABLE IF EXISTS `berth`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `berth` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(128) DEFAULT NULL COMMENT 'Descriptive name',
`participant_id` int unsigned DEFAULT NULL COMMENT 'If berth belongs to a participant, reference it here',
@ -23,12 +35,17 @@ CREATE TABLE IF NOT EXISTS `berth` (
PRIMARY KEY (`id`),
KEY `FK_BERTH_PART` (`participant_id`),
CONSTRAINT `FK_BERTH_PART` FOREIGN KEY (`participant_id`) REFERENCES `participant` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Berth of ship for a ship call';
) ENGINE=InnoDB AUTO_INCREMENT=195 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Berth of ship for a ship call';
/*!40101 SET character_set_client = @saved_cs_client */;
-- Daten Export vom Benutzer nicht ausgewählt
--
-- Table structure for table `notification`
--
-- Exportiere Struktur von Tabelle bremen_calling.notification
CREATE TABLE IF NOT EXISTS `notification` (
DROP TABLE IF EXISTS `notification`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `notification` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`times_id` int unsigned NOT NULL COMMENT 'times record that caused the notification',
`participant_id` int unsigned NOT NULL COMMENT 'participant ref',
@ -44,11 +61,16 @@ CREATE TABLE IF NOT EXISTS `notification` (
CONSTRAINT `FK_NOT_PART` FOREIGN KEY (`participant_id`) REFERENCES `participant` (`id`),
CONSTRAINT `FK_NOT_TIMES` FOREIGN KEY (`times_id`) REFERENCES `times` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='An entry corresponds to an alarm given by a violated rule during times update';
/*!40101 SET character_set_client = @saved_cs_client */;
-- Daten Export vom Benutzer nicht ausgewählt
--
-- Table structure for table `participant`
--
-- Exportiere Struktur von Tabelle bremen_calling.participant
CREATE TABLE IF NOT EXISTS `participant` (
DROP TABLE IF EXISTS `participant`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `participant` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(128) DEFAULT NULL,
`street` varchar(128) DEFAULT NULL,
@ -60,12 +82,17 @@ CREATE TABLE IF NOT EXISTS `participant` (
`modified` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
`deleted` bit(1) DEFAULT b'0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='An organization taking part';
) ENGINE=InnoDB AUTO_INCREMENT=136 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='An organization taking part';
/*!40101 SET character_set_client = @saved_cs_client */;
-- Daten Export vom Benutzer nicht ausgewählt
--
-- Table structure for table `role`
--
-- Exportiere Struktur von Tabelle bremen_calling.role
CREATE TABLE IF NOT EXISTS `role` (
DROP TABLE IF EXISTS `role`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `role` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL DEFAULT '0' COMMENT 'unique role name',
`description` varchar(255) DEFAULT '0' COMMENT 'role description',
@ -74,11 +101,16 @@ CREATE TABLE IF NOT EXISTS `role` (
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='logical group of securables for one or more user';
/*!40101 SET character_set_client = @saved_cs_client */;
-- Daten Export vom Benutzer nicht ausgewählt
--
-- Table structure for table `role_securable_map`
--
-- Exportiere Struktur von Tabelle bremen_calling.role_securable_map
CREATE TABLE IF NOT EXISTS `role_securable_map` (
DROP TABLE IF EXISTS `role_securable_map`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `role_securable_map` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`role_id` int unsigned NOT NULL,
`securable_id` int unsigned NOT NULL,
@ -90,11 +122,16 @@ CREATE TABLE IF NOT EXISTS `role_securable_map` (
CONSTRAINT `FK_ROLE_SECURABLE` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`),
CONSTRAINT `FK_SECURABLE_ROLE` FOREIGN KEY (`securable_id`) REFERENCES `securable` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Assigns securables to roles';
/*!40101 SET character_set_client = @saved_cs_client */;
-- Daten Export vom Benutzer nicht ausgewählt
--
-- Table structure for table `securable`
--
-- Exportiere Struktur von Tabelle bremen_calling.securable
CREATE TABLE IF NOT EXISTS `securable` (
DROP TABLE IF EXISTS `securable`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `securable` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL DEFAULT '',
`created` datetime DEFAULT CURRENT_TIMESTAMP,
@ -102,11 +139,16 @@ CREATE TABLE IF NOT EXISTS `securable` (
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Actual permission on a single(!) feature or operation';
/*!40101 SET character_set_client = @saved_cs_client */;
-- Daten Export vom Benutzer nicht ausgewählt
--
-- Table structure for table `ship`
--
-- Exportiere Struktur von Tabelle bremen_calling.ship
CREATE TABLE IF NOT EXISTS `ship` (
DROP TABLE IF EXISTS `ship`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `ship` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(64) DEFAULT NULL,
`imo` int DEFAULT NULL,
@ -123,12 +165,17 @@ CREATE TABLE IF NOT EXISTS `ship` (
PRIMARY KEY (`id`),
KEY `FK_SHIP_PARTICIPANT` (`participant_id`),
CONSTRAINT `FK_SHIP_PARTICIPANT` FOREIGN KEY (`participant_id`) REFERENCES `participant` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
-- Daten Export vom Benutzer nicht ausgewählt
--
-- Table structure for table `shipcall`
--
-- Exportiere Struktur von Tabelle bremen_calling.shipcall
CREATE TABLE IF NOT EXISTS `shipcall` (
DROP TABLE IF EXISTS `shipcall`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `shipcall` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`ship_id` int unsigned DEFAULT NULL,
`type` tinyint DEFAULT NULL,
@ -151,6 +198,8 @@ CREATE TABLE IF NOT EXISTS `shipcall` (
`recommended_tugs` int DEFAULT '0',
`anchored` bit(1) DEFAULT NULL,
`moored_lock` bit(1) DEFAULT NULL,
`evaluation` int DEFAULT NULL,
`evaluation_message` varchar(512) DEFAULT NULL,
`canceled` bit(1) DEFAULT NULL,
`created` datetime DEFAULT CURRENT_TIMESTAMP,
`modified` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
@ -161,12 +210,17 @@ CREATE TABLE IF NOT EXISTS `shipcall` (
CONSTRAINT `FK_SHIPCALL_BERTH_ARRIVAL` FOREIGN KEY (`arrival_berth_id`) REFERENCES `berth` (`id`),
CONSTRAINT `FK_SHIPCALL_BERTH_DEPARTURE` FOREIGN KEY (`departure_berth_id`) REFERENCES `berth` (`id`),
CONSTRAINT `FK_SHIPCALL_SHIP` FOREIGN KEY (`ship_id`) REFERENCES `ship` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Incoming, outgoing or moving to another berth';
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Incoming, outgoing or moving to another berth';
/*!40101 SET character_set_client = @saved_cs_client */;
-- Daten Export vom Benutzer nicht ausgewählt
--
-- Table structure for table `shipcall_participant_map`
--
-- Exportiere Struktur von Tabelle bremen_calling.shipcall_participant_map
CREATE TABLE IF NOT EXISTS `shipcall_participant_map` (
DROP TABLE IF EXISTS `shipcall_participant_map`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `shipcall_participant_map` (
`id` int NOT NULL AUTO_INCREMENT,
`shipcall_id` int unsigned DEFAULT NULL,
`participant_id` int unsigned DEFAULT NULL,
@ -177,12 +231,17 @@ CREATE TABLE IF NOT EXISTS `shipcall_participant_map` (
KEY `FK_MAP_SHIPCALL_PARTICIPANT` (`participant_id`),
CONSTRAINT `FK_MAP_PARTICIPANT_SHIPCALL` FOREIGN KEY (`shipcall_id`) REFERENCES `shipcall` (`id`),
CONSTRAINT `FK_MAP_SHIPCALL_PARTICIPANT` FOREIGN KEY (`participant_id`) REFERENCES `participant` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Associates a participant with a shipcall';
) ENGINE=InnoDB AUTO_INCREMENT=82 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Associates a participant with a shipcall';
/*!40101 SET character_set_client = @saved_cs_client */;
-- Daten Export vom Benutzer nicht ausgewählt
--
-- Table structure for table `shipcall_tug_map`
--
-- Exportiere Struktur von Tabelle bremen_calling.shipcall_tug_map
CREATE TABLE IF NOT EXISTS `shipcall_tug_map` (
DROP TABLE IF EXISTS `shipcall_tug_map`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `shipcall_tug_map` (
`id` int NOT NULL AUTO_INCREMENT,
`shipcall_id` int unsigned NOT NULL COMMENT 'Ref to ship call',
`ship_id` int unsigned NOT NULL COMMENT 'Ref to ship (that is a tug)',
@ -194,11 +253,16 @@ CREATE TABLE IF NOT EXISTS `shipcall_tug_map` (
CONSTRAINT `FK_SCT_SHIP` FOREIGN KEY (`ship_id`) REFERENCES `ship` (`id`),
CONSTRAINT `FK_SCT_SHIPCALL` FOREIGN KEY (`shipcall_id`) REFERENCES `shipcall` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Mapping table that assigns tugs to a ship call';
/*!40101 SET character_set_client = @saved_cs_client */;
-- Daten Export vom Benutzer nicht ausgewählt
--
-- Table structure for table `times`
--
-- Exportiere Struktur von Tabelle bremen_calling.times
CREATE TABLE IF NOT EXISTS `times` (
DROP TABLE IF EXISTS `times`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `times` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`eta_berth` datetime DEFAULT NULL,
`eta_berth_fixed` bit(1) DEFAULT NULL,
@ -215,16 +279,27 @@ CREATE TABLE IF NOT EXISTS `times` (
`participant_id` int unsigned NOT NULL,
`created` datetime DEFAULT CURRENT_TIMESTAMP,
`modified` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
`berth_id` int unsigned DEFAULT NULL,
`berth_info` varchar(512) DEFAULT NULL,
`pier_side` bit(1) DEFAULT NULL,
`participant_type` int unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK_TIME_SHIPCALL` (`shipcall_id`),
KEY `FK_TIME_PART` (`participant_id`),
KEY `FK_TIME_PART` (`participant_id`) /*!80000 INVISIBLE */,
KEY `FK_TIME_BERTH` (`berth_id`) /*!80000 INVISIBLE */,
CONSTRAINT `FK_TIME_BERTH` FOREIGN KEY (`berth_id`) REFERENCES `berth` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `FK_TIME_PART` FOREIGN KEY (`participant_id`) REFERENCES `participant` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='the planned time for the participants work';
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='the planned time for the participants work';
/*!40101 SET character_set_client = @saved_cs_client */;
-- Daten Export vom Benutzer nicht ausgewählt
--
-- Table structure for table `user`
--
-- Exportiere Struktur von Tabelle bremen_calling.user
CREATE TABLE IF NOT EXISTS `user` (
DROP TABLE IF EXISTS `user`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `user` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`participant_id` int unsigned DEFAULT NULL,
`first_name` varchar(45) DEFAULT NULL,
@ -239,12 +314,17 @@ CREATE TABLE IF NOT EXISTS `user` (
PRIMARY KEY (`id`),
KEY `FK_USER_PART` (`participant_id`),
CONSTRAINT `FK_USER_PART` FOREIGN KEY (`participant_id`) REFERENCES `participant` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='member of a participant';
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='member of a participant';
/*!40101 SET character_set_client = @saved_cs_client */;
-- Daten Export vom Benutzer nicht ausgewählt
--
-- Table structure for table `user_role_map`
--
-- Exportiere Struktur von Tabelle bremen_calling.user_role_map
CREATE TABLE IF NOT EXISTS `user_role_map` (
DROP TABLE IF EXISTS `user_role_map`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `user_role_map` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`user_id` int unsigned NOT NULL DEFAULT '0',
`role_id` int unsigned NOT NULL DEFAULT '0',
@ -256,9 +336,15 @@ CREATE TABLE IF NOT EXISTS `user_role_map` (
CONSTRAINT `FK_ROLE_USER` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`),
CONSTRAINT `FK_USER_ROLE` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Assigns a user to a role';
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
-- Daten Export vom Benutzer nicht ausgewählt
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2023-09-05 10:36:12

View File

@ -1,136 +1,155 @@
-- --------------------------------------------------------
-- Host: 127.0.0.1
-- Server Version: 8.0.34-0ubuntu0.22.04.1 - (Ubuntu)
-- Server Betriebssystem: Linux
-- HeidiSQL Version: 10.2.0.5599
-- --------------------------------------------------------
CREATE DATABASE IF NOT EXISTS `bremen_calling` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */;
USE `bremen_calling`;
-- MySQL dump 10.13 Distrib 8.0.33, for Win64 (x86_64)
--
-- Host: localhost Database: bremen_calling
-- ------------------------------------------------------
-- Server version 8.0.34-0ubuntu0.22.04.1
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET NAMES utf8 */;
/*!50503 SET NAMES utf8mb4 */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
-- Exportiere Daten aus Tabelle bremen_calling.berth: ~3 rows (ungefähr)
--
-- Dumping data for table `berth`
--
LOCK TABLES `berth` WRITE;
/*!40000 ALTER TABLE `berth` DISABLE KEYS */;
INSERT INTO `berth` (`id`, `name`, `participant_id`, `lock`, `created`, `modified`, `deleted`) VALUES
(1, 'Roland Mühle', NULL, NULL, '2023-06-26 14:01:40', NULL, b'0'),
(2, 'Stahlwerk', NULL, NULL, '2023-06-26 14:01:40', NULL, b'0'),
(3, 'Kellogs', NULL, NULL, '2023-06-26 14:01:40', NULL, b'0');
INSERT INTO `berth` VALUES (1,'Roland Mühle',NULL,NULL,'2023-06-26 14:01:40',NULL,_binary '\0'),(2,'Stahlwerk',NULL,NULL,'2023-06-26 14:01:40',NULL,_binary '\0'),(3,'Kellogs',NULL,NULL,'2023-06-26 14:01:40',NULL,_binary '\0'),(139,'Avangard Dalben',110,NULL,'2023-08-21 08:23:35',NULL,_binary '\0'),(140,'Avangard Kaje',110,NULL,'2023-08-21 08:23:35',NULL,_binary '\0'),(141,'Baustelle 2',111,NULL,'2023-08-21 08:23:35',NULL,_binary '\0'),(142,'BHW',112,NULL,'2023-08-21 08:23:36',NULL,_binary '\0'),(143,'Dalben 2',111,NULL,'2023-08-21 08:23:36',NULL,_binary '\0'),(144,'Dalben 3',111,NULL,'2023-08-21 08:23:36',NULL,_binary '\0'),(145,'Egerland Kaje',113,NULL,'2023-08-21 08:23:36',NULL,_binary '\0'),(146,'Getreideanlage Pier A',114,NULL,'2023-08-21 08:23:37',NULL,_binary '\0'),(147,'Getreideanlage Pier D',114,NULL,'2023-08-21 08:23:37',NULL,_binary '\0'),(148,'Griepe, Bnp Paribas',115,NULL,'2023-08-21 08:23:37',NULL,_binary '\0'),(149,'Hafen F',116,NULL,'2023-08-21 08:23:37',NULL,_binary '\0'),(150,'Hansa Landhandel',117,NULL,'2023-08-21 08:23:38',NULL,_binary '\0'),(151,'Hansa Melasse',118,NULL,'2023-08-21 08:23:38',NULL,_binary '\0'),(152,'Hansa-Mühle',119,NULL,'2023-08-21 08:23:38',NULL,_binary '\0'),(153,'Heidelberger Sand',120,NULL,'2023-08-21 08:23:38',NULL,_binary '\0'),(154,'HGM Bunkerstation',121,NULL,'2023-08-21 08:23:39',NULL,_binary '\0'),(155,'HGM Tanklager',121,NULL,'2023-08-21 08:23:39',NULL,_binary '\0'),(156,'Kap Horn Innen',122,NULL,'2023-08-21 08:23:39',NULL,_binary '\0'),(157,'Kap Horn Weser',122,NULL,'2023-08-21 08:23:39',NULL,_binary '\0'),(158,'Kap Horn Weser Bremer Recycling',123,NULL,'2023-08-21 08:23:40',NULL,_binary '\0'),(159,'Kap Horn Weser -GHK-',124,NULL,'2023-08-21 08:23:40',NULL,_binary '\0'),(160,'Kohlenhafen 2',111,NULL,'2023-08-21 08:23:40',NULL,_binary '\0'),(161,'Kraftwerk Farge',125,NULL,'2023-08-21 08:23:40',NULL,_binary '\0'),(162,'Kraftwerk Industriehafen',126,NULL,'2023-08-21 08:23:41',NULL,_binary '\0'),(163,'Lankenau B',111,NULL,'2023-08-21 08:23:41',NULL,_binary '\0'),(164,'Mibau, Bnp Paribas',127,NULL,'2023-08-21 08:23:41',NULL,_binary '\0'),(165,'Müller Weser',114,NULL,'2023-08-21 08:23:41',NULL,_binary '\0'),(166,'Osterort 5 Aussen',111,NULL,'2023-08-21 08:23:41',NULL,_binary '\0'),(167,'Pier 2 Anleger',128,NULL,'2023-08-21 08:23:42',NULL,_binary '\0'),(168,'Pier III',129,NULL,'2023-08-21 08:23:42',NULL,_binary '\0'),(169,'Plump',130,NULL,'2023-08-21 08:23:42',NULL,_binary '\0'),(170,'Rolandmühle',131,NULL,'2023-08-21 08:23:42',NULL,_binary '\0'),(171,'Schleusenvorhafen Nord',111,NULL,'2023-08-21 08:23:43',NULL,_binary '\0'),(172,'Schrägpier',4,NULL,'2023-08-21 08:23:43',NULL,_binary '\0'),(173,'Schuppen 19',132,NULL,'2023-08-21 08:23:43',NULL,_binary '\0'),(174,'Schuppen 20',4,NULL,'2023-08-21 08:23:43',NULL,_binary '\0'),(175,'Schuppen 21',4,NULL,'2023-08-21 08:23:43',NULL,_binary '\0'),(176,'Schuppen 22',4,NULL,'2023-08-21 08:23:43',NULL,_binary '\0'),(177,'Schuppen 23',4,NULL,'2023-08-21 08:23:44',NULL,_binary '\0'),(178,'Schuppen 24',4,NULL,'2023-08-21 08:23:44',NULL,_binary '\0'),(179,'Seedalben Dlg-Seite',111,NULL,'2023-08-21 08:23:44',NULL,_binary '\0'),(180,'Seedalben Kw-Seite',111,NULL,'2023-08-21 08:23:44',NULL,_binary '\0'),(181,'Seehausen Spüler',111,NULL,'2023-08-21 08:23:44',NULL,_binary '\0'),(182,'Tankschiffliegeplatz 1',111,NULL,'2023-08-21 08:23:44',NULL,_binary '\0'),(183,'Tankschiffliegeplatz 2',111,NULL,'2023-08-21 08:23:44',NULL,_binary '\0'),(184,'Terminal 1',10,NULL,'2023-08-21 08:23:44',NULL,_binary '\0'),(185,'Terminal 2',10,NULL,'2023-08-21 08:23:45',NULL,_binary '\0'),(186,'Terminal 3',10,NULL,'2023-08-21 08:23:45',NULL,_binary '\0'),(187,'Terminal 4',10,NULL,'2023-08-21 08:23:45',NULL,_binary '\0'),(188,'TSR Recycling',133,NULL,'2023-08-21 08:23:45',NULL,_binary '\0'),(189,'Viehbrücke',111,NULL,'2023-08-21 08:23:45',NULL,_binary '\0'),(190,'Vulkan Industriegebiet',120,NULL,'2023-08-21 08:23:46',NULL,_binary '\0'),(191,'Weserbahnhof',132,NULL,'2023-08-21 08:23:46',NULL,_binary '\0'),(192,'Weser-Petrol Holzhafen',134,NULL,'2023-08-21 08:23:46',NULL,_binary '\0'),(193,'Weser-Petrol Kalihafen',134,NULL,'2023-08-21 08:23:46',NULL,_binary '\0'),(194,'Wesertanking',135,NULL,'2023-08-21 08:23:46',NULL,_binary '\0');
/*!40000 ALTER TABLE `berth` ENABLE KEYS */;
UNLOCK TABLES;
-- Exportiere Daten aus Tabelle bremen_calling.notification: ~0 rows (ungefähr)
--
-- Dumping data for table `notification`
--
LOCK TABLES `notification` WRITE;
/*!40000 ALTER TABLE `notification` DISABLE KEYS */;
/*!40000 ALTER TABLE `notification` ENABLE KEYS */;
UNLOCK TABLES;
-- Exportiere Daten aus Tabelle bremen_calling.participant: ~11 rows (ungefähr)
--
-- Dumping data for table `participant`
--
LOCK TABLES `participant` WRITE;
/*!40000 ALTER TABLE `participant` DISABLE KEYS */;
INSERT INTO `participant` (`id`, `name`, `street`, `postal_code`, `city`, `type`, `flags`, `created`, `modified`, `deleted`) VALUES
(1, 'Schick Informatik', 'Gottlieb-Daimler-Str. 8', '73614', 'Schorndorf', 1, 42, '2023-04-17 07:18:19', '2023-08-07 11:35:37', b'0'),
(2, 'Lotsenbrüderschaft Weser 1', '', '', '', 4, 0, '2023-08-10 07:07:41', NULL, b'0'),
(3, 'Bremer Schiffsmeldedienst', 'Hafenkopf II / Überseetor 20', '28217', 'Bremen', 1, 0, '2023-08-10 07:11:10', NULL, b'0'),
(4, 'BLG Cargo Logistics GmbH', '', '', '', 2, 0, '2023-08-10 07:14:40', NULL, b'0'),
(5, 'Schiffsmakler-Verband für Küsten und Seeschiffsbefrachter e.V.', '', '', '', 8, 0, '2023-08-10 07:15:56', NULL, b'0'),
(6, 'RMS Rhenus Maritime Services GmbH', '', '', '', 8, 0, '2023-08-10 07:19:29', NULL, b'0'),
(7, 'J.MÜLLER Weser GmbH & Co. KG', '', '', '', 10, 0, '2023-08-10 07:21:43', '2023-08-10 08:47:59', b'0'),
(8, 'Schiffahrtskontor Detra GmbH & Co.KG', '', '', '', 8, 0, '2023-08-10 07:23:04', NULL, b'0'),
(9, 'Boluda Deutschland GmbH', '', '', '', 64, 0, '2023-08-10 07:24:18', NULL, b'0'),
(10, 'Weserport GmbH', '', '', '', 10, 0, '2023-08-10 07:26:42', '2023-08-10 08:48:19', b'0'),
(11, 'Port Authority Bremen', '', '', '', 32, 0, '2023-08-10 07:28:11', NULL, b'0');
INSERT INTO `participant` VALUES (1,'Schick Informatik','Gottlieb-Daimler-Str. 8','73614','Schorndorf',1,42,'2023-04-17 07:18:19','2023-08-24 07:07:02',_binary '\0'),(2,'Lotsenbrüderschaft Weser 1','','','',4,0,'2023-08-10 07:07:41',NULL,_binary '\0'),(3,'Bremer Schiffsmeldedienst','Hafenkopf II / Überseetor 20','28217','Bremen',1,0,'2023-08-10 07:11:10',NULL,_binary '\0'),(4,'BLG Cargo Logistics GmbH','','','',2,0,'2023-08-10 07:14:40',NULL,_binary '\0'),(5,'Schiffsmakler-Verband für Küsten und Seeschiffsbefrachter e.V.','','','',8,0,'2023-08-10 07:15:56',NULL,_binary '\0'),(6,'RMS Rhenus Maritime Services GmbH','','','',8,0,'2023-08-10 07:19:29',NULL,_binary '\0'),(7,'J.MÜLLER Weser GmbH & Co. KG','','','',10,0,'2023-08-10 07:21:43','2023-08-10 08:47:59',_binary '\0'),(8,'Schiffahrtskontor Detra GmbH & Co.KG','','','',8,0,'2023-08-10 07:23:04',NULL,_binary '\0'),(9,'Boluda Deutschland GmbH','','','',64,0,'2023-08-10 07:24:18',NULL,_binary '\0'),(10,'Weserport GmbH','','','',10,0,'2023-08-10 07:26:42','2023-08-10 08:48:19',_binary '\0'),(11,'Port Authority Bremen','','','',32,0,'2023-08-10 07:28:11',NULL,_binary '\0'),(12,'Nordenia Frachtkontor GmbH','','','',8,0,'2023-08-21 06:52:04',NULL,_binary '\0'),(15,'Extern','','','',0,0,'2023-08-21 06:55:18',NULL,_binary '\0'),(16,'FESTMA Vertäugesellschaft mbH','','','',16,0,'2023-08-21 06:57:23',NULL,_binary '\0'),(110,'Avangard',NULL,NULL,NULL,2,0,'2023-08-21 08:23:35','2023-08-21 10:04:21',_binary '\0'),(111,'Bremenports',NULL,NULL,NULL,2,0,'2023-08-21 08:23:35','2023-08-21 10:04:21',_binary '\0'),(112,'Bremer Holzwerke',NULL,NULL,NULL,2,0,'2023-08-21 08:23:36','2023-08-21 10:04:21',_binary '\0'),(113,'Egerland',NULL,NULL,NULL,2,0,'2023-08-21 08:23:36','2023-08-21 10:04:21',_binary '\0'),(114,'Müller J. Bremen',NULL,NULL,NULL,2,0,'2023-08-21 08:23:37','2023-08-21 10:04:21',_binary '\0'),(115,'Griepe',NULL,NULL,NULL,2,0,'2023-08-21 08:23:37','2023-08-21 10:04:21',_binary '\0'),(116,'Mseven Real Estate',NULL,NULL,NULL,2,0,'2023-08-21 08:23:37','2023-08-21 10:04:21',_binary '\0'),(117,'Hansa Landhandel',NULL,NULL,NULL,2,0,'2023-08-21 08:23:38','2023-08-21 10:04:21',_binary '\0'),(118,'Hansa Melasse',NULL,NULL,NULL,2,0,'2023-08-21 08:23:38','2023-08-21 10:04:21',_binary '\0'),(119,'Hansa-Mühle',NULL,NULL,NULL,2,0,'2023-08-21 08:23:38','2023-08-21 10:04:21',_binary '\0'),(120,'Heidelberger Sand Und Kies Gmbh',NULL,NULL,NULL,2,0,'2023-08-21 08:23:38','2023-08-21 10:04:21',_binary '\0'),(121,'HGM',NULL,NULL,NULL,2,0,'2023-08-21 08:23:39','2023-08-21 10:04:21',_binary '\0'),(122,'Kap-Horn Logistics Gmbh',NULL,NULL,NULL,2,0,'2023-08-21 08:23:39','2023-08-21 10:04:21',_binary '\0'),(123,'Bremer Recycling Kontor',NULL,NULL,NULL,2,0,'2023-08-21 08:23:39','2023-08-21 10:04:21',_binary '\0'),(124,'GHK',NULL,NULL,NULL,2,0,'2023-08-21 08:23:40','2023-08-21 10:04:21',_binary '\0'),(125,'Kraftwerk Farge Engie Gmbh & Co. KG',NULL,NULL,NULL,2,0,'2023-08-21 08:23:40','2023-08-21 10:04:21',_binary '\0'),(126,'Swb Erzeugung',NULL,NULL,NULL,2,0,'2023-08-21 08:23:40','2023-08-21 10:04:21',_binary '\0'),(127,'Mibau',NULL,NULL,NULL,2,0,'2023-08-21 08:23:41','2023-08-21 10:04:21',_binary '\0'),(128,'SWG',NULL,NULL,NULL,2,0,'2023-08-21 08:23:41','2023-08-21 10:04:21',_binary '\0'),(129,'Umweltschutz Nord Ganderkesee',NULL,NULL,NULL,2,0,'2023-08-21 08:23:42','2023-08-21 10:04:21',_binary '\0'),(130,'Nehlsen Industrieservice Gmbh & Co. KG',NULL,NULL,NULL,2,0,'2023-08-21 08:23:42','2023-08-21 10:04:21',_binary '\0'),(131,'Rolandmühle',NULL,NULL,NULL,2,0,'2023-08-21 08:23:42','2023-08-21 10:04:21',_binary '\0'),(132,'Wfb',NULL,NULL,NULL,2,0,'2023-08-21 08:23:43','2023-08-21 10:04:21',_binary '\0'),(133,'TSR',NULL,NULL,NULL,2,0,'2023-08-21 08:23:45','2023-08-21 10:04:21',_binary '\0'),(134,'Weser-Petrol',NULL,NULL,NULL,2,0,'2023-08-21 08:23:46','2023-08-21 10:04:21',_binary '\0'),(135,'Wesertanking',NULL,NULL,NULL,2,0,'2023-08-21 08:23:46','2023-08-21 10:04:21',_binary '\0');
/*!40000 ALTER TABLE `participant` ENABLE KEYS */;
UNLOCK TABLES;
-- Exportiere Daten aus Tabelle bremen_calling.role: ~2 rows (ungefähr)
--
-- Dumping data for table `role`
--
LOCK TABLES `role` WRITE;
/*!40000 ALTER TABLE `role` DISABLE KEYS */;
INSERT INTO `role` (`id`, `name`, `description`, `created`, `modified`) VALUES
(1, 'My first role', 'A very good description', '2023-04-17 07:31:57', NULL),
(2, 'Another role', 'This role is very nice as well', '2023-04-17 07:32:12', NULL);
INSERT INTO `role` VALUES (1,'My first role','A very good description','2023-04-17 07:31:57',NULL),(2,'Another role','This role is very nice as well','2023-04-17 07:32:12',NULL);
/*!40000 ALTER TABLE `role` ENABLE KEYS */;
UNLOCK TABLES;
-- Exportiere Daten aus Tabelle bremen_calling.role_securable_map: ~0 rows (ungefähr)
--
-- Dumping data for table `role_securable_map`
--
LOCK TABLES `role_securable_map` WRITE;
/*!40000 ALTER TABLE `role_securable_map` DISABLE KEYS */;
/*!40000 ALTER TABLE `role_securable_map` ENABLE KEYS */;
UNLOCK TABLES;
-- Exportiere Daten aus Tabelle bremen_calling.securable: ~2 rows (ungefähr)
--
-- Dumping data for table `securable`
--
LOCK TABLES `securable` WRITE;
/*!40000 ALTER TABLE `securable` DISABLE KEYS */;
INSERT INTO `securable` (`id`, `name`, `created`, `modified`) VALUES
(1, 'First secure thing', '2023-04-17 07:38:12', NULL),
(2, 'Another secure thing', '2023-04-17 07:38:22', NULL);
INSERT INTO `securable` VALUES (1,'First secure thing','2023-04-17 07:38:12',NULL),(2,'Another secure thing','2023-04-17 07:38:22',NULL);
/*!40000 ALTER TABLE `securable` ENABLE KEYS */;
UNLOCK TABLES;
-- Exportiere Daten aus Tabelle bremen_calling.ship: ~2 rows (ungefähr)
--
-- Dumping data for table `ship`
--
LOCK TABLES `ship` WRITE;
/*!40000 ALTER TABLE `ship` DISABLE KEYS */;
INSERT INTO `ship` (`id`, `name`, `imo`, `callsign`, `participant_id`, `length`, `width`, `is_tug`, `bollard_pull`, `eni`, `created`, `modified`, `deleted`) VALUES
(1, 'Dicke Berta', 1234567, 'DEBE', 1, 100, 20, b'0', NULL, NULL, '2023-06-27 10:43:02', NULL, b'0'),
(2, 'Maersk Neston', 9632167, '9V3532', 1, 210.07, 30.2, b'0', NULL, NULL, '2023-07-27 12:34:13', NULL, b'0');
INSERT INTO `ship` VALUES (1,'Dicke Berta',1234567,'DEBE',1,100,20,_binary '\0',NULL,NULL,'2023-06-27 10:43:02',NULL,_binary '\0'),(2,'Maersk Neston',9632167,'9V3532',1,210.07,30.2,_binary '\0',NULL,NULL,'2023-07-27 12:34:13',NULL,_binary '\0'),(3,'AFRICAN HALCYON',9343613,NULL,NULL,177.13,28.4,_binary '\0',NULL,NULL,'2023-08-24 10:41:56',NULL,_binary '\0'),(4,'AMIKO',9125669,NULL,NULL,99.98,16.5,_binary '\0',NULL,NULL,'2023-08-24 10:42:17',NULL,_binary '\0'),(5,'ARKLOW BEACON',9638795,NULL,NULL,119.49,14.99,_binary '\0',NULL,NULL,'2023-08-24 10:42:17',NULL,_binary '\0'),(6,'FWN ATLANTIDE',9535620,NULL,NULL,145.65,18.25,_binary '\0',NULL,NULL,'2023-08-24 10:42:17',NULL,_binary '\0'),(7,'IONIAN SPIRIT',9747235,NULL,NULL,179.9,30,_binary '\0',NULL,NULL,'2023-08-24 10:42:17',NULL,_binary '\0'),(8,'IRMA',9180396,NULL,NULL,199.9,23.6,_binary '\0',NULL,NULL,'2023-08-24 10:42:17',NULL,_binary '\0'),(9,'JANA',9330185,NULL,NULL,69.34,12,_binary '\0',NULL,NULL,'2023-08-24 10:42:18',NULL,_binary '\0'),(10,'MEDI PERTH',9804552,NULL,NULL,199.99,32.24,_binary '\0',NULL,NULL,'2023-08-24 10:42:18',NULL,_binary '\0'),(11,'S NEPTUNE',9634892,NULL,NULL,169.99,27,_binary '\0',NULL,NULL,'2023-08-24 10:42:18',NULL,_binary '\0'),(12,'WESER STAHL',9186687,NULL,NULL,192,32.26,_binary '\0',NULL,NULL,'2023-08-24 10:42:18',NULL,_binary '\0');
/*!40000 ALTER TABLE `ship` ENABLE KEYS */;
UNLOCK TABLES;
-- Exportiere Daten aus Tabelle bremen_calling.shipcall: ~8 rows (ungefähr)
--
-- Dumping data for table `shipcall`
--
LOCK TABLES `shipcall` WRITE;
/*!40000 ALTER TABLE `shipcall` DISABLE KEYS */;
INSERT INTO `shipcall` (`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`, `created`, `modified`) VALUES
(3, 1, 1, '2023-08-13 07:18:19', '43B', NULL, NULL, NULL, b'0', b'1', 0, b'0', b'1', NULL, NULL, NULL, NULL, NULL, b'0', 3, NULL, NULL, NULL, '2023-06-27 11:03:28', '2023-08-07 15:19:56'),
(4, 2, 1, '2023-08-14 10:43:02', '43', NULL, NULL, NULL, NULL, NULL, 2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, b'0', 0, NULL, NULL, NULL, '2023-07-27 12:36:49', '2023-08-07 15:19:56'),
(5, 1, 1, '2023-07-23 07:18:19', '43B', NULL, NULL, NULL, b'0', b'1', 0, b'0', b'1', NULL, NULL, NULL, NULL, NULL, b'0', 2, NULL, NULL, NULL, '2023-08-11 15:11:50', NULL),
(6, 1, 1, '2023-07-23 07:18:19', '43B', NULL, NULL, NULL, b'0', b'1', 0, b'0', b'1', NULL, NULL, NULL, NULL, NULL, b'0', 2, NULL, NULL, NULL, '2023-08-11 15:11:53', NULL),
(7, 1, 1, '2023-07-23 07:18:19', '43B', NULL, NULL, NULL, b'0', b'1', 0, b'0', b'1', NULL, NULL, NULL, NULL, NULL, b'0', 2, NULL, NULL, NULL, '2023-08-13 12:12:34', NULL),
(8, 1, 1, '2023-07-23 07:18:19', '43B', NULL, NULL, NULL, b'0', b'1', 0, b'0', b'1', NULL, NULL, NULL, NULL, NULL, b'0', 2, NULL, NULL, NULL, '2023-08-13 12:14:52', NULL),
(9, 1, 1, '2023-07-23 07:18:19', '43B', NULL, NULL, NULL, b'0', b'1', 0, b'0', b'1', NULL, NULL, NULL, NULL, NULL, b'0', 2, NULL, NULL, NULL, '2023-08-13 12:17:09', NULL),
(10, 1, 1, '2023-08-23 07:18:19', '43B', NULL, NULL, NULL, b'0', b'1', 0, b'0', b'1', NULL, NULL, NULL, NULL, NULL, b'0', 3, NULL, NULL, NULL, '2023-08-14 07:55:48', '2023-08-14 07:56:52');
INSERT INTO `shipcall` VALUES (3,7,1,'2023-09-21 03:00:00','43B','2023-08-25 12:17:16',177,177,_binary '',_binary '',0,_binary '\0',_binary '',_binary '',_binary '',7.5,NULL,NULL,_binary '\0',3,_binary '',_binary '\0',_binary '\0','2023-06-27 11:03:28','2023-09-04 08:13:15'),(4,3,2,'2023-09-24 12:22:20','43','2023-09-01 02:00:00',184,184,_binary '',_binary '',2,_binary '\0',_binary '\0',_binary '\0',_binary '\0',6.35,NULL,NULL,_binary '\0',1,_binary '\0',_binary '',_binary '\0','2023-07-27 12:36:49','2023-09-04 08:13:15'),(5,1,1,'2023-07-23 07:18:19','43B',NULL,NULL,NULL,_binary '\0',_binary '',0,_binary '\0',_binary '',NULL,NULL,NULL,NULL,NULL,_binary '\0',2,NULL,NULL,NULL,'2023-08-11 15:11:50',NULL),(6,1,1,'2023-07-23 07:18:19','43B',NULL,NULL,NULL,_binary '\0',_binary '',0,_binary '\0',_binary '',NULL,NULL,NULL,NULL,NULL,_binary '\0',2,NULL,NULL,NULL,'2023-08-11 15:11:53',NULL),(7,1,1,'2023-07-23 07:18:19','43B',NULL,NULL,NULL,_binary '\0',_binary '',0,_binary '\0',_binary '',NULL,NULL,NULL,NULL,NULL,_binary '\0',2,NULL,NULL,NULL,'2023-08-13 12:12:34',NULL),(8,1,1,'2023-07-23 07:18:19','43B',NULL,NULL,NULL,_binary '\0',_binary '',0,_binary '\0',_binary '',NULL,NULL,NULL,NULL,NULL,_binary '\0',2,NULL,NULL,NULL,'2023-08-13 12:14:52',NULL),(9,1,1,'2023-07-23 07:18:19','43B',NULL,NULL,NULL,_binary '\0',_binary '',0,_binary '\0',_binary '',NULL,NULL,NULL,NULL,NULL,_binary '\0',2,NULL,NULL,NULL,'2023-08-13 12:17:09',NULL),(10,4,1,'2023-09-11 10:00:00','43B','2023-08-25 12:26:14',146,146,_binary '\0',_binary '',0,_binary '\0',_binary '\0',_binary '',_binary '\0',4.4,NULL,NULL,_binary '',3,_binary '\0',_binary '\0',_binary '\0','2023-08-14 07:55:48','2023-09-04 08:14:36'),(11,1,1,'2023-07-23 07:18:19','43B',NULL,NULL,NULL,_binary '\0',_binary '',0,_binary '\0',_binary '',NULL,NULL,NULL,NULL,NULL,_binary '\0',2,NULL,NULL,NULL,'2023-08-18 09:14:13',NULL),(12,1,1,'2023-07-23 07:18:19','43B',NULL,NULL,NULL,_binary '\0',_binary '',0,_binary '\0',_binary '',NULL,NULL,NULL,NULL,NULL,_binary '\0',2,NULL,NULL,NULL,'2023-08-18 09:14:20',NULL),(13,1,1,'2023-07-23 07:18:19','43B',NULL,NULL,NULL,_binary '\0',_binary '',0,_binary '\0',_binary '',NULL,NULL,NULL,NULL,NULL,_binary '\0',2,NULL,NULL,NULL,'2023-08-18 09:14:45',NULL),(14,1,1,'2023-07-23 07:18:19','43B',NULL,NULL,NULL,_binary '\0',_binary '',0,_binary '\0',_binary '',NULL,NULL,NULL,NULL,NULL,_binary '\0',2,NULL,NULL,NULL,'2023-08-18 09:17:42',NULL),(15,1,1,'2023-07-23 07:18:19','43B',NULL,NULL,NULL,_binary '\0',_binary '',0,_binary '\0',_binary '',NULL,NULL,NULL,NULL,NULL,_binary '\0',2,NULL,NULL,NULL,'2023-08-18 09:17:51',NULL),(16,1,3,'2023-09-21 16:19:14','Test','2023-08-26 16:18:54',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'0001-01-01 00:00:00','2023-09-04 13:05:33'),(17,7,1,'2023-09-01 03:00:01','','2023-08-25 12:20:05',177,177,_binary '',_binary '',NULL,_binary '',_binary '\0',_binary '\0',_binary '\0',7.5,'2023-08-31 23:00:01','2023-09-01 05:00:01',_binary '\0',2,_binary '\0',_binary '\0',_binary '\0','2023-08-24 12:20:04',NULL),(18,3,2,'2023-09-25 20:44:21','','2023-09-01 03:00:28',184,184,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'2023-08-27 20:45:06','2023-09-04 08:14:35');
/*!40000 ALTER TABLE `shipcall` ENABLE KEYS */;
UNLOCK TABLES;
-- Exportiere Daten aus Tabelle bremen_calling.shipcall_participant_map: ~6 rows (ungefähr)
--
-- Dumping data for table `shipcall_participant_map`
--
LOCK TABLES `shipcall_participant_map` WRITE;
/*!40000 ALTER TABLE `shipcall_participant_map` DISABLE KEYS */;
INSERT INTO `shipcall_participant_map` (`id`, `shipcall_id`, `participant_id`, `created`, `modified`) VALUES
(1, 3, 2, '2023-08-11 15:01:23', NULL),
(2, 3, 4, '2023-08-11 15:01:29', NULL),
(3, 9, 2, '2023-08-13 12:17:17', NULL),
(4, 9, 4, '2023-08-13 12:17:18', NULL),
(24, 10, 3, '2023-08-14 08:48:30', NULL),
(26, 10, 9, '2023-08-14 09:03:29', NULL);
INSERT INTO `shipcall_participant_map` VALUES (1,3,2,'2023-08-11 15:01:23',NULL),(3,9,2,'2023-08-13 12:17:17',NULL),(4,9,4,'2023-08-13 12:17:18',NULL),(24,10,3,'2023-08-14 08:48:30',NULL),(26,10,9,'2023-08-14 09:03:29',NULL),(28,10,7,'2023-08-21 14:36:44',NULL),(29,10,16,'2023-08-21 14:36:44',NULL),(30,10,2,'2023-08-21 14:36:44',NULL),(32,10,11,'2023-08-21 14:36:44',NULL),(33,10,1,'2023-08-21 14:36:44',NULL),(34,3,3,'2023-08-21 14:45:52',NULL),(35,3,11,'2023-08-21 14:45:52',NULL),(43,16,3,'2023-08-21 16:19:13',NULL),(44,16,11,'2023-08-21 16:19:13',NULL),(45,16,1,'2023-08-21 16:19:13',NULL),(48,3,16,'2023-08-23 16:58:54',NULL),(49,3,9,'2023-08-23 16:58:54',NULL),(50,4,10,'2023-08-24 10:01:40',NULL),(51,4,16,'2023-08-24 10:01:40',NULL),(52,4,2,'2023-08-24 10:01:40',NULL),(53,4,10,'2023-08-24 10:01:40',NULL),(54,4,9,'2023-08-24 10:01:40',NULL),(55,4,3,'2023-08-24 10:01:40',NULL),(56,4,11,'2023-08-24 10:01:40',NULL),(57,4,1,'2023-08-24 10:01:40',NULL),(58,3,1,'2023-08-24 10:42:56',NULL),(59,3,4,'2023-08-24 12:17:16',NULL),(60,17,12,'2023-08-24 12:20:04',NULL),(61,17,16,'2023-08-24 12:20:04',NULL),(62,17,2,'2023-08-24 12:20:04',NULL),(63,17,4,'2023-08-24 12:20:04',NULL),(64,17,9,'2023-08-24 12:20:04',NULL),(65,17,3,'2023-08-24 12:20:04',NULL),(66,17,11,'2023-08-24 12:20:04',NULL),(67,17,1,'2023-08-24 12:20:04',NULL),(68,18,10,'2023-08-27 20:45:06',NULL),(69,18,16,'2023-08-27 20:45:06',NULL),(70,18,2,'2023-08-27 20:45:06',NULL),(71,18,10,'2023-08-27 20:45:06',NULL),(72,18,9,'2023-08-27 20:45:06',NULL),(73,18,3,'2023-08-27 20:45:06',NULL),(74,18,11,'2023-08-27 20:45:06',NULL),(75,18,1,'2023-08-27 20:45:06',NULL),(79,16,2,'2023-09-04 10:31:45',NULL),(81,3,7,'2023-09-04 11:45:26',NULL);
/*!40000 ALTER TABLE `shipcall_participant_map` ENABLE KEYS */;
UNLOCK TABLES;
-- Exportiere Daten aus Tabelle bremen_calling.shipcall_tug_map: ~0 rows (ungefähr)
--
-- Dumping data for table `shipcall_tug_map`
--
LOCK TABLES `shipcall_tug_map` WRITE;
/*!40000 ALTER TABLE `shipcall_tug_map` DISABLE KEYS */;
/*!40000 ALTER TABLE `shipcall_tug_map` ENABLE KEYS */;
UNLOCK TABLES;
-- Exportiere Daten aus Tabelle bremen_calling.times: ~0 rows (ungefähr)
--
-- Dumping data for table `times`
--
LOCK TABLES `times` WRITE;
/*!40000 ALTER TABLE `times` DISABLE KEYS */;
INSERT INTO `times` (`id`, `eta_berth`, `eta_berth_fixed`, `etd_berth`, `etd_berth_fixed`, `lock_time`, `lock_time_fixed`, `zone_entry`, `zone_entry_fixed`, `operations_start`, `operations_end`, `remarks`, `shipcall_id`, `participant_id`, `created`, `modified`) VALUES
(1, '2023-05-18 07:18:19', NULL, '2023-05-18 09:18:19', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 3, 1, '2023-06-27 11:05:01', '2023-06-27 11:05:30');
INSERT INTO `times` VALUES (1,'2023-05-18 07:18:19',NULL,'2023-05-18 09:18:19',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,3,1,'2023-06-27 11:05:01','2023-06-27 11:05:30',NULL,NULL,NULL),(2,'2023-08-23 09:26:22',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'test',16,1,'0001-01-01 00:00:00',NULL,NULL,NULL,NULL),(3,NULL,NULL,NULL,NULL,'2023-08-24 09:32:18',NULL,NULL,NULL,NULL,NULL,'',16,1,'2023-08-23 09:32:21',NULL,NULL,NULL,NULL),(4,'2023-08-19 07:05:29',NULL,'2023-09-07 09:00:00',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Lotsenbemerkung von M.B.',3,2,'2023-08-24 07:05:39','2023-09-04 10:30:58',NULL,NULL,NULL),(5,'2023-08-19 08:30:30',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'früher wird das nichts',3,16,'2023-08-24 07:10:43','2023-08-24 07:11:04',NULL,NULL,NULL),(6,NULL,NULL,'2023-09-01 02:00:00',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'VB Blumenthal',4,9,'2023-08-24 12:29:48','2023-08-24 12:52:43',NULL,NULL,NULL),(7,'2023-09-01 03:30:00',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'VB Blexen, VB Blumenthal, \r\nFrüher geht es nicht',17,9,'2023-08-24 12:53:40','2023-08-24 12:55:20',NULL,NULL,NULL),(8,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Keine Schlepporder',10,9,'2023-08-24 12:58:18',NULL,NULL,NULL,NULL),(9,NULL,NULL,'2023-09-01 02:00:01',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',4,16,'2023-08-24 13:00:16',NULL,NULL,NULL,NULL),(10,'2023-09-01 10:00:32',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',10,16,'2023-08-24 13:00:39',NULL,NULL,NULL,NULL),(11,NULL,NULL,'2023-09-01 02:00:39',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',4,2,'2023-08-24 13:01:45',NULL,NULL,NULL,NULL),(12,'2023-09-01 03:00:52',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',17,2,'2023-08-24 13:01:59',NULL,NULL,NULL,NULL),(13,'2023-09-01 10:00:10',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',10,2,'2023-08-24 13:02:16','2023-09-04 09:11:45',NULL,NULL,NULL),(14,NULL,NULL,'2023-09-01 02:00:07',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',4,11,'2023-08-24 13:03:14',NULL,NULL,NULL,NULL),(15,'2023-09-01 03:00:20',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',17,11,'2023-08-24 13:03:27',NULL,NULL,NULL,NULL),(16,'2023-09-01 10:00:34',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',10,11,'2023-08-24 13:03:39',NULL,NULL,NULL,NULL),(17,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',17,4,'2023-08-24 13:05:11','2023-08-24 13:05:57',NULL,NULL,NULL),(18,'2023-09-01 02:00:35',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',4,10,'2023-08-24 13:06:45',NULL,NULL,NULL,NULL),(19,'2023-09-01 03:00:41',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',17,10,'2023-08-24 13:07:48',NULL,NULL,NULL,NULL),(20,NULL,NULL,'2023-09-01 02:00:02',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',4,10,'2023-08-24 13:08:10',NULL,NULL,NULL,NULL),(21,'2023-09-01 10:00:17',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',10,10,'2023-08-24 13:08:24',NULL,NULL,NULL,NULL),(22,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Klärung abwarten => 0300/0330?',17,16,'2023-08-24 13:08:53','2023-08-24 13:09:33',NULL,NULL,NULL),(23,NULL,NULL,'2023-09-01 03:00:43',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',18,11,'2023-08-27 20:45:49',NULL,NULL,NULL,NULL),(24,NULL,NULL,'2023-09-01 03:00:21',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',18,10,'2023-08-27 20:46:25',NULL,NULL,NULL,NULL),(25,'2023-09-01 13:23:12',_binary '','2023-09-03 03:00:51',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'es geht nicht früher!',18,2,'2023-08-27 20:46:54','2023-09-01 13:25:39',NULL,NULL,NULL),(26,NULL,NULL,'2023-09-01 03:00:34',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',18,9,'2023-08-27 20:47:40',NULL,NULL,NULL,NULL),(27,NULL,NULL,'2023-09-01 03:00:00',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',18,16,'2023-08-27 20:48:05',NULL,NULL,NULL,NULL);
/*!40000 ALTER TABLE `times` ENABLE KEYS */;
UNLOCK TABLES;
-- Exportiere Daten aus Tabelle bremen_calling.user: ~21 rows (ungefähr)
--
-- Dumping data for table `user`
--
LOCK TABLES `user` WRITE;
/*!40000 ALTER TABLE `user` DISABLE KEYS */;
INSERT INTO `user` (`id`, `participant_id`, `first_name`, `last_name`, `user_name`, `user_email`, `user_phone`, `password_hash`, `api_key`, `created`, `modified`) VALUES
(1, 1, 'Daniel', 'Schick', 'dani', NULL, NULL, '$2b$12$qfjw4b3XvGuu0t6HR8OYGOzF5b8gmC6PyIIBNbIXMXEayJunEEKmi', '0815', '2023-04-17 07:15:41', '2023-08-11 11:11:34'),
(2, 1, 'Londo', 'Mollari', 'Londo', 'l.mollari@centauri.gov', '+01 555 324 2313', '$2b$12$VwmwvO2dxlOixWc1HjX3j.753SDJTMR.o7av/bVGTM2tLW2jQT0yy', NULL, '2023-06-27 08:34:55', NULL),
(3, 2, 'Maik', 'Baudeck', 'maikb', NULL, NULL, '$2b$12$4SxGRlinOrpEVvqDZcE.wOusMZYsepdc6vj1vDpNhbPtApxU8VGPi', '', '2023-08-10 07:09:35', '2023-08-11 11:11:55'),
(4, 3, 'Christin', 'Hollmann', 'christinh', NULL, NULL, '$2b$12$ul0QJmcuUhktDYDjcyEpx.6yY1ieLdaCxZ6a3SFSuTq94IqK4Y/re', '', '2023-08-10 07:12:05', '2023-08-11 11:10:33'),
(5, 3, 'Bastian', 'Güttner', 'bastiang', NULL, NULL, '$2b$12$0oCX3c2WyMykmxMoLqmpNubke713xhYlEEQgnxBV6Fj/TaUn.3/U6', '', '2023-08-10 07:12:26', '2023-08-11 11:11:13'),
(6, 3, 'Benjamin', 'Wiese', 'benjaminw', NULL, NULL, '$2b$12$RRj32KdLIf3D7z7cVWFqa.yZM5.ODOS0HqU3rdCuFrJS8HJ/rtqwy', '', '2023-08-10 07:13:01', '2023-08-11 11:11:16'),
(7, 1, 'Sladjan', 'Veselinovic', 'sladjanv', NULL, NULL, '$2b$12$4DctoCbZwxTvE39lXNRzneQ2kb/lXlJ5wEZ1CGbbw.rGM3nuAYjpa', '', '2023-08-10 07:13:39', '2023-08-11 11:11:45'),
(8, 1, 'Kersten', 'Gevers', 'kersteng', NULL, NULL, '$2b$12$zKX8iLPnXRmp5wD1Yp8P7e..U9R0A4ytbiMjd.l.IGkMzahcHPNWq', '', '2023-08-10 07:13:59', '2023-08-11 11:11:49'),
(9, 4, 'Dirk', 'Brunnert', 'dirkb', NULL, NULL, '$2b$12$HTeq/Fdfse6oElk7DLsQae5dtvWJloee.VtBH.THsj2kdcxxBkCDW', '', '2023-08-10 07:15:01', '2023-08-11 11:12:01'),
(10, 5, 'Thorsten', 'Fischer', 'thorstenf', NULL, NULL, '$2b$12$NHEpTNHuKU4ruPRIfd9yc.yv5faHGemFfRI3TISniqM7QNqHiyZpK', '', '2023-08-10 07:16:20', '2023-08-11 11:12:07'),
(11, 6, 'Lisa', 'Friedhoff', 'lisaf', NULL, NULL, '$2b$12$DJKJHGrQwfY9pwzgFfPds.DHGsygHyV3KDs38Hq4AUHPPs3jBPH3y', '', '2023-08-10 07:19:52', '2023-08-11 11:12:12'),
(12, 6, 'Dario', 'Fritschi', 'dariof', NULL, NULL, '$2b$12$MwCVTMQkN6zCAzCsE572Ye.M0nRDQNld4AgorLVyWq.DcQEmAy5lu', '', '2023-08-10 07:20:11', '2023-08-11 11:12:15'),
(13, 7, 'Hergen', 'Hanke', 'hergenh', NULL, NULL, '$2b$12$MKb6BDRrTbNd0qg5BdAS.upzlqxcWOgU/VEafJKSuzE9JLIWCimq6', '', '2023-08-10 07:22:09', '2023-08-11 11:12:24'),
(14, 8, 'Hardy', 'Paasch', 'hardyp', NULL, NULL, '$2b$12$l1lE/UqnYnOvci.N4j3zBOz6HC0z87ovnO0n6BIZYO7VN8gj.qGey', '', '2023-08-10 07:23:25', '2023-08-11 11:12:28'),
(15, 8, 'Marc', 'Pagel', 'marcp', NULL, NULL, '$2b$12$UCVJKzqX92Z8xZJ4kK0BRuFXMRdqcaXaGmBrqnYWARdKlPvZvLUZq', '', '2023-08-10 07:23:41', '2023-08-11 11:12:30'),
(16, 9, 'Andreas', 'Peukert', 'andreasp', NULL, NULL, '$2b$12$jNmciJAVR6p0IflvAthmk.j0SoOBvFHwDiEDKUHfwJq7baRsKg/LG', '', '2023-08-10 07:24:37', '2023-08-11 11:12:45'),
(17, 8, 'Christina', 'Rachiele', 'christinar', NULL, NULL, '$2b$12$BCsVgPRuIWPuuor07lprF.klQxvF901O3AXUhRrBJoEvYIjNQ.HKS', '', '2023-08-10 07:25:05', '2023-08-11 11:12:33'),
(18, 9, 'Sonia', 'Rekawek', 'soniar', NULL, NULL, '$2b$12$uHCkH6gu13yqllXBibLFIOWOpvctMC7NmojtXqDd6xsLq7bmvNOMu', '', '2023-08-10 07:25:27', '2023-08-11 11:12:48'),
(19, 6, 'Frank', 'Roelfs', 'frankr', NULL, NULL, '$2b$12$cEQAhUe9VJV6uTkfOY6/R.oAVfmFZQ4vS5G6BqoNEyaVHtFRDtB56', '', '2023-08-10 07:26:04', '2023-08-11 11:12:19'),
(20, 10, 'Vera', 'Schliedermann', 'veras', NULL, NULL, '$2b$12$FKcitW6W1HPwd.cdkZLGLeTFuzjsEIrbiKInysAKN.RibZ4gVLZHi', '', '2023-08-10 07:27:01', '2023-08-11 11:12:54'),
(21, 8, 'Michael', 'Strudthoff', 'michaels', NULL, NULL, '$2b$12$doTiywWpkso1UWB5eiAW1eoACP6rN4UDVt7qFFdRFvhhWUXikCmS2', '', '2023-08-10 07:27:27', '2023-08-11 11:12:37'),
(22, 4, 'Volker', 'Viohl', 'volkerv', NULL, NULL, '$2b$12$.YavQbWNE4eJDQA.ZNSKROYvMPWifBXyMX0IL0H2z50M720fpfTJW', '', '2023-08-10 07:27:50', '2023-08-11 11:12:04'),
(23, 11, 'Frauke', 'Zabel', 'fraukez', NULL, NULL, '$2b$12$rawQg6Cjl1yECGm9DOG8degdWdD.nZjEgGp8eXO98nh11QV1sEEEO', '', '2023-08-10 07:28:33', '2023-08-11 11:12:58'),
(24, 8, 'Jan', 'Zierow', 'janz', NULL, NULL, '$2b$12$CbnjUT42cf0mkIAqAURg3OksP9G3brmsE2GQTECTZ4.cVuhPn5D2G', '', '2023-08-10 07:28:55', '2023-08-11 11:12:39');
INSERT INTO `user` VALUES (1,1,'Daniel','Schick','dani',NULL,NULL,'$2b$12$qfjw4b3XvGuu0t6HR8OYGOzF5b8gmC6PyIIBNbIXMXEayJunEEKmi','0815','2023-04-17 07:15:41','2023-08-11 11:11:34'),(2,1,'Londo','Mollari','Londo','l.mollari@centauri.gov','+01 555 324 2313','$2b$12$P7MkcbOzmp7Wxsl8Ip5tg.KvMlvQEdFZN6AoM1Ze54.kvjYZxSizy',NULL,'2023-06-27 08:34:55','2023-09-04 13:36:34'),(3,2,'Maik','Baudeck','maikb',NULL,NULL,'$2b$12$4SxGRlinOrpEVvqDZcE.wOusMZYsepdc6vj1vDpNhbPtApxU8VGPi','','2023-08-10 07:09:35','2023-08-11 11:11:55'),(4,3,'Christin','Hollmann','christinh',NULL,NULL,'$2b$12$ul0QJmcuUhktDYDjcyEpx.6yY1ieLdaCxZ6a3SFSuTq94IqK4Y/re','','2023-08-10 07:12:05','2023-08-11 11:10:33'),(5,3,'Bastian','Güttner','bastiang',NULL,NULL,'$2b$12$0oCX3c2WyMykmxMoLqmpNubke713xhYlEEQgnxBV6Fj/TaUn.3/U6','','2023-08-10 07:12:26','2023-08-11 11:11:13'),(6,3,'Benjamin','Wiese','benjaminw',NULL,NULL,'$2b$12$RRj32KdLIf3D7z7cVWFqa.yZM5.ODOS0HqU3rdCuFrJS8HJ/rtqwy','','2023-08-10 07:13:01','2023-08-11 11:11:16'),(7,1,'Sladjan','Veselinovic','sladjanv',NULL,NULL,'$2b$12$4DctoCbZwxTvE39lXNRzneQ2kb/lXlJ5wEZ1CGbbw.rGM3nuAYjpa','','2023-08-10 07:13:39','2023-08-11 11:11:45'),(8,1,'Kersten','Gevers','kersteng',NULL,NULL,'$2b$12$zKX8iLPnXRmp5wD1Yp8P7e..U9R0A4ytbiMjd.l.IGkMzahcHPNWq','','2023-08-10 07:13:59','2023-08-11 11:11:49'),(9,4,'Dirk','Brunnert','dirkb',NULL,NULL,'$2b$12$HTeq/Fdfse6oElk7DLsQae5dtvWJloee.VtBH.THsj2kdcxxBkCDW','','2023-08-10 07:15:01','2023-08-11 11:12:01'),(10,5,'Thorsten','Fischer','thorstenf',NULL,NULL,'$2b$12$NHEpTNHuKU4ruPRIfd9yc.yv5faHGemFfRI3TISniqM7QNqHiyZpK','','2023-08-10 07:16:20','2023-08-11 11:12:07'),(11,6,'Lisa','Friedhoff','lisaf',NULL,NULL,'$2b$12$DJKJHGrQwfY9pwzgFfPds.DHGsygHyV3KDs38Hq4AUHPPs3jBPH3y','','2023-08-10 07:19:52','2023-08-11 11:12:12'),(12,6,'Dario','Fritschi','dariof',NULL,NULL,'$2b$12$MwCVTMQkN6zCAzCsE572Ye.M0nRDQNld4AgorLVyWq.DcQEmAy5lu','','2023-08-10 07:20:11','2023-08-11 11:12:15'),(13,7,'Hergen','Hanke','hergenh',NULL,NULL,'$2b$12$MKb6BDRrTbNd0qg5BdAS.upzlqxcWOgU/VEafJKSuzE9JLIWCimq6','','2023-08-10 07:22:09','2023-08-11 11:12:24'),(14,8,'Hardy','Paasch','hardyp',NULL,NULL,'$2b$12$l1lE/UqnYnOvci.N4j3zBOz6HC0z87ovnO0n6BIZYO7VN8gj.qGey','','2023-08-10 07:23:25','2023-08-11 11:12:28'),(15,8,'Marc','Pagel','marcp',NULL,NULL,'$2b$12$UCVJKzqX92Z8xZJ4kK0BRuFXMRdqcaXaGmBrqnYWARdKlPvZvLUZq','','2023-08-10 07:23:41','2023-08-11 11:12:30'),(16,9,'Andreas','Peukert','andreasp',NULL,NULL,'$2b$12$jNmciJAVR6p0IflvAthmk.j0SoOBvFHwDiEDKUHfwJq7baRsKg/LG','','2023-08-10 07:24:37','2023-08-11 11:12:45'),(17,8,'Christina','Rachiele','christinar',NULL,NULL,'$2b$12$BCsVgPRuIWPuuor07lprF.klQxvF901O3AXUhRrBJoEvYIjNQ.HKS','','2023-08-10 07:25:05','2023-08-11 11:12:33'),(18,9,'Sonia','Rekawek','soniar',NULL,NULL,'$2b$12$uHCkH6gu13yqllXBibLFIOWOpvctMC7NmojtXqDd6xsLq7bmvNOMu','','2023-08-10 07:25:27','2023-08-11 11:12:48'),(19,6,'Frank','Roelfs','frankr',NULL,NULL,'$2b$12$cEQAhUe9VJV6uTkfOY6/R.oAVfmFZQ4vS5G6BqoNEyaVHtFRDtB56','','2023-08-10 07:26:04','2023-08-11 11:12:19'),(20,10,'Vera','Schliedermann','veras',NULL,NULL,'$2b$12$FKcitW6W1HPwd.cdkZLGLeTFuzjsEIrbiKInysAKN.RibZ4gVLZHi','','2023-08-10 07:27:01','2023-08-11 11:12:54'),(21,8,'Michael','Strudthoff','michaels',NULL,NULL,'$2b$12$doTiywWpkso1UWB5eiAW1eoACP6rN4UDVt7qFFdRFvhhWUXikCmS2','','2023-08-10 07:27:27','2023-08-11 11:12:37'),(22,4,'Volker','Viohl','volkerv',NULL,NULL,'$2b$12$.YavQbWNE4eJDQA.ZNSKROYvMPWifBXyMX0IL0H2z50M720fpfTJW','','2023-08-10 07:27:50','2023-08-11 11:12:04'),(23,11,'Frauke','Zabel','fraukez',NULL,NULL,'$2b$12$rawQg6Cjl1yECGm9DOG8degdWdD.nZjEgGp8eXO98nh11QV1sEEEO','','2023-08-10 07:28:33','2023-08-11 11:12:58'),(24,8,'Jan','Zierow','janz',NULL,NULL,'$2b$12$CbnjUT42cf0mkIAqAURg3OksP9G3brmsE2GQTECTZ4.cVuhPn5D2G','','2023-08-10 07:28:55','2023-08-11 11:12:39'),(25,12,'Berit','Güstrau','beritg',NULL,NULL,'$2b$12$g8WJTEWwsrtMyqpVW/GFVuzyRjB2/n0YJJyvBx.3l51YiVEUjEQYy','','2023-08-21 06:52:35',NULL),(26,15,'Ilknur','Colmorn','ilknurc',NULL,NULL,'$2b$12$tpEb0JQ8Li4YkPH28FeYk.1Jt2vK.TFn9SyhBKJ08gn7S5d8WYRlO','','2023-08-21 06:56:42',NULL),(27,16,'Horst','Imgram','horsti',NULL,NULL,'$2b$12$05NFPSaP78puAa8pL39KrOKTafs/TzWwr4YfV4/Vrdu90assvNFZa','','2023-08-21 06:57:58',NULL);
/*!40000 ALTER TABLE `user` ENABLE KEYS */;
UNLOCK TABLES;
-- Exportiere Daten aus Tabelle bremen_calling.user_role_map: ~0 rows (ungefähr)
--
-- Dumping data for table `user_role_map`
--
LOCK TABLES `user_role_map` WRITE;
/*!40000 ALTER TABLE `user_role_map` DISABLE KEYS */;
/*!40000 ALTER TABLE `user_role_map` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2023-09-05 10:38:13

View File

@ -7,7 +7,7 @@
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:p = "clr-namespace:BreCalClient.Resources"
mc:Ignorable="d"
Title="Help" Height="270" Width="500">
Title="Help" Height="280" Width="500">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="180" />

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="BreCalClient.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="BreCalClient.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<BreCalClient.Properties.Settings>
<setting name="API_URL" serializeAs="String">
<value>https://brecaltest.bsmd-emswe.eu</value>
</setting>
<setting name="BG_COLOR" serializeAs="String">
<value>#751D1F</value>
</setting>
<setting name="APP_TITLE" serializeAs="String">
<value>!!Bremen calling Testversion!!</value>
</setting>
<setting name="LOGO_IMAGE_URL" serializeAs="String">
<value>https://www.textbausteine.net/</value>
</setting>
</BreCalClient.Properties.Settings>
</applicationSettings>
<userSettings>
<BreCalClient.Properties.Settings>
<setting name="FilterCriteria" serializeAs="String">
<value />
</setting>
</BreCalClient.Properties.Settings>
</userSettings>
</configuration>

View File

@ -7,24 +7,28 @@
<UseWPF>true</UseWPF>
<SignAssembly>True</SignAssembly>
<StartupObject>BreCalClient.App</StartupObject>
<AssemblyOriginatorKeyFile>E:\gitlager\git_brcal\misc\brecal.snk</AssemblyOriginatorKeyFile>
<AssemblyVersion>0.3.0.0</AssemblyVersion>
<FileVersion>0.3.0.0</FileVersion>
<AssemblyOriginatorKeyFile>..\..\misc\brecal.snk</AssemblyOriginatorKeyFile>
<AssemblyVersion>0.7.0.0</AssemblyVersion>
<FileVersion>0.7.0.0</FileVersion>
<Title>Bremen calling client</Title>
<Description>A Windows WPF client for the Bremen calling API.</Description>
<ApplicationIcon>containership.ico</ApplicationIcon>
<AssemblyName>BreCalTestClient</AssemblyName>
</PropertyGroup>
<ItemGroup>
<None Remove="Resources\arrow_down_green.png" />
<None Remove="Resources\arrow_down_red.png" />
<None Remove="Resources\arrow_right_blue.png" />
<None Remove="Resources\arrow_right_green.png" />
<None Remove="Resources\arrow_up_blue.png" />
<None Remove="Resources\arrow_up_green.png" />
<None Remove="Resources\arrow_up_red.png" />
<None Remove="Resources\clipboard.png" />
<None Remove="Resources\clock.png" />
<None Remove="Resources\containership.ico" />
<None Remove="Resources\containership.png" />
<None Remove="Resources\delete.png" />
<None Remove="Resources\emergency_stop_button.png" />
<None Remove="Resources\logo_bremen_calling.png" />
<None Remove="Resources\ship2.png" />
@ -64,12 +68,15 @@
<Resource Include="Resources\arrow_down_green.png" />
<Resource Include="Resources\arrow_down_red.png" />
<Resource Include="Resources\arrow_right_blue.png" />
<Resource Include="Resources\arrow_right_green.png" />
<Resource Include="Resources\arrow_up_blue.png" />
<Resource Include="Resources\arrow_up_green.png" />
<Resource Include="Resources\arrow_up_red.png" />
<Resource Include="Resources\clipboard.png" />
<Resource Include="Resources\clock.png" />
<Resource Include="Resources\containership.ico" />
<Resource Include="Resources\containership.png" />
<Resource Include="Resources\delete.png" />
<Resource Include="Resources\emergency_stop_button.png" />
<Resource Include="Resources\logo_bremen_calling.png" />
<Resource Include="Resources\ship2.png" />
@ -89,15 +96,20 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Extended.Wpf.Toolkit" Version="4.5.0" />
<PackageReference Include="Extended.Wpf.Toolkit" Version="4.5.1" />
<PackageReference Include="JsonSubTypes" Version="2.0.1" />
<PackageReference Include="log4net" Version="2.0.15" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Polly" Version="7.2.3" />
<PackageReference Include="RestSharp" Version="108.0.2" />
<PackageReference Include="Polly" Version="7.2.4" />
<PackageReference Include="RestSharp" Version="110.2.0" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Settings.Designer.cs">
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Update="Resources\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
@ -112,4 +124,11 @@
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Update="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,123 @@
// Copyright (c) 2023 schick Informatik
// Description: Static lists used everywhere
//
using BreCalClient.misc.Model;
using System.Collections.Concurrent;
using System.Collections.Generic;
namespace BreCalClient
{
public static class BreCalLists
{
#region Fields
private static readonly List<Participant> aList = new();
private static readonly List<Participant> mList = new();
private static readonly List<Participant> pList = new();
private static readonly List<Participant> tList = new();
private static readonly List<Participant> terList = new();
private static List<Berth> _berths = new();
private static List<Participant> _participants = new();
private static List<Ship> _ships = new();
private readonly static ConcurrentDictionary<int, Ship> _shipLookupDict = new();
private readonly static ConcurrentDictionary<int, Berth> _berthLookupDict = new();
private readonly static Dictionary<int, Participant> _participantLookupDict = new();
#endregion
#region Properties
public static ConcurrentDictionary<int, Ship> ShipLookupDict { get { return _shipLookupDict; } }
public static ConcurrentDictionary<int, Berth> BerthLookupDict { get { return _berthLookupDict; } }
public static Dictionary<int, Participant> ParticipantLookupDict { get { return _participantLookupDict; } }
/// <summary>
/// Participants that are agents
/// </summary>
public static List<Participant> Participants_Agent { get { return aList; } }
/// <summary>
/// Participants that are mooring companies
/// </summary>
public static List<Participant> Participants_Mooring { get { return mList; } }
/// <summary>
/// Participants that are pilots
/// </summary>
public static List<Participant> Participants_Pilot { get { return pList; } }
/// <summary>
/// Participants that are tug shipping companies
/// </summary>
public static List<Participant> Participants_Tug { get { return tList; } }
/// <summary>
/// Participants that are terminals
/// </summary>
public static List<Participant> Participants_Terminal { get { return terList; } }
/// <summary>
/// All participants
/// </summary>
public static List<Participant> Participants { get { return _participants; } }
/// <summary>
/// All berths
/// </summary>
public static List<Berth> Berths { get { return _berths; } }
/// <summary>
/// All ships
/// </summary>
public static List<Ship> Ships { get { return _ships; } }
#endregion
#region methods
internal static void InitializeParticipants(List<Participant> participants)
{
_participants = participants;
aList.Clear();
mList.Clear();
pList.Clear();
tList.Clear();
terList.Clear();
foreach (Participant p in participants)
{
_participantLookupDict[p.Id] = p;
if (p.IsTypeFlagSet(Extensions.ParticipantType.AGENCY)) aList.Add(p);
if (p.IsTypeFlagSet(Extensions.ParticipantType.MOORING)) mList.Add(p);
if (p.IsTypeFlagSet(Extensions.ParticipantType.PILOT)) pList.Add(p);
if (p.IsTypeFlagSet(Extensions.ParticipantType.TUG)) tList.Add(p);
if (p.IsTypeFlagSet(Extensions.ParticipantType.TERMINAL)) terList.Add(p);
}
}
internal static void InitializeBerths(List<Berth> berths)
{
foreach (var berth in berths)
_berthLookupDict[berth.Id] = berth;
_berths = berths;
}
internal static void InitializeShips(List<Ship> ships)
{
foreach (var ship in ships)
_shipLookupDict[ship.Id] = ship;
_ships = ships;
}
#endregion
}
}

View File

@ -8,7 +8,7 @@
xmlns:db="clr-namespace:BreCalClient;assembly=BreCalClient"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
mc:Ignorable="d"
Title="{x:Static p:Resources.textEditShipcall}" Height="466" Width="800" Loaded="Window_Loaded" ResizeMode="NoResize" Icon="Resources/containership.ico">
Title="{x:Static p:Resources.textEditShipcall}" Height="214" Width="800" Loaded="Window_Loaded" ResizeMode="NoResize" Icon="Resources/containership.ico">
<Window.Resources>
<local:BoolToIndexConverter x:Key="boolToIndexConverter" />
</Window.Resources>
@ -26,94 +26,75 @@
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
</Grid.RowDefinitions>
<Label Content="{x:Static p:Resources.textShip}" Grid.Column="0" Grid.Row="0" HorizontalContentAlignment="Right"/>
<Label Content="{x:Static p:Resources.textType}" Grid.Column="0" Grid.Row="1" HorizontalContentAlignment="Right" />
<Label Content="ETA" Grid.Column="0" Grid.Row="2" HorizontalContentAlignment="Right"/>
<Label Content="{x:Static p:Resources.textVoyage}" Grid.Column="0" Grid.Row="3" HorizontalContentAlignment="Right"/>
<Label Content="ETD" Grid.Column="0" Grid.Row="4" HorizontalContentAlignment="Right"/>
<Label Content="{x:Static p:Resources.textArrivalTerminal}" Grid.Column="0" Grid.Row="5" HorizontalContentAlignment="Right"/>
<Label Content="{x:Static p:Resources.textDepartureTerminal}" Grid.Column="0" Grid.Row="6" HorizontalContentAlignment="Right"/>
<Label Content="{x:Static p:Resources.textTugRequired}" Grid.Column="1" Grid.Row="7" />
<Label Content="{x:Static p:Resources.textPilotRequired}" Grid.Column="1" Grid.Row="8" />
<Label Content="{x:Static p:Resources.textPierside}" Grid.Column="0" Grid.Row="9" HorizontalContentAlignment="Right" />
<Label Content="{x:Static p:Resources.textBunkering}" Grid.Column="1" Grid.Row="10" />
<Label Content="{x:Static p:Resources.textReplenishingTerminal}" Grid.Column="1" Grid.Row="11" />
<Label Content="{x:Static p:Resources.textReplenishingLock}" Grid.Column="1" Grid.Row="12" />
<Label Content="{x:Static p:Resources.textDraft}" Grid.Column="0" Grid.Row="13" HorizontalContentAlignment="Right" />
<ComboBox x:Name="comboBoxShip" Margin="2" Grid.Column="1" Grid.Row="0" SelectionChanged="comboBoxShip_SelectionChanged" SelectedValuePath="Id">
<ComboBox.ItemTemplate>
<DataTemplate>
<!--Border-->
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} ({1})">
<Binding Path="Name" />
<Binding Path="Imo" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} ({1})">
<Binding Path="Name" />
<Binding Path="Imo" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
<!--/Border-->
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<ComboBox x:Name="comboBoxCategories" Grid.Column="1" Margin="2" Grid.Row="1" SelectedValuePath="Key"/>
<xctk:DateTimePicker x:Name="datePickerETA" Grid.Column="1" Grid.Row="2" Margin="2" />
<TextBox x:Name="textBoxVoyage" Grid.Column="1" Grid.Row="3" Margin="2" VerticalContentAlignment="Center" />
<xctk:DateTimePicker x:Name="datePickerETD" Grid.Column="1" Grid.Row="4" Margin="2" />
<ComboBox Name="comboBoxArrivalBerth" Grid.Column="1" Grid.Row="5" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id" />
<ComboBox Name="comboBoxDepartureBerth" Grid.Column="1" Grid.Row="6" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id" />
<CheckBox x:Name="checkBoxTugRequired" Grid.Column="0" Grid.Row="7" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,4,0" />
<CheckBox x:Name="checkBoxPilotRequired" Grid.Column="0" Grid.Row="8" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,4,0" />
<ComboBox x:Name="comboBoxPierside" Grid.Column="1" Grid.Row="9" Margin="2" >
<ComboBoxItem Content="{x:Static p:Resources.textNotRotated}" />
<ComboBoxItem Content="{x:Static p:Resources.textRotated}" />
<Label Content="IMO" Grid.Column="0" Grid.Row="1" HorizontalContentAlignment="Right"/>
<xctk:IntegerUpDown x:Name="integerUpDownIMO" IsReadOnly="True" Margin="2" Grid.Column="1" Grid.Row="1" />
<Label Content="{x:Static p:Resources.textCallsign}" Grid.Column="0" Grid.Row="2" HorizontalContentAlignment="Right"/>
<TextBox x:Name="textBoxCallsign" IsReadOnly="True" Grid.Column="1" Grid.Row="2" Margin="2" />
<Label Content="{x:Static p:Resources.textLength}" Grid.Column="0" Grid.Row="3" HorizontalContentAlignment="Right"/>
<xctk:DoubleUpDown x:Name="doubleUpDownLength" Margin="2" Grid.Column="1" Grid.Row="3" FormatString="N2" IsReadOnly="True" />
<Label Content="{x:Static p:Resources.textWidth}" Grid.Column="0" Grid.Row="4" HorizontalContentAlignment="Right"/>
<xctk:DoubleUpDown x:Name="doubleUpDownWidth" Margin="2" Grid.Column="1" Grid.Row="4" FormatString="N2" IsReadOnly="True" />
<Label Content="{x:Static p:Resources.textType}" Grid.Column="2" Grid.Row="0" HorizontalContentAlignment="Right" />
<Label Content="ETA" Grid.Column="2" Grid.Row="2" HorizontalContentAlignment="Right"/>
<Label Content="ETD" Grid.Column="2" Grid.Row="3" HorizontalContentAlignment="Right"/>
<ComboBox x:Name="comboBoxCategories" Grid.Column="3" Margin="2" Grid.Row="0" SelectedValuePath="Key" SelectionChanged="comboBoxCategories_SelectionChanged"/>
<xctk:DateTimePicker x:Name="datePickerETA" Grid.Column="3" Grid.Row="2" Margin="2" Format="Custom" FormatString="dd.MM. yyyy HH:mm" IsEnabled="False"/>
<xctk:DateTimePicker x:Name="datePickerETD" Grid.Column="3" Grid.Row="3" Margin="2" Format="Custom" FormatString="dd.MM. yyyy HH:mm" IsEnabled="False"/>
<Label Content="{x:Static p:Resources.textBerth}" Grid.Column="2" Grid.Row="1" HorizontalContentAlignment="Right"/>
<Grid Grid.Row="1" Grid.Column="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".5*" />
<ColumnDefinition Width=".5*" />
</Grid.ColumnDefinitions>
<ComboBox Name="comboBoxArrivalBerth" Grid.Column="0" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id">
<ComboBox.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemArrivalBerth" Click="contextMenuItemArrivalBerth_Click" />
</ContextMenu>
</ComboBox.ContextMenu>
</ComboBox>
<ComboBox Name="comboBoxDepartureBerth" Grid.Column="1" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id">
<ComboBox.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemDepartureBerth" Click="contextMenuItemDepartureBerth_Click" />
</ContextMenu>
</ComboBox.ContextMenu>
</ComboBox>
</Grid>
<Label Content="{x:Static p:Resources.textAgency}" Grid.Column="2" Grid.Row="4" HorizontalContentAlignment="Right"/>
<ComboBox Name="comboBoxAgency" Grid.Column="3" Grid.Row="4" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id" SelectionChanged="comboBoxAgency_SelectionChanged">
<ComboBox.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearAssignment}" Name="contextMenuItemClearAgency" Click="contextMenuItemClearAgency_Click" />
</ContextMenu>
</ComboBox.ContextMenu>
</ComboBox>
<CheckBox x:Name="checkBoxBunkering" Grid.Column="0" Grid.Row="10" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,4,0" />
<CheckBox x:Name="checkBoxReplenishingTerminal" Grid.Column="0" Grid.Row="11" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,4,0" />
<CheckBox x:Name="checkBoxReplenishingLock" Grid.Column="0" Grid.Row="12" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,4,0" />
<xctk:DoubleUpDown x:Name="doubleUpDownDraft" Grid.Column="1" Grid.Row="13" Margin="2" FormatString="N2" Minimum="0" />
<Label Content="{x:Static p:Resources.textParticipants}" FontWeight="DemiBold" Grid.Column="3" Grid.Row="0" />
<Label Content="{x:Static p:Resources.textAgency}" Grid.Column="2" Grid.Row="1" HorizontalContentAlignment="Right"/>
<Label Content="{x:Static p:Resources.textMooring}" Grid.Column="2" Grid.Row="2" HorizontalContentAlignment="Right"/>
<Label Content="{x:Static p:Resources.textPilot}" Grid.Column="2" Grid.Row="3" HorizontalContentAlignment="Right"/>
<Label Content="{x:Static p:Resources.textTug}" Grid.Column="2" Grid.Row="4" HorizontalContentAlignment="Right"/>
<Label Content="{x:Static p:Resources.textTerminal}" Grid.Column="2" Grid.Row="5" HorizontalContentAlignment="Right"/>
<Label Content="{x:Static p:Resources.textTidalWindow}" FontWeight="DemiBold" Grid.Column="3" Grid.Row="6" />
<Label Content="{x:Static p:Resources.textFrom}" Grid.Column="2" Grid.Row="7" HorizontalContentAlignment="Right"/>
<Label Content="{x:Static p:Resources.textTo}" Grid.Column="2" Grid.Row="8" HorizontalContentAlignment="Right"/>
<Label Content="{x:Static p:Resources.textRainSensitiveCargo}" Grid.Column="3" Grid.Row="9" />
<Label Content="{x:Static p:Resources.textRecommendedTugs}" Grid.Column="2" Grid.Row="10" HorizontalContentAlignment="Right"/>
<Label Content="{x:Static p:Resources.textAnchored}" Grid.Column="3" Grid.Row="11" />
<Label Content="{x:Static p:Resources.textMooredLock}" Grid.Column="3" Grid.Row="12" />
<Label Content="{x:Static p:Resources.textCancelled}" Grid.Column="3" Grid.Row="13" />
<ComboBox Name="comboBoxAgency" Grid.Column="3" Grid.Row="1" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id"/>
<ComboBox Name="comboBoxMooring" Grid.Column="3" Grid.Row="2" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id"/>
<ComboBox Name="comboBoxPilot" Grid.Column="3" Grid.Row="3" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id"/>
<ComboBox Name="comboBoxTug" Grid.Column="3" Grid.Row="4" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id"/>
<ComboBox Name="comboBoxTerminal" Grid.Column="3" Grid.Row="5" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id"/>
<xctk:DateTimePicker Name="datePickerTidalWindowFrom" Grid.Column="3" Grid.Row="7" Margin="2" />
<xctk:DateTimePicker Name="datePickerTidalWindowTo" Grid.Column="3" Grid.Row="8" Margin="2" />
<CheckBox x:Name="checkBoxRainsensitiveCargo" Grid.Column="2" Grid.Row="9" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,4,0" />
<xctk:IntegerUpDown x:Name="integerUpDownRecommendedTugs" Grid.Column="3" Grid.Row="10" Minimum="0" Margin="2" />
<CheckBox x:Name="checkBoxAnchored" Grid.Column="2" Grid.Row="11" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,4,0" />
<CheckBox x:Name="checkBoxMooredLock" Grid.Column="2" Grid.Row="12" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,4,0" />
<CheckBox x:Name="checkBoxCanceled" Grid.Column="2" Grid.Row="13" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,4,0" />
<Label x:Name="labelBSMDGranted" Grid.Row="14" Grid.Column="1" Grid.ColumnSpan="2" Content="{x:Static p:Resources.textBSMDGranted}" Visibility="Hidden" FontWeight="DemiBold" />
<StackPanel Grid.Row="14" Grid.Column="3" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Width= "80" Margin="2" Content="{x:Static p:Resources.textOK}" x:Name="buttonOK" Click="buttonOK_Click" IsEnabled="False" />
<Button Width="80" Margin="2" Content="{x:Static p:Resources.textCancel}" x:Name="buttonCancel" Click="buttonCancel_Click"/>

View File

@ -8,6 +8,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using static BreCalClient.Extensions;
namespace BreCalClient
{
@ -23,13 +24,7 @@ namespace BreCalClient
#region Properties
public Shipcall Shipcall { get; set; } = new ();
public List<Participant> Participants { get; set; } = new();
public List<Berth> Berths { get; set; } = new();
public List<Ship> Ships { get; set; } = new();
public ShipcallControlModel ShipcallModel { get; set; } = new ();
public Ship? SelectedShip {
get
@ -44,33 +39,17 @@ namespace BreCalClient
private void Window_Loaded(object sender, RoutedEventArgs e)
{
List<Participant> aList = new();
List<Participant> mList = new();
List<Participant> pList = new();
List<Participant> tList = new();
List<Participant> terList = new();
this.comboBoxAgency.ItemsSource = BreCalLists.Participants_Agent;
foreach(Participant p in Participants)
{
if (p.IsFlagSet(Extensions.ParticipantType.AGENCY)) aList.Add(p);
if (p.IsFlagSet(Extensions.ParticipantType.MOORING)) mList.Add(p);
if (p.IsFlagSet(Extensions.ParticipantType.PILOT)) pList.Add(p);
if (p.IsFlagSet(Extensions.ParticipantType.TUG)) tList.Add(p);
if (p.IsFlagSet(Extensions.ParticipantType.TERMINAL)) terList.Add(p);
}
this.comboBoxAgency.ItemsSource = aList;
this.comboBoxMooring.ItemsSource = mList;
this.comboBoxPilot.ItemsSource = pList;
this.comboBoxTug.ItemsSource = tList;
this.comboBoxTerminal.ItemsSource = terList;
this.comboBoxShip.ItemsSource = Ships;
this.comboBoxShip.ItemsSource = BreCalLists.Ships;
this.comboBoxCategories.ItemsSource = Enum.GetValues(typeof(Extensions.TypeEnum));
this.comboBoxArrivalBerth.ItemsSource = this.Berths;
this.comboBoxDepartureBerth.ItemsSource = this.Berths;
this.comboBoxArrivalBerth.ItemsSource = BreCalLists.Berths;
this.comboBoxDepartureBerth.ItemsSource = BreCalLists.Berths;
if (this.ShipcallModel.Shipcall == null) this.ShipcallModel.Shipcall = new();
this.CopyToControls();
this.EnableControls();
}
private void buttonOK_Click(object sender, RoutedEventArgs e)
@ -89,6 +68,72 @@ namespace BreCalClient
private void comboBoxShip_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
this.buttonOK.IsEnabled = this.comboBoxShip.SelectedItem != null;
if (this.comboBoxShip.SelectedItem != null)
{
Ship? ship = this.comboBoxShip.SelectedItem as Ship;
this.integerUpDownIMO.Value = ship?.Imo;
this.textBoxCallsign.Text = ship?.Callsign;
this.doubleUpDownLength.Value = ship?.Length;
this.doubleUpDownWidth.Value = ship?.Width;
}
else
{
this.integerUpDownIMO.Value = null;
this.textBoxCallsign.Text = string.Empty;
this.doubleUpDownLength.Value = null;
this.doubleUpDownWidth.Value = null;
}
}
private void comboBoxAgency_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
this.EnableControls();
}
#endregion
#region Context menu handlers
private void contextMenuItemClearAgency_Click(object sender, RoutedEventArgs e)
{
this.comboBoxAgency.SelectedIndex = -1;
this.ShipcallModel.AssignedParticipants.Remove(Extensions.ParticipantType.AGENCY);
}
private void contextMenuItemArrivalBerth_Click(object sender, RoutedEventArgs e)
{
this.comboBoxArrivalBerth.SelectedIndex = -1;
this.ShipcallModel.Berth = "";
}
private void contextMenuItemDepartureBerth_Click(object sender, RoutedEventArgs e)
{
this.comboBoxDepartureBerth.SelectedIndex -= 1;
}
private void comboBoxCategories_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
TypeEnum? type = this.comboBoxCategories.SelectedItem as TypeEnum?;
if(type != null)
{
switch (type)
{
case TypeEnum.Incoming:
this.datePickerETA.IsEnabled = true;
this.datePickerETD.IsEnabled = false;
this.datePickerETD.Value = null;
break;
case TypeEnum.Outgoing:
this.datePickerETA.IsEnabled = false;
this.datePickerETD.IsEnabled = true;
this.datePickerETA.Value = null;
break;
case TypeEnum.Shifting:
this.datePickerETA.IsEnabled = true;
this.datePickerETD.IsEnabled = true;
break;
}
}
}
#endregion
@ -97,96 +142,102 @@ namespace BreCalClient
private void CopyToModel()
{
this.Shipcall.Type = (int) this.comboBoxCategories.SelectedItem;
this.Shipcall.Eta = this.datePickerETA.Value ?? DateTime.Now;
this.Shipcall.Voyage = this.textBoxVoyage.Text.Trim();
this.Shipcall.Etd = this.datePickerETD.Value ?? DateTime.Now.AddDays(1);
this.Shipcall.Anchored = this.checkBoxAnchored.IsChecked;
this.Shipcall.ShipId = ((Ship)this.comboBoxShip.SelectedItem).Id;
this.Shipcall.ArrivalBerthId = (this.comboBoxArrivalBerth.SelectedItem != null) ? ((Berth)this.comboBoxArrivalBerth.SelectedItem).Id : null;
this.Shipcall.DepartureBerthId = (this.comboBoxDepartureBerth.SelectedItem != null) ? ((Berth)this.comboBoxDepartureBerth.SelectedItem).Id : null;
this.Shipcall.Bunkering = this.checkBoxBunkering.IsChecked;
this.Shipcall.Canceled = this.checkBoxCanceled.IsChecked;
this.Shipcall.Draft = (float?) this.doubleUpDownDraft.Value;
this.Shipcall.MooredLock = this.checkBoxMooredLock.IsChecked;
this.Shipcall.RainSensitiveCargo = this.checkBoxRainsensitiveCargo.IsChecked;
this.Shipcall.PilotRequired = this.checkBoxPilotRequired.IsChecked;
this.Shipcall.ReplenishingLock = this.checkBoxReplenishingLock.IsChecked;
this.Shipcall.ReplenishingTerminal = this.checkBoxReplenishingTerminal.IsChecked;
this.Shipcall.RecommendedTugs = this.integerUpDownRecommendedTugs.Value;
this.Shipcall.TidalWindowFrom = this.datePickerTidalWindowFrom.Value;
this.Shipcall.TidalWindowTo = this.datePickerTidalWindowTo.Value;
this.Shipcall.TugRequired = this.checkBoxTugRequired.IsChecked;
if(this.comboBoxPierside.SelectedIndex >= 0)
if (this.ShipcallModel.Shipcall != null)
{
this.Shipcall.PierSide = (this.comboBoxPierside.SelectedIndex == 0) ? true : false;
this.ShipcallModel.Shipcall.Type = (int)this.comboBoxCategories.SelectedItem;
this.ShipcallModel.Shipcall.Eta = this.datePickerETA.Value ?? DateTime.Now;
this.ShipcallModel.Shipcall.Etd = this.datePickerETD.Value ?? DateTime.Now.AddDays(1);
this.ShipcallModel.Shipcall.ShipId = ((Ship)this.comboBoxShip.SelectedItem).Id;
this.ShipcallModel.Ship = (Ship)this.comboBoxShip.SelectedItem;
this.ShipcallModel.Shipcall.ArrivalBerthId = (this.comboBoxArrivalBerth.SelectedItem != null) ? ((Berth)this.comboBoxArrivalBerth.SelectedItem).Id : null;
this.ShipcallModel.Shipcall.DepartureBerthId = (this.comboBoxDepartureBerth.SelectedItem != null) ? ((Berth)this.comboBoxDepartureBerth.SelectedItem).Id : null;
// remove all and add selected participants
this.ShipcallModel.Shipcall.Participants.Clear();
this.ShipcallModel.AssignedParticipants.Clear();
Participant? participant;
participant = (Participant?)this.comboBoxAgency.SelectedItem;
if (participant != null)
{
this.ShipcallModel.Shipcall.Participants.Add(participant.Id);
this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.AGENCY] = participant;
}
// BSMD and port authority are always added
foreach (Participant p in BreCalLists.Participants)
{
if (p.Type == (int)Extensions.ParticipantType.PORT_ADMINISTRATION)
{
this.ShipcallModel.Shipcall.Participants.Add(p.Id);
this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.PORT_ADMINISTRATION] = p;
}
if (p.Type == (int)Extensions.ParticipantType.BSMD)
{
this.ShipcallModel.Shipcall.Participants.Add(p.Id);
this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.BSMD] = p;
}
}
}
// remove all and add selected participants
this.Shipcall.Participants.Clear();
Participant? participant;
participant = (Participant?) this.comboBoxAgency.SelectedItem;
if (participant != null) this.Shipcall.Participants.Add(participant.Id);
participant = (Participant?) this.comboBoxMooring.SelectedItem;
if (participant != null) this.Shipcall.Participants.Add(participant.Id);
participant = (Participant?) this.comboBoxPilot.SelectedItem;
if (participant != null) this.Shipcall.Participants.Add(participant.Id);
participant = (Participant?) this.comboBoxTerminal.SelectedItem;
if (participant != null) this.Shipcall.Participants.Add(participant.Id);
participant = (Participant?) this.comboBoxTug.SelectedItem;
if (participant != null) this.Shipcall.Participants.Add(participant.Id);
// BSMD and port authority are always added
foreach(Participant p in Participants)
{
if(p.Type == (int) Extensions.ParticipantType.PORT_ADMINISTRATION) this.Shipcall.Participants.Add(p.Id);
if (p.Type == (int)Extensions.ParticipantType.BSMD) this.Shipcall.Participants.Add(p.Id);
}
}
private void CopyToControls()
{
if (this.Shipcall == null) return;
this.comboBoxCategories.SelectedItem = (Extensions.TypeEnum) this.Shipcall.Type;
if(this.Shipcall.Eta != DateTime.MinValue)
this.datePickerETA.Value = this.Shipcall.Eta;
this.textBoxVoyage.Text = this.Shipcall.Voyage;
this.datePickerETD.Value = this.Shipcall.Etd;
this.checkBoxAnchored.IsChecked = this.Shipcall.Anchored;
this.comboBoxShip.SelectedValue = this.Shipcall.ShipId;
this.comboBoxArrivalBerth.SelectedValue = this.Shipcall.ArrivalBerthId;
this.comboBoxDepartureBerth.SelectedValue = this.Shipcall.DepartureBerthId;
this.checkBoxBunkering.IsChecked = this.Shipcall.Bunkering;
this.checkBoxCanceled.IsChecked = this.Shipcall.Canceled;
this.doubleUpDownDraft.Value = this.Shipcall.Draft;
this.checkBoxMooredLock.IsChecked = this.Shipcall.MooredLock;
this.checkBoxRainsensitiveCargo.IsChecked = this.Shipcall.RainSensitiveCargo;
this.checkBoxPilotRequired.IsChecked = this.Shipcall.PilotRequired;
this.checkBoxReplenishingLock.IsChecked = this.Shipcall.ReplenishingLock;
this.checkBoxReplenishingTerminal.IsChecked = this.Shipcall.ReplenishingTerminal;
this.integerUpDownRecommendedTugs.Value = this.Shipcall.RecommendedTugs;
this.datePickerTidalWindowFrom.Value = this.Shipcall.TidalWindowFrom;
this.datePickerTidalWindowTo.Value = this.Shipcall.TidalWindowTo;
this.checkBoxTugRequired.IsChecked = this.Shipcall.TugRequired;
if(this.Shipcall.PierSide.HasValue)
if (this.ShipcallModel == null) return;
if (this.ShipcallModel.Shipcall != null)
{
if (this.Shipcall.PierSide.Value) this.comboBoxPierside.SelectedIndex = 0;
else this.comboBoxPierside.SelectedIndex = 1;
this.comboBoxCategories.SelectedItem = (Extensions.TypeEnum)this.ShipcallModel.Shipcall.Type;
if (this.ShipcallModel.Shipcall.Eta != DateTime.MinValue)
this.datePickerETA.Value = this.ShipcallModel.Shipcall.Eta;
// this.textBoxVoyage.Text = this.ShipcallModel.Shipcall.Voyage;
this.datePickerETD.Value = this.ShipcallModel.Shipcall.Etd;
this.comboBoxShip.SelectedValue = this.ShipcallModel.Shipcall.ShipId;
this.comboBoxArrivalBerth.SelectedValue = this.ShipcallModel.Shipcall.ArrivalBerthId;
this.comboBoxDepartureBerth.SelectedValue = this.ShipcallModel.Shipcall.DepartureBerthId;
if (this.ShipcallModel.Shipcall.Participants == null) this.ShipcallModel.Shipcall.Participants = new();
foreach (int participant_id in this.ShipcallModel.Shipcall.Participants)
{
if (((List<Participant>)this.comboBoxAgency.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxAgency.SelectedValue = participant_id;
}
}
}
private void EnableControls()
{
bool isBsmd = App.Participant.IsTypeFlagSet(Extensions.ParticipantType.BSMD);
bool isAgency = App.Participant.IsTypeFlagSet(Extensions.ParticipantType.AGENCY);
bool editRightGrantedForBSMD = false;
// Special case: Selected Agency allows BSMD to edit their fields
if (this.comboBoxAgency.SelectedIndex >= 0)
{
int agencyParticipantId = (int)this.comboBoxAgency.SelectedValue;
Participant? p = BreCalLists.Participants.Find(x => x.Id == agencyParticipantId);
if (p != null)
{
if(p.IsFlagSet(ParticipantFlag.ALLOW_BSMD) && isBsmd)
isAgency = true;
if(p.IsFlagSet(ParticipantFlag.ALLOW_BSMD))
editRightGrantedForBSMD = true;
}
}
if (this.Shipcall.Participants == null) this.Shipcall.Participants = new();
this.comboBoxAgency.IsEnabled = isBsmd;
this.comboBoxArrivalBerth.IsEnabled = isBsmd || isAgency;
this.comboBoxCategories.IsEnabled = isBsmd;
this.comboBoxDepartureBerth.IsEnabled = isBsmd || isAgency;
this.comboBoxShip.IsEnabled = isBsmd;
this.datePickerETA.IsEnabled = isAgency || isBsmd;
this.datePickerETD.IsEnabled = isAgency;
foreach(int participant_id in this.Shipcall.Participants)
{
if (((List<Participant>)this.comboBoxAgency.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxAgency.SelectedValue = participant_id;
if (((List<Participant>)this.comboBoxMooring.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxMooring.SelectedValue = participant_id;
if (((List<Participant>)this.comboBoxPilot.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxPilot.SelectedValue = participant_id;
if (((List<Participant>)this.comboBoxTerminal.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxTerminal.SelectedValue = participant_id;
if (((List<Participant>)this.comboBoxTug.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxTug.SelectedValue = participant_id;
}
this.labelBSMDGranted.Visibility = editRightGrantedForBSMD ? Visibility.Visible : Visibility.Hidden;
}
#endregion

View File

@ -0,0 +1,139 @@
<Window x:Class="BreCalClient.EditTimesAgencyIncomingControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BreCalClient"
xmlns:p = "clr-namespace:BreCalClient.Resources"
xmlns:db="clr-namespace:BreCalClient;assembly=BreCalClient"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
mc:Ignorable="d"
Title="{x:Static p:Resources.textEditShipcall}" Height="403" Width="800" Loaded="Window_Loaded" ResizeMode="NoResize" Icon="Resources/containership.ico">
<Window.Resources>
<local:BoolToIndexConverter x:Key="boolToIndexConverter" />
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*"/>
<ColumnDefinition Width=".3*" />
<ColumnDefinition Width="0.15*"/>
<ColumnDefinition Width=".35*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Grid.Column="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="30" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0" Content="{x:Static p:Resources.textIncoming}" FontWeight="DemiBold"/>
<Image Margin="2" Grid.Column="1" Source="Resources/arrow_down_red.png" />
</Grid>
<Label Content="ETA" Grid.Column="0" Grid.Row="1" HorizontalContentAlignment="Right"/>
<xctk:DateTimePicker x:Name="datePickerETA" Grid.Column="1" Grid.Row="1" Margin="2" Format="Custom" FormatString="dd.MM. yyyy HH:mm"/>
<Label Content="{x:Static p:Resources.textBerth}" Grid.Column="0" Grid.Row="2" HorizontalContentAlignment="Right"/>
<ComboBox Name="comboBoxArrivalBerth" Grid.Column="1" Grid.Row="2" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id">
<ComboBox.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemArrivalBerth" Click="contextMenuItemArrivalBerth_Click" />
</ContextMenu>
</ComboBox.ContextMenu>
</ComboBox>
<Label Content="{x:Static p:Resources.textPierside}" Grid.Column="0" Grid.Row="3" HorizontalContentAlignment="Right" />
<ComboBox x:Name="comboBoxPierside" Grid.Column="1" Grid.Row="3" Margin="2" >
<ComboBoxItem Content="{x:Static p:Resources.textNotRotated}" />
<ComboBoxItem Content="{x:Static p:Resources.textRotated}" />
</ComboBox>
<Label Content="{x:Static p:Resources.textBerthRemarks}" Grid.Column="0" Grid.Row="4" HorizontalContentAlignment="Right" />
<TextBox x:Name="textBoxBerthRemarks" Grid.Column="1" Grid.Row="4" Margin="2" Grid.RowSpan="2" VerticalContentAlignment="Top" AcceptsReturn="True"/>
<Label Content="{x:Static p:Resources.textDraft}" Grid.Column="0" Grid.Row="6" HorizontalContentAlignment="Right" />
<xctk:DoubleUpDown x:Name="doubleUpDownDraft" Grid.Column="1" Grid.Row="6" Margin="2" FormatString="N2" Minimum="0" />
<Label Content="{x:Static p:Resources.textTidalWindow}" FontWeight="DemiBold" Grid.Column="0" Grid.Row="7" HorizontalContentAlignment="Right"/>
<Label Content="{x:Static p:Resources.textFrom}" Grid.Column="0" Grid.Row="8" HorizontalContentAlignment="Right"/>
<Label Content="{x:Static p:Resources.textTo}" Grid.Column="0" Grid.Row="9" HorizontalContentAlignment="Right"/>
<xctk:DateTimePicker Name="datePickerTidalWindowFrom" Grid.Column="1" Grid.Row="8" Margin="2" Format="Custom" FormatString="dd.MM. yyyy HH:mm"/>
<xctk:DateTimePicker Name="datePickerTidalWindowTo" Grid.Column="1" Grid.Row="9" Margin="2" Format="Custom" FormatString="dd.MM. yyyy HH:mm"/>
<Label Content="{x:Static p:Resources.textCancelled}" Grid.Column="0" Grid.Row="10" HorizontalContentAlignment="Right" />
<CheckBox x:Name="checkBoxCanceled" Grid.Column="1" Grid.Row="10" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,4,0" />
<Label Content="{x:Static p:Resources.textAnchored}" Grid.Column="2" Grid.Row="0" HorizontalContentAlignment="Right"/>
<CheckBox x:Name="checkBoxAnchored" Grid.Column="3" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Left" />
<Label Content="{x:Static p:Resources.textTugRequired}" Grid.Column="2" Grid.Row="1" HorizontalContentAlignment="Right"/>
<Grid Grid.Column="3" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="28" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<CheckBox x:Name="checkBoxTugRequired" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left" />
<ComboBox Name="comboBoxTug" Grid.Column="1" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id">
<ComboBox.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearAssignment}" Name="contextMenuItemClearTug" Click="contextMenuItemClearTug_Click" />
</ContextMenu>
</ComboBox.ContextMenu>
</ComboBox>
</Grid>
<Label Content="{x:Static p:Resources.textRecommendedTugs}" Grid.Column="2" Grid.Row="2" HorizontalContentAlignment="Right"/>
<xctk:IntegerUpDown x:Name="integerUpDownRecommendedTugs" Grid.Column="3" Grid.Row="2" Minimum="0" Margin="2" />
<Label Content="{x:Static p:Resources.textPilotRequired}" Grid.Column="2" Grid.Row="3" HorizontalContentAlignment="Right" />
<Grid Grid.Column="3" Grid.Row="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="28" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<CheckBox x:Name="checkBoxPilotRequired" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left" />
<ComboBox Name="comboBoxPilot" Grid.Column="1" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id">
<ComboBox.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearAssignment}" Name="contextMenuItemClearPilot" Click="contextMenuItemClearPilot_Click" />
</ContextMenu>
</ComboBox.ContextMenu>
</ComboBox>
</Grid>
<Label Content="{x:Static p:Resources.textMooring}" Grid.Column="2" Grid.Row="4" HorizontalContentAlignment="Right"/>
<ComboBox Name="comboBoxMooring" Grid.Column="3" Grid.Row="4" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id">
<ComboBox.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearAssignment}" Name="contextMenuItemClearMooring" Click="contextMenuItemClearMooring_Click" />
</ContextMenu>
</ComboBox.ContextMenu>
</ComboBox>
<Label Content="{x:Static p:Resources.textMooredLock}" Grid.Column="2" Grid.Row="5" HorizontalContentAlignment="Right" />
<CheckBox x:Name="checkBoxMooredLock" Grid.Column="3" Grid.Row="5" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,4,0" />
<Label Content="{x:Static p:Resources.textTerminal}" Grid.Column="2" Grid.Row="6" HorizontalContentAlignment="Right"/>
<ComboBox Name="comboBoxTerminal" Grid.Column="3" Grid.Row="6" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id">
<ComboBox.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearAssignment}" Name="contextMenuItemClearTerminal" Click="contextMenuItemClearTerminal_Click" />
</ContextMenu>
</ComboBox.ContextMenu>
</ComboBox>
<Label Content="{x:Static p:Resources.textBunkering}" Grid.Column="3" Grid.Row="7" />
<Label Content="{x:Static p:Resources.textReplenishingTerminal}" Grid.Column="3" Grid.Row="8" />
<Label Content="{x:Static p:Resources.textReplenishingLock}" Grid.Column="3" Grid.Row="9" />
<CheckBox x:Name="checkBoxBunkering" Grid.Column="2" Grid.Row="7" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,4,0" />
<CheckBox x:Name="checkBoxReplenishingTerminal" Grid.Column="2" Grid.Row="8" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,4,0" />
<CheckBox x:Name="checkBoxReplenishingLock" Grid.Column="2" Grid.Row="9" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,4,0" />
<Label Content="{x:Static p:Resources.textRemarks}" Grid.Row="10" Grid.Column="2" HorizontalAlignment="Right"/>
<TextBox x:Name="textBoxRemarks" Grid.Column="3" Grid.Row="10" Margin="2" Grid.RowSpan="2" VerticalContentAlignment="Top" AcceptsReturn="True" />
<StackPanel Grid.Row="14" Grid.Column="3" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Width= "80" Margin="2" Content="{x:Static p:Resources.textOK}" x:Name="buttonOK" Click="buttonOK_Click" />
<Button Width="80" Margin="2" Content="{x:Static p:Resources.textCancel}" x:Name="buttonCancel" Click="buttonCancel_Click"/>
</StackPanel>
</Grid>
</Window>

View File

@ -0,0 +1,218 @@
// Copyright (c) 2023 schick Informatik
// Description: Input control for incoming shipcalls
//
using BreCalClient.misc.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
namespace BreCalClient
{
/// <summary>
/// Interaction logic for EditTimesAgencyIncomingControl.xaml
/// </summary>
public partial class EditTimesAgencyIncomingControl : Window, IEditShipcallTimesControl
{
#region Construction
public EditTimesAgencyIncomingControl()
{
InitializeComponent();
}
#endregion
#region Properties
public ShipcallControlModel ShipcallModel { get; set; } = new();
public Times Times { get; set; } = new();
#endregion
#region event handler
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;
this.CopyToControls();
}
private void buttonOK_Click(object sender, RoutedEventArgs e)
{
this.CopyToModel();
this.DialogResult = true;
this.Close();
}
private void buttonCancel_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = false;
this.Close();
}
#endregion
#region private methods
private void CopyToModel()
{
if (this.ShipcallModel.Shipcall != null)
{
this.Times.EtaBerth = this.datePickerETA.Value;
if (this.comboBoxPierside.SelectedIndex >= 0)
{
this.ShipcallModel.Shipcall.PierSide = (this.comboBoxPierside.SelectedIndex == 0) ? true : false;
}
this.Times.BerthInfo = this.textBoxBerthRemarks.Text.Trim();
if((this.comboBoxArrivalBerth.SelectedValue != null) && ((int?)this.comboBoxArrivalBerth.SelectedValue != this.ShipcallModel.Shipcall.ArrivalBerthId))
{
this.Times.BerthId = (int?)this.comboBoxArrivalBerth.SelectedValue;
}
this.ShipcallModel.Shipcall.Draft = (float?)this.doubleUpDownDraft.Value;
this.ShipcallModel.Shipcall.TidalWindowFrom = this.datePickerTidalWindowFrom.Value;
this.ShipcallModel.Shipcall.TidalWindowTo = this.datePickerTidalWindowTo.Value;
this.ShipcallModel.Shipcall.Canceled = this.checkBoxCanceled.IsChecked;
this.ShipcallModel.Shipcall.Anchored = this.checkBoxAnchored.IsChecked;
this.ShipcallModel.Shipcall.TugRequired = this.checkBoxTugRequired.IsChecked;
this.ShipcallModel.Shipcall.RecommendedTugs = this.integerUpDownRecommendedTugs.Value;
this.ShipcallModel.Shipcall.PilotRequired = this.checkBoxPilotRequired.IsChecked;
this.ShipcallModel.Shipcall.MooredLock = this.checkBoxMooredLock.IsChecked;
this.ShipcallModel.Shipcall.Bunkering = this.checkBoxBunkering.IsChecked;
this.ShipcallModel.Shipcall.ReplenishingTerminal = this.checkBoxReplenishingTerminal.IsChecked;
this.ShipcallModel.Shipcall.ReplenishingLock = this.checkBoxReplenishingLock.IsChecked;
if (!string.IsNullOrEmpty(this.textBoxRemarks.Text.Trim()))
this.Times.Remarks = this.textBoxRemarks.Text.Trim();
Participant? participant = (Participant?)this.comboBoxMooring.SelectedItem;
if (participant != null)
{
this.ShipcallModel.Shipcall.Participants.Add(participant.Id);
this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.MOORING] = participant;
}
participant = (Participant?)this.comboBoxPilot.SelectedItem;
if (participant != null)
{
this.ShipcallModel.Shipcall.Participants.Add(participant.Id);
this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.PILOT] = participant;
}
participant = (Participant?)this.comboBoxTerminal.SelectedItem;
if (participant != null)
{
this.ShipcallModel.Shipcall.Participants.Add(participant.Id);
this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.TERMINAL] = participant;
}
participant = (Participant?)this.comboBoxTug.SelectedItem;
if (participant != null)
{
this.ShipcallModel.Shipcall.Participants.Add(participant.Id);
this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.TUG] = participant;
}
}
}
private void CopyToControls()
{
if (this.ShipcallModel == null) return;
if (this.ShipcallModel.Shipcall != null)
{
if(this.Times.EtaBerth.HasValue)
{
this.datePickerETA.Value = this.Times.EtaBerth.Value;
}
else
{
// if not set through times use value of BSMD entry
if (this.ShipcallModel.Shipcall.Eta != DateTime.MinValue)
this.datePickerETA.Value = this.ShipcallModel.Shipcall.Eta;
}
if (Times.BerthId.HasValue)
this.comboBoxArrivalBerth.SelectedValue = Times.BerthId;
else if (this.ShipcallModel.Shipcall.ArrivalBerthId.HasValue)
this.comboBoxArrivalBerth.SelectedValue = this.ShipcallModel.Shipcall.ArrivalBerthId;
if (this.ShipcallModel.Shipcall.PierSide.HasValue)
{
if (this.ShipcallModel.Shipcall.PierSide.Value) this.comboBoxPierside.SelectedIndex = 0;
else this.comboBoxPierside.SelectedIndex = 1;
}
this.textBoxBerthRemarks.Text = this.Times.BerthInfo;
this.doubleUpDownDraft.Value = this.ShipcallModel.Shipcall.Draft;
this.datePickerTidalWindowFrom.Value = this.ShipcallModel.Shipcall.TidalWindowFrom;
this.datePickerTidalWindowTo.Value = this.ShipcallModel.Shipcall.TidalWindowTo;
this.checkBoxCanceled.IsChecked = this.ShipcallModel.Shipcall.Canceled;
this.checkBoxAnchored.IsChecked = this.ShipcallModel.Shipcall.Anchored;
this.checkBoxTugRequired.IsChecked = this.ShipcallModel.Shipcall.TugRequired;
this.integerUpDownRecommendedTugs.Value = this.ShipcallModel.Shipcall.RecommendedTugs;
this.checkBoxPilotRequired.IsChecked = this.ShipcallModel.Shipcall.PilotRequired;
this.checkBoxMooredLock.IsChecked = this.ShipcallModel.Shipcall.MooredLock;
this.checkBoxBunkering.IsChecked = this.ShipcallModel.Shipcall.Bunkering;
this.checkBoxReplenishingLock.IsChecked = this.ShipcallModel.Shipcall.ReplenishingLock;
this.checkBoxReplenishingTerminal.IsChecked = this.ShipcallModel.Shipcall.ReplenishingTerminal;
if(!string.IsNullOrEmpty(this.Times.Remarks))
this.textBoxRemarks.Text = this.Times.Remarks;
foreach (int participant_id in this.ShipcallModel.Shipcall.Participants)
{
if (((List<Participant>)this.comboBoxMooring.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxMooring.SelectedValue = participant_id;
if (((List<Participant>)this.comboBoxPilot.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxPilot.SelectedValue = participant_id;
if (((List<Participant>)this.comboBoxTerminal.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxTerminal.SelectedValue = participant_id;
if (((List<Participant>)this.comboBoxTug.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxTug.SelectedValue = participant_id;
}
}
}
#endregion
#region context menu handlers
private void contextMenuItemArrivalBerth_Click(object sender, RoutedEventArgs e)
{
this.comboBoxArrivalBerth.SelectedIndex = -1;
this.ShipcallModel.Berth = "";
}
private void contextMenuItemClearTug_Click(object sender, RoutedEventArgs e)
{
this.comboBoxTug.SelectedIndex = -1;
this.ShipcallModel.AssignedParticipants.Remove(Extensions.ParticipantType.TUG);
}
private void contextMenuItemClearPilot_Click(object sender, RoutedEventArgs e)
{
this.comboBoxPilot.SelectedIndex = -1;
this.ShipcallModel.AssignedParticipants.Remove(Extensions.ParticipantType.PILOT);
}
private void contextMenuItemClearMooring_Click(object sender, RoutedEventArgs e)
{
this.comboBoxMooring.SelectedIndex = -1;
this.ShipcallModel.AssignedParticipants.Remove(Extensions.ParticipantType.MOORING);
}
private void contextMenuItemClearTerminal_Click(object sender, RoutedEventArgs e)
{
this.comboBoxTerminal.SelectedIndex = -1;
this.ShipcallModel.AssignedParticipants.Remove(Extensions.ParticipantType.TERMINAL);
}
#endregion
}
}

View File

@ -0,0 +1,129 @@
<Window x:Class="BreCalClient.EditTimesAgencyOutgoingControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BreCalClient"
xmlns:p = "clr-namespace:BreCalClient.Resources"
xmlns:db="clr-namespace:BreCalClient;assembly=BreCalClient"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
mc:Ignorable="d"
Title="{x:Static p:Resources.textEditShipcall}" Height="375" Width="800" Loaded="Window_Loaded" ResizeMode="NoResize" Icon="Resources/containership.ico">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*"/>
<ColumnDefinition Width=".3*" />
<ColumnDefinition Width="0.15*"/>
<ColumnDefinition Width=".35*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Grid.Column="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="30" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0" Content="{x:Static p:Resources.textOutgoing}" FontWeight="DemiBold"/>
<Image Margin="2" Grid.Column="1" Source="Resources/arrow_up_blue.png" />
</Grid>
<Label Content="ETD" Grid.Column="0" Grid.Row="1" HorizontalContentAlignment="Right"/>
<xctk:DateTimePicker x:Name="datePickerETD" Grid.Column="1" Grid.Row="1" Margin="2" Format="Custom" FormatString="dd.MM. yyyy HH:mm"/>
<Label Content="{x:Static p:Resources.textBerth}" Grid.Column="0" Grid.Row="2" HorizontalContentAlignment="Right" />
<ComboBox Name="comboBoxDepartureBerth" Grid.Column="1" Grid.Row="2" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id">
<ComboBox.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemDepartureBerth" Click="contextMenuItemDepartureBerth_Click" />
</ContextMenu>
</ComboBox.ContextMenu>
</ComboBox>
<Label Content="{x:Static p:Resources.textPierside}" Grid.Column="0" Grid.Row="3" HorizontalContentAlignment="Right" />
<ComboBox x:Name="comboBoxPierside" Grid.Column="1" Grid.Row="3" Margin="2" >
<ComboBoxItem Content="{x:Static p:Resources.textNotRotated}" />
<ComboBoxItem Content="{x:Static p:Resources.textRotated}" />
</ComboBox>
<Label Content="{x:Static p:Resources.textBerthRemarks}" Grid.Column="0" Grid.Row="4" HorizontalContentAlignment="Right" />
<TextBox x:Name="textBoxBerthRemarks" Grid.Column="1" Grid.Row="4" Margin="2" Grid.RowSpan="2" VerticalContentAlignment="Top" AcceptsReturn="True"/>
<Label Content="{x:Static p:Resources.textDraft}" Grid.Column="0" Grid.Row="6" HorizontalContentAlignment="Right" />
<xctk:DoubleUpDown x:Name="doubleUpDownDraft" Grid.Column="1" Grid.Row="6" Margin="2" FormatString="N2" Minimum="0" />
<Label Content="{x:Static p:Resources.textTidalWindow}" FontWeight="DemiBold" Grid.Column="0" Grid.Row="7" HorizontalContentAlignment="Right"/>
<Label Content="{x:Static p:Resources.textFrom}" Grid.Column="0" Grid.Row="8" HorizontalContentAlignment="Right"/>
<Label Content="{x:Static p:Resources.textTo}" Grid.Column="0" Grid.Row="9" HorizontalContentAlignment="Right"/>
<xctk:DateTimePicker Name="datePickerTidalWindowFrom" Grid.Column="1" Grid.Row="8" Margin="2" Format="Custom" FormatString="dd.MM. yyyy HH:mm"/>
<xctk:DateTimePicker Name="datePickerTidalWindowTo" Grid.Column="1" Grid.Row="9" Margin="2" Format="Custom" FormatString="dd.MM. yyyy HH:mm"/>
<Label Content="{x:Static p:Resources.textCancelled}" Grid.Column="0" Grid.Row="10" HorizontalContentAlignment="Right" />
<CheckBox x:Name="checkBoxCanceled" Grid.Column="1" Grid.Row="10" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,4,0" />
<Label Content="{x:Static p:Resources.textTugRequired}" Grid.Column="2" Grid.Row="1" HorizontalContentAlignment="Right"/>
<Grid Grid.Column="3" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="28" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<CheckBox x:Name="checkBoxTugRequired" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left" />
<ComboBox Name="comboBoxTug" Grid.Column="1" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id">
<ComboBox.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearAssignment}" Name="contextMenuItemClearTug" Click="contextMenuItemClearTug_Click" />
</ContextMenu>
</ComboBox.ContextMenu>
</ComboBox>
</Grid>
<Label Content="{x:Static p:Resources.textRecommendedTugs}" Grid.Column="2" Grid.Row="2" HorizontalContentAlignment="Right"/>
<xctk:IntegerUpDown x:Name="integerUpDownRecommendedTugs" Grid.Column="3" Grid.Row="2" Minimum="0" Margin="2" />
<Label Content="{x:Static p:Resources.textPilotRequired}" Grid.Column="2" Grid.Row="3" HorizontalContentAlignment="Right" />
<Grid Grid.Column="3" Grid.Row="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="28" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<CheckBox x:Name="checkBoxPilotRequired" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left" />
<ComboBox Name="comboBoxPilot" Grid.Column="1" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id">
<ComboBox.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearAssignment}" Name="contextMenuItemClearPilot" Click="contextMenuItemClearPilot_Click" />
</ContextMenu>
</ComboBox.ContextMenu>
</ComboBox>
</Grid>
<Label Content="{x:Static p:Resources.textMooring}" Grid.Column="2" Grid.Row="4" HorizontalContentAlignment="Right"/>
<ComboBox Name="comboBoxMooring" Grid.Column="3" Grid.Row="4" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id">
<ComboBox.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearAssignment}" Name="contextMenuItemClearMooring" Click="contextMenuItemClearMooring_Click" />
</ContextMenu>
</ComboBox.ContextMenu>
</ComboBox>
<Label Content="{x:Static p:Resources.textMooredLock}" Grid.Column="2" Grid.Row="5" HorizontalContentAlignment="Right" />
<CheckBox x:Name="checkBoxMooredLock" Grid.Column="3" Grid.Row="5" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,4,0" />
<Label Content="{x:Static p:Resources.textTerminal}" Grid.Column="2" Grid.Row="6" HorizontalContentAlignment="Right"/>
<ComboBox Name="comboBoxTerminal" Grid.Column="3" Grid.Row="6" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id">
<ComboBox.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearAssignment}" Name="contextMenuItemClearTerminal" Click="contextMenuItemClearTerminal_Click" />
</ContextMenu>
</ComboBox.ContextMenu>
</ComboBox>
<Label Content="{x:Static p:Resources.textRainSensitiveCargo}" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="7" HorizontalAlignment="Right" />
<CheckBox x:Name="checkBoxRainsensitiveCargo" Grid.Column="3" Grid.Row="7" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,4,0" />
<Label Content="{x:Static p:Resources.textRemarks}" Grid.Column="2" Grid.Row="8" HorizontalContentAlignment="Right" />
<TextBox x:Name="textBoxRemarks" Grid.Column="3" Grid.Row="8" Margin="2" Grid.RowSpan="3" VerticalContentAlignment="Top" AcceptsReturn="True" />
<StackPanel Grid.Row="11" Grid.Column="3" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Width= "80" Margin="2" Content="{x:Static p:Resources.textOK}" x:Name="buttonOK" Click="buttonOK_Click" />
<Button Width="80" Margin="2" Content="{x:Static p:Resources.textCancel}" x:Name="buttonCancel" Click="buttonCancel_Click"/>
</StackPanel>
</Grid>
</Window>

View File

@ -0,0 +1,208 @@
// Copyright (c) 2023 schick Informatik
// Description: Input control for outgoing shipcalls
//
using BreCalClient.misc.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
namespace BreCalClient
{
/// <summary>
/// Interaction logic for EditTimesAgencyOutgoingControl.xaml
/// </summary>
public partial class EditTimesAgencyOutgoingControl : Window, IEditShipcallTimesControl
{
#region Construction
public EditTimesAgencyOutgoingControl()
{
InitializeComponent();
}
#endregion
#region Properties
public ShipcallControlModel ShipcallModel { get; set; } = new();
public Times Times { get; set; } = new();
#endregion
#region event handler
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;
this.CopyToControls();
}
private void buttonOK_Click(object sender, RoutedEventArgs e)
{
this.CopyToModel();
this.DialogResult = true;
this.Close();
}
private void buttonCancel_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = false;
this.Close();
}
#endregion
#region private methods
private void CopyToModel()
{
if (this.ShipcallModel.Shipcall != null)
{
this.Times.EtdBerth = this.datePickerETD.Value;
if (this.comboBoxPierside.SelectedIndex >= 0)
{
this.ShipcallModel.Shipcall.PierSide = (this.comboBoxPierside.SelectedIndex == 0) ? true : false;
}
if ((this.comboBoxDepartureBerth.SelectedValue != null) && ((int?)this.comboBoxDepartureBerth.SelectedValue != this.ShipcallModel.Shipcall.DepartureBerthId))
{
this.Times.BerthId = (int?)this.comboBoxDepartureBerth.SelectedValue;
}
this.Times.BerthInfo = this.textBoxBerthRemarks.Text.Trim();
this.ShipcallModel.Shipcall.Draft = (float?)this.doubleUpDownDraft.Value;
this.ShipcallModel.Shipcall.TidalWindowFrom = this.datePickerTidalWindowFrom.Value;
this.ShipcallModel.Shipcall.TidalWindowTo = this.datePickerTidalWindowTo.Value;
this.ShipcallModel.Shipcall.Canceled = this.checkBoxCanceled.IsChecked;
this.ShipcallModel.Shipcall.TugRequired = this.checkBoxTugRequired.IsChecked;
this.ShipcallModel.Shipcall.RecommendedTugs = this.integerUpDownRecommendedTugs.Value;
this.ShipcallModel.Shipcall.PilotRequired = this.checkBoxPilotRequired.IsChecked;
this.ShipcallModel.Shipcall.MooredLock = this.checkBoxMooredLock.IsChecked;
this.ShipcallModel.Shipcall.RainSensitiveCargo = this.checkBoxRainsensitiveCargo.IsChecked;
if(!string.IsNullOrEmpty(this.textBoxRemarks.Text.Trim()))
this.Times.Remarks = this.textBoxRemarks.Text.Trim();
Participant? participant = (Participant?)this.comboBoxMooring.SelectedItem;
if (participant != null)
{
this.ShipcallModel.Shipcall.Participants.Add(participant.Id);
this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.MOORING] = participant;
}
participant = (Participant?)this.comboBoxPilot.SelectedItem;
if (participant != null)
{
this.ShipcallModel.Shipcall.Participants.Add(participant.Id);
this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.PILOT] = participant;
}
participant = (Participant?)this.comboBoxTerminal.SelectedItem;
if (participant != null)
{
this.ShipcallModel.Shipcall.Participants.Add(participant.Id);
this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.TERMINAL] = participant;
}
participant = (Participant?)this.comboBoxTug.SelectedItem;
if (participant != null)
{
this.ShipcallModel.Shipcall.Participants.Add(participant.Id);
this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.TUG] = participant;
}
}
}
private void CopyToControls()
{
if (this.ShipcallModel == null) return;
if (this.ShipcallModel.Shipcall != null)
{
if (this.Times.EtdBerth.HasValue)
{
this.datePickerETD.Value = this.Times.EtdBerth.Value;
}
else
{
// if not set through times use value of BSMD entry
if (this.ShipcallModel.Shipcall.Etd != DateTime.MinValue)
this.datePickerETD.Value = this.ShipcallModel.Shipcall.Etd;
}
if (this.Times.BerthId.HasValue)
this.comboBoxDepartureBerth.SelectedValue = this.Times.BerthId;
else if (this.ShipcallModel.Shipcall.DepartureBerthId.HasValue)
this.comboBoxDepartureBerth.SelectedValue = this.ShipcallModel.Shipcall.DepartureBerthId;
if (this.ShipcallModel.Shipcall.PierSide.HasValue)
{
if (this.ShipcallModel.Shipcall.PierSide.Value) this.comboBoxPierside.SelectedIndex = 0;
else this.comboBoxPierside.SelectedIndex = 1;
}
this.textBoxBerthRemarks.Text = this.Times.BerthInfo;
this.doubleUpDownDraft.Value = this.ShipcallModel.Shipcall.Draft;
this.datePickerTidalWindowFrom.Value = this.ShipcallModel.Shipcall.TidalWindowFrom;
this.datePickerTidalWindowTo.Value = this.ShipcallModel.Shipcall.TidalWindowTo;
this.checkBoxCanceled.IsChecked = this.ShipcallModel.Shipcall.Canceled;
this.checkBoxTugRequired.IsChecked = this.ShipcallModel.Shipcall.TugRequired;
this.integerUpDownRecommendedTugs.Value = this.ShipcallModel.Shipcall.RecommendedTugs;
this.checkBoxPilotRequired.IsChecked = this.ShipcallModel.Shipcall.PilotRequired;
this.checkBoxMooredLock.IsChecked = this.ShipcallModel.Shipcall.MooredLock;
this.checkBoxRainsensitiveCargo.IsChecked = this.ShipcallModel.Shipcall.RainSensitiveCargo;
if(!string.IsNullOrEmpty(this.Times.Remarks))
this.textBoxRemarks.Text = this.Times.Remarks;
foreach (int participant_id in this.ShipcallModel.Shipcall.Participants)
{
if (((List<Participant>)this.comboBoxMooring.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxMooring.SelectedValue = participant_id;
if (((List<Participant>)this.comboBoxPilot.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxPilot.SelectedValue = participant_id;
if (((List<Participant>)this.comboBoxTerminal.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxTerminal.SelectedValue = participant_id;
if (((List<Participant>)this.comboBoxTug.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxTug.SelectedValue = participant_id;
}
}
}
#endregion
#region context menu handlers
private void contextMenuItemClearTug_Click(object sender, RoutedEventArgs e)
{
this.comboBoxTug.SelectedIndex = -1;
this.ShipcallModel.AssignedParticipants.Remove(Extensions.ParticipantType.TUG);
}
private void contextMenuItemClearPilot_Click(object sender, RoutedEventArgs e)
{
this.comboBoxPilot.SelectedIndex = -1;
this.ShipcallModel.AssignedParticipants.Remove(Extensions.ParticipantType.PILOT);
}
private void contextMenuItemClearMooring_Click(object sender, RoutedEventArgs e)
{
this.comboBoxMooring.SelectedIndex = -1;
this.ShipcallModel.AssignedParticipants.Remove(Extensions.ParticipantType.MOORING);
}
private void contextMenuItemDepartureBerth_Click(object sender, RoutedEventArgs e)
{
this.comboBoxDepartureBerth.SelectedIndex = -1;
this.ShipcallModel.Berth = "";
}
private void contextMenuItemClearTerminal_Click(object sender, RoutedEventArgs e)
{
this.comboBoxTerminal.SelectedIndex = -1;
this.ShipcallModel.AssignedParticipants.Remove(Extensions.ParticipantType.TERMINAL);
}
#endregion
}
}

View File

@ -0,0 +1,153 @@
<Window x:Class="BreCalClient.EditTimesAgencyShiftingControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BreCalClient"
xmlns:p = "clr-namespace:BreCalClient.Resources"
xmlns:db="clr-namespace:BreCalClient;assembly=BreCalClient"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
mc:Ignorable="d"
Title="{x:Static p:Resources.textEditShipcall}" Height="460" Width="800" Loaded="Window_Loaded" ResizeMode="NoResize" Icon="Resources/containership.ico">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*"/>
<ColumnDefinition Width=".3*" />
<ColumnDefinition Width="0.15*"/>
<ColumnDefinition Width=".35*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Grid.Column="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="30" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0" Content="{x:Static p:Resources.textShiftingFrom}" FontWeight="DemiBold"/>
<Image Margin="2" Grid.Column="1" Source="Resources/arrow_right_green.png" />
</Grid>
<Label Content="ETD" Grid.Column="0" Grid.Row="1" HorizontalContentAlignment="Right"/>
<xctk:DateTimePicker x:Name="datePickerETD" Grid.Column="1" Grid.Row="1" Margin="2" Format="Custom" FormatString="dd.MM. yyyy HH:mm"/>
<Label Content="{x:Static p:Resources.textBerth}" Grid.Column="0" Grid.Row="2" HorizontalContentAlignment="Right" />
<ComboBox Name="comboBoxDepartureBerth" Grid.Column="1" Grid.Row="2" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id">
<ComboBox.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemDepartureBerth" Click="contextMenuItemDepartureBerth_Click" />
</ContextMenu>
</ComboBox.ContextMenu>
</ComboBox>
<Label Content="{x:Static p:Resources.textDraft}" Grid.Column="0" Grid.Row="3" HorizontalContentAlignment="Right" />
<xctk:DoubleUpDown x:Name="doubleUpDownDraft" Grid.Column="1" Grid.Row="3" Margin="2" FormatString="N2" Minimum="0" />
<Label Content="{x:Static p:Resources.textTidalWindow}" FontWeight="DemiBold" Grid.Column="0" Grid.Row="4" HorizontalContentAlignment="Right"/>
<Label Content="{x:Static p:Resources.textFrom}" Grid.Column="0" Grid.Row="5" HorizontalContentAlignment="Right"/>
<Label Content="{x:Static p:Resources.textTo}" Grid.Column="0" Grid.Row="6" HorizontalContentAlignment="Right"/>
<xctk:DateTimePicker Name="datePickerTidalWindowFrom" Grid.Column="1" Grid.Row="5" Margin="2" Format="Custom" FormatString="dd.MM. yyyy HH:mm"/>
<xctk:DateTimePicker Name="datePickerTidalWindowTo" Grid.Column="1" Grid.Row="6" Margin="2" Format="Custom" FormatString="dd.MM. yyyy HH:mm"/>
<Grid Grid.Row="7" Grid.Column="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="30" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0" Content="{x:Static p:Resources.textShiftingTo}" FontWeight="DemiBold"/>
<Image Margin="2" Grid.Column="1" Source="Resources/arrow_right_green.png" />
</Grid>
<Label Content="ETA" Grid.Column="0" Grid.Row="8" HorizontalContentAlignment="Right"/>
<xctk:DateTimePicker x:Name="datePickerETA" Grid.Column="1" Grid.Row="8" Margin="2" Format="Custom" FormatString="dd.MM. yyyy HH:mm"/>
<Label Content="{x:Static p:Resources.textBerth}" Grid.Column="0" Grid.Row="9" HorizontalContentAlignment="Right"/>
<ComboBox Name="comboBoxArrivalBerth" Grid.Column="1" Grid.Row="9" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id">
<ComboBox.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemArrivalBerth" Click="contextMenuItemArrivalBerth_Click" />
</ContextMenu>
</ComboBox.ContextMenu>
</ComboBox>
<Label Content="{x:Static p:Resources.textPierside}" Grid.Column="0" Grid.Row="10" HorizontalContentAlignment="Right" />
<ComboBox x:Name="comboBoxPiersideArrival" Grid.Column="1" Grid.Row="10" Margin="2" >
<ComboBoxItem Content="{x:Static p:Resources.textNotRotated}" />
<ComboBoxItem Content="{x:Static p:Resources.textRotated}" />
</ComboBox>
<Label Content="{x:Static p:Resources.textBerthRemarks}" Grid.Column="0" Grid.Row="11" HorizontalContentAlignment="Right" />
<TextBox x:Name="textBoxBerthRemarksArrival" Grid.Column="1" Grid.Row="11" Margin="2,1,2,3" Grid.RowSpan="2" VerticalContentAlignment="Top" AcceptsReturn="True" />
<Label Content="{x:Static p:Resources.textCancelled}" Grid.Column="0" Grid.Row="13" HorizontalContentAlignment="Right" />
<CheckBox x:Name="checkBoxCanceled" Grid.Column="1" Grid.Row="13" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,4,0" />
<Label Content="{x:Static p:Resources.textTugRequired}" Grid.Column="2" Grid.Row="1" HorizontalContentAlignment="Right"/>
<Grid Grid.Column="3" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="28" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<CheckBox x:Name="checkBoxTugRequired" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left" />
<ComboBox Name="comboBoxTug" Grid.Column="1" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id">
<ComboBox.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearAssignment}" Name="contextMenuItemClearTug" Click="contextMenuItemClearTug_Click" />
</ContextMenu>
</ComboBox.ContextMenu>
</ComboBox>
</Grid>
<Label Content="{x:Static p:Resources.textRecommendedTugs}" Grid.Column="2" Grid.Row="2" HorizontalContentAlignment="Right"/>
<xctk:IntegerUpDown x:Name="integerUpDownRecommendedTugs" Grid.Column="3" Grid.Row="2" Minimum="0" Margin="2" />
<Label Content="{x:Static p:Resources.textPilotRequired}" Grid.Column="2" Grid.Row="3" HorizontalContentAlignment="Right" />
<Grid Grid.Column="3" Grid.Row="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="28" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<CheckBox x:Name="checkBoxPilotRequired" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left" />
<ComboBox Name="comboBoxPilot" Grid.Column="1" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id">
<ComboBox.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearAssignment}" Name="contextMenuItemClearPilot" Click="contextMenuItemClearPilot_Click" />
</ContextMenu>
</ComboBox.ContextMenu>
</ComboBox>
</Grid>
<Label Content="{x:Static p:Resources.textMooring}" Grid.Column="2" Grid.Row="4" HorizontalContentAlignment="Right"/>
<ComboBox Name="comboBoxMooring" Grid.Column="3" Grid.Row="4" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id">
<ComboBox.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearAssignment}" Name="contextMenuItemClearMooring" Click="contextMenuItemClearMooring_Click" />
</ContextMenu>
</ComboBox.ContextMenu>
</ComboBox>
<Label Content="{x:Static p:Resources.textMooredLock}" Grid.Column="2" Grid.Row="5" HorizontalContentAlignment="Right" />
<CheckBox x:Name="checkBoxMooredLock" Grid.Column="3" Grid.Row="5" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,4,0" />
<Label Content="{x:Static p:Resources.textTerminal}" Grid.Column="2" Grid.Row="6" HorizontalContentAlignment="Right"/>
<ComboBox Name="comboBoxTerminal" Grid.Column="3" Grid.Row="6" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id">
<ComboBox.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearAssignment}" Name="contextMenuItemClearTerminal" Click="contextMenuItemClearTerminal_Click" />
</ContextMenu>
</ComboBox.ContextMenu>
</ComboBox>
<Label Content="{x:Static p:Resources.textRainSensitiveCargo}" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="7" HorizontalAlignment="Right" />
<CheckBox x:Name="checkBoxRainsensitiveCargo" Grid.Column="3" Grid.Row="7" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,4,0" />
<Label Content="{x:Static p:Resources.textRemarks}" Grid.Column="2" Grid.Row="8" HorizontalContentAlignment="Right" />
<TextBox x:Name="textBoxRemarks" Grid.Column="3" Grid.Row="8" Margin="2,1,2,3" Grid.RowSpan="3" VerticalContentAlignment="Top" AcceptsReturn="True" />
<StackPanel Grid.Row="14" Grid.Column="3" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Width= "80" Margin="2" Content="{x:Static p:Resources.textOK}" x:Name="buttonOK" Click="buttonOK_Click" />
<Button Width="80" Margin="2" Content="{x:Static p:Resources.textCancel}" x:Name="buttonCancel" Click="buttonCancel_Click"/>
</StackPanel>
</Grid>
</Window>

View File

@ -0,0 +1,231 @@
// Copyright (c) 2023 schick Informatik
// Description: Input control for shifting operations
//
using BreCalClient.misc.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
namespace BreCalClient
{
/// <summary>
/// Interaction logic for EditTimesAgencyShiftingControl.xaml
/// </summary>
public partial class EditTimesAgencyShiftingControl : Window, IEditShipcallTimesControl
{
#region Construction
public EditTimesAgencyShiftingControl()
{
InitializeComponent();
}
#endregion
#region Properties
public ShipcallControlModel ShipcallModel { get; set; } = new();
public Times Times { get; set; } = new();
#endregion
#region event handler
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;
this.comboBoxArrivalBerth.ItemsSource = BreCalLists.Berths;
this.CopyToControls();
}
private void buttonOK_Click(object sender, RoutedEventArgs e)
{
this.CopyToModel();
this.DialogResult = true;
this.Close();
}
private void buttonCancel_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = false;
this.Close();
}
#endregion
#region private methods
private void CopyToModel()
{
if (this.ShipcallModel.Shipcall != null)
{
this.Times.EtdBerth = this.datePickerETD.Value;
this.Times.EtaBerth = this.datePickerETA.Value;
this.ShipcallModel.Shipcall.DepartureBerthId = (int)this.comboBoxDepartureBerth.SelectedValue;
if (this.comboBoxPiersideArrival.SelectedIndex >= 0)
{
this.ShipcallModel.Shipcall.PierSide = (this.comboBoxPiersideArrival.SelectedIndex == 0) ? true : false;
}
this.Times.BerthInfo = this.textBoxBerthRemarksArrival.Text.Trim();
if ((this.comboBoxArrivalBerth.SelectedValue != null) && ((int?)this.comboBoxArrivalBerth.SelectedValue != this.ShipcallModel.Shipcall.ArrivalBerthId))
{
this.Times.BerthId = (int?)this.comboBoxArrivalBerth.SelectedValue;
}
this.ShipcallModel.Shipcall.Draft = (float?)this.doubleUpDownDraft.Value;
this.ShipcallModel.Shipcall.TidalWindowFrom = this.datePickerTidalWindowFrom.Value;
this.ShipcallModel.Shipcall.TidalWindowTo = this.datePickerTidalWindowTo.Value;
this.ShipcallModel.Shipcall.Canceled = this.checkBoxCanceled.IsChecked;
this.ShipcallModel.Shipcall.TugRequired = this.checkBoxTugRequired.IsChecked;
this.ShipcallModel.Shipcall.RecommendedTugs = this.integerUpDownRecommendedTugs.Value;
this.ShipcallModel.Shipcall.PilotRequired = this.checkBoxPilotRequired.IsChecked;
this.ShipcallModel.Shipcall.MooredLock = this.checkBoxMooredLock.IsChecked;
this.ShipcallModel.Shipcall.RainSensitiveCargo = this.checkBoxRainsensitiveCargo.IsChecked;
if(!string.IsNullOrEmpty(this.textBoxRemarks.Text.Trim()))
this.Times.Remarks = this.textBoxRemarks.Text.Trim();
Participant? participant = (Participant?)this.comboBoxMooring.SelectedItem;
if (participant != null)
{
this.ShipcallModel.Shipcall.Participants.Add(participant.Id);
this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.MOORING] = participant;
}
participant = (Participant?)this.comboBoxPilot.SelectedItem;
if (participant != null)
{
this.ShipcallModel.Shipcall.Participants.Add(participant.Id);
this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.PILOT] = participant;
}
participant = (Participant?)this.comboBoxTerminal.SelectedItem;
if (participant != null)
{
this.ShipcallModel.Shipcall.Participants.Add(participant.Id);
this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.TERMINAL] = participant;
}
participant = (Participant?)this.comboBoxTug.SelectedItem;
if (participant != null)
{
this.ShipcallModel.Shipcall.Participants.Add(participant.Id);
this.ShipcallModel.AssignedParticipants[Extensions.ParticipantType.TUG] = participant;
}
}
}
private void CopyToControls()
{
if (this.ShipcallModel == null) return;
if (this.ShipcallModel.Shipcall != null)
{
if (this.Times.EtaBerth.HasValue)
{
this.datePickerETA.Value = this.Times.EtaBerth.Value;
}
else
{
// if not set through times use value of BSMD entry
if (this.ShipcallModel.Shipcall.Eta != DateTime.MinValue)
this.datePickerETA.Value = this.ShipcallModel.Shipcall.Eta;
}
if(this.Times.EtdBerth.HasValue)
{
this.datePickerETD.Value = this.Times.EtdBerth.Value;
}
else
{
if (this.ShipcallModel.Shipcall.Etd != DateTime.MinValue)
this.datePickerETD.Value = this.ShipcallModel.Shipcall.Etd;
}
if (this.Times.BerthId.HasValue)
this.comboBoxArrivalBerth.SelectedValue = this.Times.BerthId;
else if (this.ShipcallModel.Shipcall.ArrivalBerthId.HasValue)
this.comboBoxArrivalBerth.SelectedValue = this.ShipcallModel.Shipcall.ArrivalBerthId;
if (this.ShipcallModel.Shipcall.DepartureBerthId.HasValue)
this.comboBoxDepartureBerth.SelectedValue = this.ShipcallModel.Shipcall.DepartureBerthId;
if (this.ShipcallModel.Shipcall.PierSide.HasValue)
{
if (this.ShipcallModel.Shipcall.PierSide.Value) this.comboBoxPiersideArrival.SelectedIndex = 0;
else this.comboBoxPiersideArrival.SelectedIndex = 1;
}
this.textBoxBerthRemarksArrival.Text = this.Times.BerthInfo;
this.doubleUpDownDraft.Value = this.ShipcallModel.Shipcall.Draft;
this.datePickerTidalWindowFrom.Value = this.ShipcallModel.Shipcall.TidalWindowFrom;
this.datePickerTidalWindowTo.Value = this.ShipcallModel.Shipcall.TidalWindowTo;
this.checkBoxCanceled.IsChecked = this.ShipcallModel.Shipcall.Canceled;
this.checkBoxTugRequired.IsChecked = this.ShipcallModel.Shipcall.TugRequired;
this.integerUpDownRecommendedTugs.Value = this.ShipcallModel.Shipcall.RecommendedTugs;
this.checkBoxPilotRequired.IsChecked = this.ShipcallModel.Shipcall.PilotRequired;
this.checkBoxMooredLock.IsChecked = this.ShipcallModel.Shipcall.MooredLock;
this.checkBoxRainsensitiveCargo.IsChecked = this.ShipcallModel.Shipcall.RainSensitiveCargo;
if(!string.IsNullOrEmpty(this.Times.Remarks))
this.textBoxRemarks.Text = this.Times.Remarks;
foreach (int participant_id in this.ShipcallModel.Shipcall.Participants)
{
if (((List<Participant>)this.comboBoxMooring.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxMooring.SelectedValue = participant_id;
if (((List<Participant>)this.comboBoxPilot.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxPilot.SelectedValue = participant_id;
if (((List<Participant>)this.comboBoxTerminal.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxTerminal.SelectedValue = participant_id;
if (((List<Participant>)this.comboBoxTug.ItemsSource).Any(x => x.Id == participant_id)) this.comboBoxTug.SelectedValue = participant_id;
}
}
}
#endregion
#region context menu handlers
private void contextMenuItemDepartureBerth_Click(object sender, RoutedEventArgs e)
{
this.comboBoxDepartureBerth.SelectedIndex = -1;
this.ShipcallModel.Berth = "";
}
private void contextMenuItemArrivalBerth_Click(object sender, RoutedEventArgs e)
{
this.comboBoxArrivalBerth.SelectedIndex = -1;
this.ShipcallModel.Berth = "";
}
private void contextMenuItemClearTug_Click(object sender, RoutedEventArgs e)
{
this.comboBoxTug.SelectedIndex = -1;
this.ShipcallModel.AssignedParticipants.Remove(Extensions.ParticipantType.TUG);
}
private void contextMenuItemClearPilot_Click(object sender, RoutedEventArgs e)
{
this.comboBoxPilot.SelectedIndex = -1;
this.ShipcallModel.AssignedParticipants.Remove(Extensions.ParticipantType.PILOT);
}
private void contextMenuItemClearMooring_Click(object sender, RoutedEventArgs e)
{
this.comboBoxMooring.SelectedIndex = -1;
this.ShipcallModel.AssignedParticipants.Remove(Extensions.ParticipantType.MOORING);
}
private void contextMenuItemClearTerminal_Click(object sender, RoutedEventArgs e)
{
this.comboBoxTerminal.SelectedIndex = -1;
this.ShipcallModel.AssignedParticipants.Remove(Extensions.ParticipantType.TERMINAL);
}
#endregion
}
}

View File

@ -8,7 +8,7 @@
xmlns:db="clr-namespace:BreCalClient;assembly=BreCalClient"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
mc:Ignorable="d"
Title="{x:Static p:Resources.textEditTimes}" Height="320" Width="400" Loaded="Window_Loaded" ResizeMode="NoResize" Icon="Resources/containership.ico">
Title="{x:Static p:Resources.textEditTimes}" Height="265" Width="400" Loaded="Window_Loaded" ResizeMode="NoResize" Icon="Resources/containership.ico">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".25*" />
@ -21,8 +21,6 @@
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="56" />
<RowDefinition Height="28" />
</Grid.RowDefinitions>
@ -31,22 +29,60 @@
<Label Grid.Row="2" Grid.Column="0" Content="{x:Static p:Resources.textETDBerth}" HorizontalContentAlignment="Right" />
<Label Grid.Row="3" Grid.Column="0" Content="{x:Static p:Resources.textLockTime}" HorizontalContentAlignment="Right" />
<Label Grid.Row="4" Grid.Column="0" Content="{x:Static p:Resources.textZoneEntryTime}" HorizontalContentAlignment="Right" />
<Label Grid.Row="5" Grid.Column="0" Content="{x:Static p:Resources.textOperationsStart}" HorizontalContentAlignment="Right" />
<Label Grid.Row="6" Grid.Column="0" Content="{x:Static p:Resources.textOperationsEnd}" HorizontalContentAlignment="Right" />
<Label Grid.Row="7" Grid.Column="0" Content="{x:Static p:Resources.textRemarks}" HorizontalContentAlignment="Right" />
<xctk:DateTimePicker IsEnabled="False" Grid.Row="1" Grid.Column="1" Margin="2" Name="datePickerETABerth" />
<Label Grid.Row="5" Grid.Column="0" Content="{x:Static p:Resources.textRemarks}" HorizontalContentAlignment="Right" />
<xctk:DateTimePicker IsEnabled="False" Grid.Row="1" Grid.Column="1" Margin="2" Name="datePickerETABerth" Format="Custom" FormatString="dd.MM. yyyy HH:mm">
<xctk:DateTimePicker.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemClearETA" Click="contextMenuItemClearETA_Click" >
<MenuItem.Icon>
<Image Source="Resources\delete.png" />
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</xctk:DateTimePicker.ContextMenu>
</xctk:DateTimePicker>
<CheckBox IsEnabled="False" Grid.Row="1" Grid.Column="2" Margin="4,0,0,0" Name="checkBoxEtaBerthFixed" VerticalAlignment="Center" />
<xctk:DateTimePicker IsEnabled="False" Grid.Row="2" Grid.Column="1" Margin="2" Name="datePickerETDBerth" />
<xctk:DateTimePicker IsEnabled="False" Grid.Row="2" Grid.Column="1" Margin="2" Name="datePickerETDBerth" Format="Custom" FormatString="dd.MM. yyyy HH:mm">
<xctk:DateTimePicker.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemClearETD" Click="contextMenuItemClearETD_Click" >
<MenuItem.Icon>
<Image Source="Resources\delete.png" />
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</xctk:DateTimePicker.ContextMenu>
</xctk:DateTimePicker>
<CheckBox IsEnabled="False" Grid.Row="2" Grid.Column="2" Margin="4,0,0,0" Name="checkBoxEtDBerthFixed" VerticalAlignment="Center" />
<xctk:DateTimePicker IsEnabled="False" Grid.Row="3" Grid.Column="1" Margin="2" Name="datePickerLockTime" />
<xctk:DateTimePicker IsEnabled="False" Grid.Row="3" Grid.Column="1" Margin="2" Name="datePickerLockTime" Format="Custom" FormatString="dd.MM. yyyy HH:mm">
<xctk:DateTimePicker.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemClearLockTime" Click="contextMenuItemClearLockTime_Click" >
<MenuItem.Icon>
<Image Source="Resources\delete.png" />
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</xctk:DateTimePicker.ContextMenu>
</xctk:DateTimePicker>
<CheckBox IsEnabled="False" Grid.Row="3" Grid.Column="2" Margin="4,0,0,0" Name="checkBoxLockTimeFixed" VerticalAlignment="Center" />
<xctk:DateTimePicker IsEnabled="False" Grid.Row="4" Grid.Column="1" Margin="2" Name="datePickerZoneEntry" />
<xctk:DateTimePicker IsEnabled="False" Grid.Row="4" Grid.Column="1" Margin="2" Name="datePickerZoneEntry" Format="Custom" FormatString="dd.MM. yyyy HH:mm">
<xctk:DateTimePicker.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemClearZoneEntry" Click="contextMenuItemClearZoneEntry_Click" >
<MenuItem.Icon>
<Image Source="Resources\delete.png" />
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</xctk:DateTimePicker.ContextMenu>
</xctk:DateTimePicker>
<CheckBox IsEnabled="False" Grid.Row="4" Grid.Column="2" Margin="4,0,0,0" Name="checkBoxZoneEntryFixed" VerticalAlignment="Center" />
<xctk:DateTimePicker IsEnabled="False" Grid.Row="5" Grid.Column="1" Margin="2" Name="datePickerOperationStart" />
<xctk:DateTimePicker IsEnabled="False" Grid.Row="6" Grid.Column="1" Margin="2" Name="datePickerOperationEnd" />
<TextBox Grid.Row="7" Grid.Column="1" Margin="2" Name="textBoxRemarks" TextWrapping="Wrap" AcceptsReturn="True" SpellCheck.IsEnabled="True" AcceptsTab="True" />
<StackPanel Grid.Row="8" Grid.Column="1" Grid.ColumnSpan="2" Orientation="Horizontal" HorizontalAlignment="Right">
<TextBox Grid.Row="5" Grid.Column="1" Margin="2" Name="textBoxRemarks" TextWrapping="Wrap" AcceptsReturn="True" SpellCheck.IsEnabled="True" AcceptsTab="True" />
<StackPanel Grid.Row="6" Grid.Column="1" Grid.ColumnSpan="2" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Width= "80" Margin="2" Content="{x:Static p:Resources.textOK}" x:Name="buttonOK" Click="buttonOK_Click" />
<Button Width="80" Margin="2" Content="{x:Static p:Resources.textCancel}" x:Name="buttonCancel" Click="buttonCancel_Click"/>
</StackPanel>

View File

@ -11,7 +11,7 @@ namespace BreCalClient
/// <summary>
/// Interaction logic for EditTimesControl.xaml
/// </summary>
public partial class EditTimesControl : Window
public partial class EditTimesControl : Window, IEditTimesControl
{
#region Construction
@ -37,28 +37,25 @@ namespace BreCalClient
{
this.CopyToControls();
// enable controls according to participant type
this.datePickerETABerth.IsEnabled = App.Participant.IsFlagSet(Extensions.ParticipantType.AGENCY) ||
App.Participant.IsFlagSet(Extensions.ParticipantType.MOORING) ||
App.Participant.IsFlagSet(Extensions.ParticipantType.PILOT) ||
App.Participant.IsFlagSet(Extensions.ParticipantType.PORT_ADMINISTRATION) ||
App.Participant.IsFlagSet(Extensions.ParticipantType.TUG);
this.datePickerETABerth.IsEnabled = App.Participant.IsTypeFlagSet(Extensions.ParticipantType.AGENCY) ||
App.Participant.IsTypeFlagSet(Extensions.ParticipantType.MOORING) ||
App.Participant.IsTypeFlagSet(Extensions.ParticipantType.PILOT) ||
App.Participant.IsTypeFlagSet(Extensions.ParticipantType.PORT_ADMINISTRATION) ||
App.Participant.IsTypeFlagSet(Extensions.ParticipantType.TUG);
this.checkBoxEtaBerthFixed.IsEnabled = this.datePickerETABerth.IsEnabled;
this.datePickerETDBerth.IsEnabled = this.datePickerETABerth.IsEnabled;
this.checkBoxEtDBerthFixed.IsEnabled = this.datePickerETABerth.IsEnabled;
this.datePickerLockTime.IsEnabled = App.Participant.IsFlagSet(Extensions.ParticipantType.AGENCY) ||
App.Participant.IsFlagSet(Extensions.ParticipantType.MOORING) ||
App.Participant.IsFlagSet(Extensions.ParticipantType.PORT_ADMINISTRATION);
this.datePickerLockTime.IsEnabled = App.Participant.IsTypeFlagSet(Extensions.ParticipantType.AGENCY) ||
App.Participant.IsTypeFlagSet(Extensions.ParticipantType.MOORING) ||
App.Participant.IsTypeFlagSet(Extensions.ParticipantType.PORT_ADMINISTRATION);
this.checkBoxLockTimeFixed.IsEnabled = this.datePickerLockTime.IsEnabled;
this.datePickerZoneEntry.IsEnabled = App.Participant.IsFlagSet(Extensions.ParticipantType.AGENCY) ||
App.Participant.IsFlagSet(Extensions.ParticipantType.PILOT);
this.datePickerZoneEntry.IsEnabled = App.Participant.IsTypeFlagSet(Extensions.ParticipantType.AGENCY) ||
App.Participant.IsTypeFlagSet(Extensions.ParticipantType.PILOT);
this.checkBoxZoneEntryFixed.IsEnabled = this.datePickerZoneEntry.IsEnabled;
this.datePickerOperationStart.IsEnabled = App.Participant.IsFlagSet(Extensions.ParticipantType.TERMINAL);
this.datePickerOperationEnd.IsEnabled = App.Participant.IsFlagSet(Extensions.ParticipantType.TERMINAL);
}
private void buttonOK_Click(object sender, RoutedEventArgs e)
@ -85,8 +82,7 @@ namespace BreCalClient
this.Times.EtdBerth = this.datePickerETDBerth.Value;
this.Times.LockTime = this.datePickerLockTime.Value;
this.Times.ZoneEntry = this.datePickerZoneEntry.Value;
this.Times.OperationsStart = this.datePickerOperationStart.Value;
this.Times.OperationsEnd = this.datePickerOperationEnd.Value;
this.Times.EtaBerthFixed = this.checkBoxEtaBerthFixed.IsChecked;
this.Times.EtdBerthFixed = this.checkBoxEtDBerthFixed.IsChecked;
this.Times.LockTimeFixed = this.checkBoxLockTimeFixed.IsChecked;
@ -100,8 +96,7 @@ namespace BreCalClient
this.datePickerETDBerth.Value = this.Times.EtdBerth;
this.datePickerLockTime.Value = this.Times.LockTime;
this.datePickerZoneEntry.Value = this.Times.ZoneEntry;
this.datePickerOperationStart.Value = this.Times.OperationsStart;
this.datePickerOperationEnd.Value = this.Times.OperationsEnd;
this.checkBoxEtaBerthFixed.IsChecked = this.Times.EtaBerthFixed;
this.checkBoxEtDBerthFixed.IsChecked = this.Times.EtdBerthFixed;
this.checkBoxLockTimeFixed.IsChecked = this.Times.LockTimeFixed;
@ -110,5 +105,29 @@ namespace BreCalClient
#endregion
#region clear value event handler
private void contextMenuItemClearETA_Click(object sender, RoutedEventArgs e)
{
this.datePickerETABerth.Value = null;
}
private void contextMenuItemClearETD_Click(object sender, RoutedEventArgs e)
{
this.datePickerETDBerth.Value = null;
}
private void contextMenuItemClearLockTime_Click(object sender, RoutedEventArgs e)
{
this.datePickerLockTime.Value = null;
}
private void contextMenuItemClearZoneEntry_Click(object sender, RoutedEventArgs e)
{
this.datePickerZoneEntry.Value = null;
}
#endregion
}
}

View File

@ -0,0 +1,76 @@
<Window x:Class="BreCalClient.EditTimesTerminalControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:p = "clr-namespace:BreCalClient.Resources"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:local="clr-namespace:BreCalClient"
mc:Ignorable="d"
Title="{x:Static p:Resources.textEditTimes}" Loaded="Window_Loaded" Height="295" Width="400" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".4*" />
<ColumnDefinition Width=".6*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="28" />
<RowDefinition Height="56" />
<RowDefinition Height="56" />
<RowDefinition Height="28" />
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="{x:Static p:Resources.textOperationsStart}" HorizontalContentAlignment="Right" />
<Label Grid.Row="1" Grid.Column="0" Content="{x:Static p:Resources.textOperationsEnd}" HorizontalContentAlignment="Right" />
<Label Grid.Row="2" Grid.Column="0" Content="{x:Static p:Resources.textBerth}" HorizontalAlignment="Right" />
<Label Grid.Row="3" Grid.Column="0" Content="{x:Static p:Resources.textRotated}" HorizontalContentAlignment="Right" />
<Label Grid.Row="4" Grid.Column="0" Content="{x:Static p:Resources.textBerthRemarks}" HorizontalContentAlignment="Right" />
<Label Grid.Row="5" Grid.Column="0" Content="{x:Static p:Resources.textRemarks}" HorizontalContentAlignment="Right" />
<xctk:DateTimePicker Grid.Row="0" Grid.Column="1" Margin="2" Name="datePickerOperationStart" Format="Custom" FormatString="dd.MM. yyyy HH:mm">
<xctk:DateTimePicker.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemClearOperationStart" Click="contextMenuItemClearOperationStart_Click" >
<MenuItem.Icon>
<Image Source="Resources\delete.png" />
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</xctk:DateTimePicker.ContextMenu>
</xctk:DateTimePicker>
<xctk:DateTimePicker Grid.Row="1" Grid.Column="1" Margin="2" Name="datePickerOperationEnd" Format="Custom" FormatString="dd.MM. yyyy HH:mm">
<xctk:DateTimePicker.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemClearOperationEnd" Click="contextMenuItemClearOperationEnd_Click" >
<MenuItem.Icon>
<Image Source="Resources\delete.png" />
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</xctk:DateTimePicker.ContextMenu>
</xctk:DateTimePicker>
<ComboBox Name="comboBoxBerth" Grid.Column="1" Grid.Row="2" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id">
<ComboBox.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemBerth" Click="contextMenuItemBerth_Click" />
</ContextMenu>
</ComboBox.ContextMenu>
</ComboBox>
<ComboBox x:Name="comboBoxPierside" Grid.Column="1" Grid.Row="3" Margin="2" >
<ComboBoxItem Content="{x:Static p:Resources.textNotRotated}" />
<ComboBoxItem Content="{x:Static p:Resources.textRotated}" />
</ComboBox>
<TextBox Grid.Row="4" Grid.Column="1" Margin="2" Name="textBoxBerthRemarks" TextWrapping="Wrap" AcceptsReturn="True" SpellCheck.IsEnabled="True" AcceptsTab="True" />
<TextBox Grid.Row="5" Grid.Column="1" Margin="2" Name="textBoxRemarks" TextWrapping="Wrap" AcceptsReturn="True" SpellCheck.IsEnabled="True" AcceptsTab="True" />
<StackPanel Grid.Row="6" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Width= "80" Margin="2" Content="{x:Static p:Resources.textOK}" x:Name="buttonOK" Click="buttonOK_Click" />
<Button Width="80" Margin="2" Content="{x:Static p:Resources.textCancel}" x:Name="buttonCancel" Click="buttonCancel_Click"/>
</StackPanel>
</Grid>
</Window>

View File

@ -0,0 +1,96 @@
// Copyright (c) 2023 schick Informatik
// Description: Terminals have all different fields so a different dialog
//
using BreCalClient.misc.Model;
using System.Windows;
namespace BreCalClient
{
/// <summary>
/// Interaction logic for EditTimesTerminalControl.xaml
/// </summary>
public partial class EditTimesTerminalControl : Window, IEditTimesControl
{
public EditTimesTerminalControl()
{
InitializeComponent();
}
#region Properties
public Times Times { get; set; } = new();
#endregion
#region event handler
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.comboBoxBerth.ItemsSource = BreCalLists.Berths;
this.CopyToControls();
}
private void contextMenuItemClearOperationStart_Click(object sender, RoutedEventArgs e)
{
this.datePickerOperationStart.Value = null;
}
private void contextMenuItemClearOperationEnd_Click(object sender, RoutedEventArgs e)
{
this.datePickerOperationEnd.Value = null;
}
private void contextMenuItemBerth_Click(object sender, RoutedEventArgs e)
{
this.comboBoxBerth.SelectedIndex -= 1;
}
private void buttonOK_Click(object sender, RoutedEventArgs e)
{
this.CopyToModel();
this.DialogResult = true;
this.Close();
}
private void buttonCancel_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = false;
this.Close();
}
#endregion
#region private methods
private void CopyToModel()
{
switch(this.comboBoxPierside.SelectedIndex)
{
case 0: this.Times.PierSide = true; break;
case 1: this.Times.PierSide= false; break;
default: this.Times.PierSide = null; break;
}
this.Times.OperationsStart = this.datePickerOperationStart.Value;
this.Times.OperationsEnd = this.datePickerOperationEnd.Value;
this.Times.BerthId = (this.comboBoxBerth.SelectedItem != null) ? ((Berth)this.comboBoxBerth.SelectedItem).Id : null;
this.Times.Remarks = this.textBoxRemarks.Text.Trim();
this.Times.BerthInfo = this.textBoxBerthRemarks.Text.Trim();
}
private void CopyToControls()
{
this.datePickerOperationStart.Value = this.Times.OperationsStart;
this.datePickerOperationEnd.Value = this.Times.OperationsEnd;
if(this.Times.PierSide == null) { this.comboBoxPierside.SelectedIndex = -1; }
else this.comboBoxPierside.SelectedIndex = (this.Times.PierSide ?? false) ? 0 : 1;
this.comboBoxBerth.SelectedValue = this.Times.BerthId;
this.textBoxRemarks.Text = this.Times.Remarks;
this.textBoxBerthRemarks.Text = this.Times.BerthInfo;
}
#endregion
}
}

View File

@ -41,6 +41,16 @@ namespace BreCalClient
TUG = 64,
}
/// <summary>
/// Custom participant flags
/// </summary>
[Flags]
public enum ParticipantFlag
{
[Description("allow BSMD initial info")]
ALLOW_BSMD = 1,
}
/// <summary>
/// Should actually be defined in yaml
/// </summary>
@ -51,19 +61,25 @@ namespace BreCalClient
Shifting = 3
}
public enum SortOrder
{
SHIP_NAME,
ETA_ETD,
MODIFIED
}
#endregion
#region public helper
public static bool IsFlagSet(this Participant participant, ParticipantType flag)
public static bool IsTypeFlagSet(this Participant participant, ParticipantType flag)
{
return (participant.Type & (uint)flag) != 0;
}
public static void SetFlag(this Participant participant, bool value, ParticipantType flag)
public static bool IsFlagSet(this Participant participant, ParticipantFlag flag)
{
if (value) participant.Type |= (int)flag;
else participant.Type &= (int)~flag;
return (participant.Flags & (uint)flag) != 0;
}
public static string Truncate(this string value, int maxLength)

View File

@ -0,0 +1,23 @@
// Copyright (c) 2023 schick Informatik
// Description: Interfaces to simplify dialog handling
//
using BreCalClient.misc.Model;
namespace BreCalClient
{
internal interface IEditTimesControl
{
Times Times { get; set; }
bool? ShowDialog();
}
internal interface IEditShipcallTimesControl : IEditTimesControl
{
ShipcallControlModel ShipcallModel { get; set; }
}
}

View File

@ -5,6 +5,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BreCalClient"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:sets="clr-namespace:BreCalClient.Properties"
xmlns:p = "clr-namespace:BreCalClient.Resources"
mc:Ignorable="d"
Title="{DynamicResource textApplicationTitle}" Height="450" Width="800" Loaded="Window_Loaded" Closing="Window_Closing" Icon="Resources/containership.ico">
@ -57,11 +58,17 @@
<ColumnDefinition Width="60" />
<ColumnDefinition Width=".1*" />
<ColumnDefinition Width=".2*" />
<ColumnDefinition Width=".6*" />
<ColumnDefinition Width=".1*" />
<ColumnDefinition Width=".2*" />
<ColumnDefinition Width=".1*" />
<ColumnDefinition Width=".2*" />
</Grid.ColumnDefinitions>
<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"/>
<ComboBox x:Name="comboBoxSortOrder" Margin="2" Grid.Column="2" />
<ComboBox x:Name="comboBoxSortOrder" Margin="2" Grid.Column="2" SelectionChanged="comboBoxSortOrder_SelectionChanged" />
<CheckBox x:Name="checkboxShowCancelledCalls" Grid.Column="3" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="2" Checked="checkboxShowCancelledCalls_Checked" Unchecked="checkboxShowCancelledCalls_Checked" />
<Label Content="{x:Static p:Resources.textShowCancelledShipcalls}" Grid.Column="4" />
<Button Margin="2" Grid.Column="6" Content="{x:Static p:Resources.textClearFilters}" x:Name="buttonClearFilter" Click="buttonClearFilter_Click" Background="Transparent" />
</Grid>
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
@ -73,13 +80,13 @@
<ColumnDefinition Width=".15*" />
<ColumnDefinition Width=".15*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Background="#203864" Foreground="White" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"></Label>
<Label Grid.Column="1" Background="#203864" Foreground="White" Content="Agent" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"></Label>
<Label Grid.Column="2" Background="#203864" Foreground="White" Content="Festmacher" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"></Label>
<Label Grid.Column="3" Background="#203864" Foreground="White" Content="Hafenamt" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"></Label>
<Label Grid.Column="4" Background="#203864" Foreground="White" Content="Lotsen" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"></Label>
<Label Grid.Column="5" Background="#203864" Foreground="White" Content="Schlepper" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"></Label>
<Label Grid.Column="6" Background="#203864" Foreground="White" Content="Terminal" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"></Label>
<Label Grid.Column="0" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" Foreground="White" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"></Label>
<Label Grid.Column="1" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" Foreground="White" Content="Agent" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"></Label>
<Label Grid.Column="2" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" Foreground="White" Content="Festmacher" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"></Label>
<Label Grid.Column="3" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" Foreground="White" Content="Hafenamt" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"></Label>
<Label Grid.Column="4" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" Foreground="White" Content="Lotsen" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"></Label>
<Label Grid.Column="5" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" Foreground="White" Content="Schlepper" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"></Label>
<Label Grid.Column="6" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" Foreground="White" Content="Terminal" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"></Label>
</Grid>
<ScrollViewer Grid.Row="3" VerticalScrollBarVisibility="Auto">
<StackPanel x:Name="stackPanel"/>

View File

@ -2,18 +2,21 @@
// Description: Bremen calling main window
//
using BreCalClient.misc.Api;
using BreCalClient.misc.Client;
using BreCalClient.misc.Model;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using log4net;
using BreCalClient.misc.Api;
using BreCalClient.misc.Client;
using BreCalClient.misc.Model;
using static BreCalClient.Extensions;
namespace BreCalClient
{
/// <summary>
@ -21,21 +24,28 @@ namespace BreCalClient
/// </summary>
public partial class MainWindow : Window
{
private readonly ILog _log = LogManager.GetLogger(typeof(MainWindow));
private const int SHIPCALL_UPDATE_INTERVAL_SECONDS = 30;
#region Fields
private const int SHIPCALL_UPDATE_INTERVAL_SECONDS = 30;
private Timer? _timer;
private Credentials? _credentials;
private readonly Dictionary<int, ShipcallControlModel> _allShipcallsDict = new();
private readonly Dictionary<int, ShipcallControl> _allShipCallsControlDict = new();
private readonly List<ShipcallControlModel> _visibleControlModels = new();
private readonly DefaultApi _api;
private readonly ObservableCollection<ShipcallControlModel> _controlModels = new();
private List<Ship> _ships = new();
private readonly ConcurrentDictionary<int, Ship> _shipLookupDict = new();
private List<Berth> _berths = new();
private readonly ConcurrentDictionary<int, Berth> _berthLookupDict = new();
private List<Participant> _participants = new();
private readonly Dictionary<int, Participant> _participantLookupDict = new();
private readonly Dictionary<int, ShipcallControl> _shipCallControlDict = new();
private readonly CancellationTokenSource _tokenSource = new();
private CancellationTokenSource _tokenSource = new();
private LoginResult? _loginResult;
private bool _refreshImmediately = false;
private bool? _showCanceled = null;
private SortOrder? _sortOrder;
// private bool _filterChanged = false;
// private bool _sequenceChanged = false;
#endregion
@ -55,7 +65,7 @@ namespace BreCalClient
public MainWindow()
{
InitializeComponent();
_api = new DefaultApi();
_api = new DefaultApi(Properties.Settings.Default.API_URL);
_api.Configuration.ApiKeyPrefix["Authorization"] = "Bearer";
}
@ -67,10 +77,21 @@ namespace BreCalClient
{
labelGeneralStatus.Text = $"Connection {ConnectionStatus.UNDEFINED}";
labelVersion.Text = "V. " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
if (!string.IsNullOrEmpty(Properties.Settings.Default.APP_TITLE))
this.Title = Properties.Settings.Default.APP_TITLE;
searchFilterControl.SearchFilterChanged += SearchFilterControl_SearchFilterChanged;
searchFilterControl.LogoImageClicked += () =>
{
Process.Start("explorer", Properties.Settings.Default.LOGO_IMAGE_URL);
};
this.comboBoxSortOrder.ItemsSource = Enum.GetValues(typeof(Extensions.SortOrder));
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
// serialize filter settings
Properties.Settings.Default.FilterCriteria = this.searchFilterControl.SearchFilter.Serialize();
Properties.Settings.Default.Save();
_tokenSource.Cancel();
}
@ -82,12 +103,11 @@ namespace BreCalClient
return;
}
Credentials credentials = new(username: textUsername.Text.Trim(),
password: textPassword.Password.Trim());
_credentials = new(username: textUsername.Text.Trim(), password: textPassword.Password.Trim());
try
{
_loginResult = await _api.LoginPostAsync(credentials);
_loginResult = await _api.LoginPostAsync(_credentials);
if (_loginResult != null)
{
if (_loginResult.Id > 0)
@ -96,6 +116,7 @@ namespace BreCalClient
this._api.Configuration.ApiKey["Authorization"] = _loginResult.Token;
this.LoadStaticLists();
this.labelUsername.Text = $"{_loginResult.FirstName} {_loginResult.LastName}";
_timer = new Timer(RefreshToken, null, 4000000, Timeout.Infinite);
}
}
labelGeneralStatus.Text = $"Connection {ConnectionStatus.SUCCESSFUL}";
@ -112,6 +133,29 @@ namespace BreCalClient
}
}
private void RefreshToken(object? state)
{
try
{
_loginResult = _api.LoginPost(_credentials);
if (_loginResult != null)
{
if (_loginResult.Id > 0)
{
this._api.Configuration.ApiKey["Authorization"] = _loginResult.Token;
}
}
else
{
_log.Error("Token refresh: Renewed login returned empty login result");
}
}
catch (Exception ex)
{
_log.ErrorFormat("Error refreshing token: {0}", ex.Message);
}
}
private void buttonExit_Click(object sender, RoutedEventArgs e)
{
this.Close();
@ -119,18 +163,21 @@ namespace BreCalClient
private void buttonNew_Click(object sender, RoutedEventArgs e)
{
EditShipcallControl esc = new()
{
Participants = this._participants,
Ships = this._ships,
Berths = this._berths
};
EditShipcallControl esc = new();
if (esc.ShowDialog() ?? false)
{
// create UI & save new dialog model
this.UpdateShipcallUI(esc.Shipcall, new List<Times>());
this._api.ShipcallsPost(esc.Shipcall);
if (esc.ShipcallModel.Shipcall != null)
{
this.UpdateUI();
this._api.ShipcallsPost(esc.ShipcallModel.Shipcall); // save new ship call
this.AddShipcall(esc.ShipcallModel);
_refreshImmediately = true; // set flag to avoid timer loop termination
_tokenSource.Cancel(); // force timer loop end
}
}
}
@ -153,6 +200,7 @@ namespace BreCalClient
try
{
await _api.UserPutAsync(ud);
MessageBox.Show(BreCalClient.Resources.Resources.textPasswordChanged, BreCalClient.Resources.Resources.textConfirmation, MessageBoxButton.OK, MessageBoxImage.Information);
}
catch (Exception ex)
{
@ -166,48 +214,76 @@ namespace BreCalClient
ad.ShowDialog();
}
private void buttonClearFilter_Click(object sender, RoutedEventArgs e)
{
this.searchFilterControl.ClearFilters();
this.checkboxShowCancelledCalls.IsChecked = false;
this.FilterShipcalls();
}
private void SearchFilterControl_SearchFilterChanged()
{
this.FilterShipcalls();
this.UpdateUI();
}
private void checkboxShowCancelledCalls_Checked(object sender, RoutedEventArgs e)
{
this._showCanceled = this.checkboxShowCancelledCalls.IsChecked;
this.SearchFilterControl_SearchFilterChanged();
}
private void comboBoxSortOrder_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
_sortOrder = (Extensions.SortOrder) this.comboBoxSortOrder.SelectedIndex;
this.FilterShipcalls();
this.UpdateUI();
}
#endregion
#region private methods
#region network operations
private async void LoadStaticLists()
{
this._berths = await _api.BerthsGetAsync();
foreach(var berth in this._berths)
_berthLookupDict[berth.Id] = berth;
this.searchFilterControl.SetBerths(this._berths);
this._ships = await _api.ShipsGetAsync();
foreach(var ship in this._ships)
_shipLookupDict[ship.Id] = ship;
this._participants = await _api.ParticipantsGetAsync();
BreCalLists.InitializeBerths(await _api.BerthsGetAsync());
BreCalLists.InitializeShips(await _api.ShipsGetAsync());
BreCalLists.InitializeParticipants(await _api.ParticipantsGetAsync());
List<Participant> agencies = new();
foreach (Participant participant in this._participants)
this.searchFilterControl.SetBerths(BreCalLists.Berths);
foreach (Participant participant in BreCalLists.Participants)
{
this._participantLookupDict[participant.Id] = participant;
if (_loginResult?.ParticipantId == participant.Id)
{
App.Participant = participant;
EnableControlsForParticipant();
}
if(participant.IsFlagSet(Extensions.ParticipantType.AGENCY))
agencies.Add(participant);
}
this.searchFilterControl.SetAgencies(agencies);
this.searchFilterControl.SetAgencies(BreCalLists.Participants_Agent);
if (!string.IsNullOrEmpty(Properties.Settings.Default.FilterCriteria))
{
SearchFilterModel? sfm = SearchFilterModel.Deserialize(Properties.Settings.Default.FilterCriteria);
if (sfm != null)
this.searchFilterControl.SetFilterFromModel(sfm);
}
_ = Task.Run(() => RefreshShipcalls());
}
private void EnableControlsForParticipant()
{
if (App.Participant.IsFlagSet(Extensions.ParticipantType.BSMD))
this.buttonNew.Visibility = Visibility.Visible;
}
public async Task RefreshShipcalls()
{
while (!_tokenSource.Token.IsCancellationRequested)
while (!_tokenSource.Token.IsCancellationRequested || _refreshImmediately)
{
if (_refreshImmediately)
{
_refreshImmediately = false;
_tokenSource = new CancellationTokenSource();
}
List<Shipcall>? shipcalls = null;
try
{
@ -226,109 +302,241 @@ namespace BreCalClient
labelStatusBar.Text = ex.Message;
}));
}
if (shipcalls != null)
{
foreach (Shipcall shipcall in shipcalls)
{
// load times for each shipcall
List<Times> currentTimes = await _api.TimesGetAsync(shipcall.Id);
this.UpdateShipcallUI(shipcall, currentTimes);
}
List<ShipcallControl> removeList = new();
foreach (ShipcallControlModel scm in this._controlModels)
{
if (shipcalls.Find(s => s.Id == scm.Shipcall?.Id) == null) // the model is no longer in the search result
if(!_allShipcallsDict.ContainsKey(shipcall.Id))
{
if((scm.Shipcall != null) && this._shipCallControlDict.ContainsKey(scm.Shipcall.Id))
// add entry
ShipcallControlModel scm = new()
{
this.Dispatcher.Invoke((Action)(() =>
{
this.stackPanel.Children.Remove(this._shipCallControlDict[scm.Shipcall.Id]);
}));
this._shipCallControlDict.Remove(scm.Shipcall.Id);
}
Shipcall = shipcall,
Times = currentTimes
};
this.AddShipcall(scm);
}
else
{
// update entry
_allShipcallsDict[shipcall.Id].Shipcall = shipcall;
_allShipcallsDict[shipcall.Id].Times = currentTimes;
UpdateShipcall(_allShipcallsDict[shipcall.Id]);
}
}
List<int> existingIds = new(this._allShipcallsDict.Keys);
foreach (int existingId in existingIds)
{
if (shipcalls.Find(s => s.Id == existingId) == null) // the model is no longer in the search result
{
this.RemoveShipcall(existingId);
}
}
this.FilterShipcalls();
this.UpdateUI();
}
await Task.Delay(TimeSpan.FromSeconds(SHIPCALL_UPDATE_INTERVAL_SECONDS), _tokenSource.Token);
try
{
await Task.Delay(TimeSpan.FromSeconds(SHIPCALL_UPDATE_INTERVAL_SECONDS), _tokenSource.Token);
}
catch(TaskCanceledException) { }
}
}
private void UpdateShipcallUI(Shipcall shipcall, List<Times> times)
{
ShipcallControlModel? selectedSCMModel = null;
#endregion
foreach (ShipcallControlModel scm in this._controlModels)
#region basic operations
private void AddShipcall(ShipcallControlModel scm)
{
if (scm.Shipcall == null) return;
_allShipcallsDict[scm.Shipcall.Id] = scm;
Shipcall shipcall = scm.Shipcall;
if (BreCalLists.ShipLookupDict.ContainsKey(shipcall.ShipId))
scm.Ship = BreCalLists.ShipLookupDict[shipcall.ShipId];
if (BreCalLists.BerthLookupDict.ContainsKey(shipcall.ArrivalBerthId ?? 0))
scm.Berth = BreCalLists.BerthLookupDict[shipcall.ArrivalBerthId ?? 0].Name;
scm.AssignParticipants(BreCalLists.Participants);
this.Dispatcher.Invoke(() =>
{
if (scm.Shipcall?.Id == shipcall.Id)
ShipcallControl sc = new()
{
selectedSCMModel = scm;
break;
Height = 120,
ShipcallControlModel = scm
};
sc.EditTimesRequested += Sc_EditTimesRequested;
sc.EditRequested += Sc_EditRequested;
sc.EditAgencyRequested += Sc_EditAgencyRequested;
sc.RefreshData();
this._allShipCallsControlDict[scm.Shipcall.Id] = sc;
});
}
private static void UpdateShipcall(ShipcallControlModel scm)
{
if(scm.Shipcall == null) return;
Shipcall shipcall = scm.Shipcall;
if (BreCalLists.ShipLookupDict.ContainsKey(shipcall.ShipId))
scm.Ship = BreCalLists.ShipLookupDict[shipcall.ShipId];
if (BreCalLists.BerthLookupDict.ContainsKey(shipcall.ArrivalBerthId ?? 0))
scm.Berth = BreCalLists.BerthLookupDict[shipcall.ArrivalBerthId ?? 0].Name;
scm.AssignParticipants(BreCalLists.Participants);
}
private void RemoveShipcall(int shipcallId)
{
this.Dispatcher.Invoke(() =>
{
this.stackPanel.Children.Remove(this._allShipCallsControlDict[shipcallId]);
});
ShipcallControlModel removeModel = this._allShipcallsDict[shipcallId];
_visibleControlModels.Remove(removeModel);
this._allShipCallsControlDict.Remove(shipcallId);
this._allShipcallsDict.Remove(shipcallId);
}
private void FilterShipcalls()
{
SearchFilterModel sfm = this.searchFilterControl.SearchFilter;
this._visibleControlModels.Clear();
// first add everything
this._visibleControlModels.AddRange(_allShipcallsDict.Values);
// now remove elements whose filter criteria are met
if(sfm.Berths.Count > 0 )
{
this._visibleControlModels.RemoveAll(x => !sfm.Berths.Contains((x.Shipcall?.ArrivalBerthId) ?? -1));
}
if(sfm.Agencies.Count > 0 )
{
_ = this._visibleControlModels.RemoveAll((x) =>
{
Participant? agency = x.GetParticipantForType(ParticipantType.AGENCY);
if(agency != null)
{
return !sfm.Agencies.Contains(agency.Id);
}
return true;
});
}
if(sfm.Categories.Count > 0 )
{
_ = this._visibleControlModels.RemoveAll(x => !sfm.Categories.Contains((x.Shipcall?.Type) ?? -1));
}
if(!string.IsNullOrEmpty(sfm.SearchString))
{
_ = this._visibleControlModels.RemoveAll(x => !(x.ContainsRemarkText(sfm.SearchString) || (x.Ship?.Name.Contains(sfm.SearchString, StringComparison.InvariantCultureIgnoreCase) ?? false)));
}
if(sfm.ShipLengthTo != null)
{
_ = this._visibleControlModels.RemoveAll(x => x.Ship?.Length > sfm.ShipLengthTo);
}
if(sfm.ShipLengthFrom != null)
{
_ = this._visibleControlModels.RemoveAll(x => x.Ship?.Length < sfm.ShipLengthFrom);
}
if(sfm.EtaFrom != null)
{
_ = this._visibleControlModels.RemoveAll(x => x.Shipcall?.Eta < sfm.EtaFrom);
}
if(sfm.EtaTo != null)
{
_ = this._visibleControlModels.RemoveAll(x => x.Shipcall?.Eta > sfm.EtaTo);
}
if(!_showCanceled ?? true) // canceled calls are filtered by default
{
_ = this._visibleControlModels.RemoveAll(x => x.Shipcall?.Canceled ?? false);
}
if (this._sortOrder != null)
{
switch(this._sortOrder)
{
case Extensions.SortOrder.SHIP_NAME:
this._visibleControlModels.Sort((x, y) => { if (x.Ship == null) return 0; if (y.Ship == null) return 0; return x.Ship.Name.CompareTo(y.Ship.Name); });
break;
case Extensions.SortOrder.MODIFIED:
this._visibleControlModels.Sort((x, y) => { if (x.Shipcall == null) return 0; if (y.Shipcall == null) return 0; return DateTime.Compare(x.Shipcall.Modified ?? x.Shipcall.Created, y.Shipcall.Modified ?? x.Shipcall.Created); });
break;
case Extensions.SortOrder.ETA_ETD:
this._visibleControlModels.Sort((x, y) =>
{
if (x.Shipcall == null) return 0;
if (y.Shipcall == null) return 0;
DateTime xDate = (x.Shipcall.Type == (int) Extensions.TypeEnum.Incoming) ? x.Shipcall.Eta : x.Shipcall.Etd ?? x.Shipcall.Eta;
DateTime yDate = (y.Shipcall.Type == (int) Extensions.TypeEnum.Incoming) ? y.Shipcall.Eta : y.Shipcall.Etd ?? y.Shipcall.Eta;
return DateTime.Compare(xDate, yDate);
});
break;
default:
break;
}
}
}
if (selectedSCMModel != null)
{
selectedSCMModel.Shipcall = shipcall;
selectedSCMModel.Times = times;
}
else
{
// no: create new entry
selectedSCMModel = new()
{
Shipcall = shipcall,
Times = times
};
if (this._shipLookupDict.ContainsKey(shipcall.ShipId))
selectedSCMModel.Ship = this._shipLookupDict[shipcall.ShipId];
if (this._berthLookupDict.ContainsKey(shipcall.ArrivalBerthId ?? 0))
selectedSCMModel.Berth = this._berthLookupDict[shipcall.ArrivalBerthId ?? 0].Name;
_controlModels.Add(selectedSCMModel);
this.Dispatcher.Invoke(new Action(() =>
#endregion
private void UpdateUI()
{
this.Dispatcher.Invoke(new Action(() =>
{
this.stackPanel.Children.Clear();
foreach(ShipcallControlModel visibleModel in this._visibleControlModels)
{
ShipcallControl sc = new()
if (visibleModel.Shipcall == null) continue; // should not happen
if(this._allShipCallsControlDict.ContainsKey(visibleModel.Shipcall.Id))
{
Height = 120,
ShipcallControlModel = selectedSCMModel,
ParticipantDict = _participantLookupDict
};
sc.EditTimesRequested += Sc_EditTimesRequested;
sc.EditRequested += Sc_EditRequested;
this.stackPanel.Children.Add(sc);
this._shipCallControlDict[shipcall.Id] = sc;
}));
}
selectedSCMModel.AssignParticipants(this._participants);
this.Dispatcher.Invoke((Action)(() =>
{
this._shipCallControlDict[shipcall.Id].RefreshData();
this._allShipCallsControlDict[visibleModel.Shipcall.Id].RefreshData();
this.stackPanel.Children.Add(this._allShipCallsControlDict[visibleModel.Shipcall.Id]);
}
}
}));
}
#region control event handler
private async void Sc_EditRequested(ShipcallControl obj)
{
Shipcall? sc = obj.ShipcallControlModel?.Shipcall;
if (sc != null)
if (obj.ShipcallControlModel != null)
{
EditShipcallControl esc = new()
{
Shipcall = sc,
Ships = _ships,
Participants = _participants,
Berths = _berths
ShipcallModel = obj.ShipcallControlModel
};
if(esc.ShowDialog() ?? false)
{
try
{
await _api.ShipcallsPutAsync(sc);
await _api.ShipcallsPutAsync(obj.ShipcallControlModel.Shipcall);
obj.RefreshData();
_refreshImmediately = true;
_tokenSource.Cancel();
}
catch (Exception ex)
{
@ -338,16 +546,21 @@ namespace BreCalClient
}
}
private async void Sc_EditTimesRequested(ShipcallControl obj, Times? times)
private async void Sc_EditTimesRequested(ShipcallControl obj, Times? times, Extensions.ParticipantType participantType)
{
// show a dialog that lets the user create / update times for the given shipcall
EditTimesControl etc = new();
IEditTimesControl etc = (participantType == ParticipantType.TERMINAL) ? new EditTimesTerminalControl() : new EditTimesControl();
bool wasEdit = false;
if (times != null)
{
etc.Times = times;
wasEdit = true;
}
// actually we should only do this on create but we have existing data
etc.Times.ParticipantType = (int) participantType;
if(etc.ShowDialog() ?? false)
{
try
@ -363,10 +576,12 @@ namespace BreCalClient
{
etc.Times.ShipcallId = obj.ShipcallControlModel.Shipcall.Id;
}
await _api.TimesPostAsync(etc.Times);
Id apiResultId = await _api.TimesPostAsync(etc.Times);
etc.Times.Id = apiResultId.VarId;
obj.ShipcallControlModel?.Times.Add(etc.Times);
}
obj.RefreshData();
_refreshImmediately = true;
_tokenSource.Cancel();
}
catch (Exception ex)
{
@ -375,6 +590,70 @@ namespace BreCalClient
}
}
private async void Sc_EditAgencyRequested(ShipcallControl sc, Times? times)
{
IEditShipcallTimesControl? editControl = null;
switch(sc.ShipcallControlModel?.Shipcall?.Type)
{
case (int)TypeEnum.Incoming:
editControl = new EditTimesAgencyIncomingControl();
break;
case (int)TypeEnum.Outgoing:
editControl = new EditTimesAgencyOutgoingControl();
break;
case (int)TypeEnum.Shifting:
editControl = new EditTimesAgencyShiftingControl();
break;
}
if (editControl != null)
{
editControl.ShipcallModel = sc.ShipcallControlModel ?? new ShipcallControlModel();
bool wasEdit = false;
if (times != null)
{
editControl.Times = times;
wasEdit = true;
}
editControl.Times.ParticipantType = (int)ParticipantType.AGENCY;
if(editControl.ShowDialog() ?? false)
{
try
{
editControl.Times.ParticipantId = App.Participant.Id;
if (wasEdit)
{
await _api.TimesPutAsync(editControl.Times);
}
else
{
if ((sc.ShipcallControlModel != null) && (sc.ShipcallControlModel.Shipcall != null))
{
editControl.Times.ShipcallId = sc.ShipcallControlModel.Shipcall.Id;
}
Id resultAPI_Id = await _api.TimesPostAsync(editControl.Times);
editControl.Times.Id = resultAPI_Id.VarId;
sc.ShipcallControlModel?.Times.Add(editControl.Times);
}
await _api.ShipcallsPutAsync(editControl.ShipcallModel.Shipcall);
_refreshImmediately = true;
_tokenSource.Cancel();
}
catch(Exception ex)
{
ShowErrorDialog(ex.Message, "Error saving agency information");
}
}
}
}
#endregion
#region helper
private void ShowErrorDialog(string message, string caption)
{
Dispatcher.Invoke(new Action(() =>
@ -383,6 +662,12 @@ namespace BreCalClient
}));
}
private void EnableControlsForParticipant()
{
if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.BSMD))
this.buttonNew.Visibility = Visibility.Visible;
}
#endregion
}

View File

@ -5,10 +5,11 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<Project>
<PropertyGroup>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>0.3.0.0</ApplicationVersion>
<ApplicationVersion>0.7.0.0</ApplicationVersion>
<BootstrapperEnabled>False</BootstrapperEnabled>
<Configuration>Release</Configuration>
<CreateWebPageOnPublish>True</CreateWebPageOnPublish>
<ErrorReportUrl>http://www.textbausteine.net</ErrorReportUrl>
<GenerateManifests>true</GenerateManifests>
<Install>True</Install>
<InstallFrom>Web</InstallFrom>

View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
<PropertyGroup>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>0.7.0.0</ApplicationVersion>
<BootstrapperEnabled>False</BootstrapperEnabled>
<Configuration>Debug</Configuration>
<CreateWebPageOnPublish>True</CreateWebPageOnPublish>
<ErrorReportUrl>http://www.textbausteine.net</ErrorReportUrl>
<GenerateManifests>true</GenerateManifests>
<Install>True</Install>
<InstallFrom>Web</InstallFrom>
<InstallUrl>https://www.bsmd-emswe.eu/testclient/</InstallUrl>
<IsRevisionIncremented>False</IsRevisionIncremented>
<IsWebBootstrapper>True</IsWebBootstrapper>
<MapFileExtensions>True</MapFileExtensions>
<OpenBrowserOnPublish>False</OpenBrowserOnPublish>
<Platform>Any CPU</Platform>
<PublishUrl>bin\publish.test\</PublishUrl>
<PublishProtocol>ClickOnce</PublishProtocol>
<PublishReadyToRun>True</PublishReadyToRun>
<PublishSingleFile>True</PublishSingleFile>
<SelfContained>True</SelfContained>
<SignatureAlgorithm>(none)</SignatureAlgorithm>
<SignManifests>False</SignManifests>
<TargetFramework>net6.0-windows</TargetFramework>
<UpdateEnabled>True</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateRequired>False</UpdateRequired>
<WebPageFileName>Publish.html</WebPageFileName>
<CreateDesktopShortcut>True</CreateDesktopShortcut>
<ErrorReportUrl>https://www.bsmd-emswe.eu/</ErrorReportUrl>
<ProductName>Bremen Calling Testclient</ProductName>
<PublisherName>Informatikbüro Daniel Schick</PublisherName>
<SuiteName>Bremen Calling</SuiteName>
<SupportUrl>http://www.textbausteine.net/</SupportUrl>
<PublishDir>bin\Debug\net6.0-windows\win-x64\app.publish\</PublishDir>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup>
<ItemGroup>
<PublishFile Include="containership.ico">
<Group>
</Group>
<TargetPath>
</TargetPath>
<PublishState>Include</PublishState>
<IncludeHash>true</IncludeHash>
<FileType>File</FileType>
</PublishFile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,74 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace BreCalClient.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.5.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("https://brecal.bsmd-emswe.eu")]
public string API_URL {
get {
return ((string)(this["API_URL"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("#751D1F")]
public string BG_COLOR {
get {
return ((string)(this["BG_COLOR"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("!!Bremen calling Testversion!!")]
public string APP_TITLE {
get {
return ((string)(this["APP_TITLE"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("https://www.textbausteine.net/")]
public string LOGO_IMAGE_URL {
get {
return ((string)(this["LOGO_IMAGE_URL"]));
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string FilterCriteria {
get {
return ((string)(this["FilterCriteria"]));
}
set {
this["FilterCriteria"] = value;
}
}
}
}

View File

@ -0,0 +1,21 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="BreCalClient.Properties" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="API_URL" Type="System.String" Scope="Application">
<Value Profile="(Default)">https://brecal.bsmd-emswe.eu</Value>
</Setting>
<Setting Name="BG_COLOR" Type="System.String" Scope="Application">
<Value Profile="(Default)">#751D1F</Value>
</Setting>
<Setting Name="APP_TITLE" Type="System.String" Scope="Application">
<Value Profile="(Default)">!!Bremen calling Testversion!!</Value>
</Setting>
<Setting Name="LOGO_IMAGE_URL" Type="System.String" Scope="Application">
<Value Profile="(Default)">https://www.textbausteine.net/</Value>
</Setting>
<Setting Name="FilterCriteria" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
</Settings>
</SettingsFile>

View File

@ -0,0 +1,40 @@
# Bremen calling WPF client
## Introduction
## API / code generation
The Rest API client is generated from the OpenAPI specification [BreCalApi.yaml](../../misc/BreCalApiyaml) into the C# file [BreCalApi.cs](../../misc/BreCalApi.cs).
In order to do so an extension for Visual Studio needs to be installed: REST API Client Code Generator for VS 2022.
https://marketplace.visualstudio.com/items?itemName=ChristianResmaHelle.ApiClientCodeGenerator2022
This extension has multiple generators, for this project OpenApiCodeGenerator is used (must be set on the yaml file in the project settings).
Internally this uses Java, currently > 55 which translates into Java JDK 17 LTS.
If code generation is not working please have a look in the output pane and select appropriate output source.
## Installation
The client is deployed via ClickOnce.
To deploy the test client, leave everything as it is in develop branch and publish using the profile [ClickOnceTestProfile.pubxml](./Properties/PublishProfiles/ClickOnceTestProfile.pubxml).
To deploy the productive version, use the profile [ClickOnceProfile.pubxml](./Properties/PublishProfiles/ClickOnceProfile.pubxml).
You will also need to change the AssemblyName in BreCalClient.csproj back to BreCalClient.
```xml
<AssemblyName>BreCalClient</AssemblyName>
```
Resources are embedded in the assembly. Therefore wherever Resources are referenced via assembly name this name has to be adjusted as well. For example:
```C++
this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalClient;component/Resources/arrow_right_green.png"));
```
It is debatable if the single contained file deployment makes sense at this point. Installation file size
is at about 150MB which takes a long time to upload however it should run on any current windows installation.
Theoretically it should also work on Linux.
### Signing
Currently neither assemblies nor the installation is signed. This probably only makes sense with a paid public code signing certificate.

View File

@ -83,9 +83,9 @@ namespace BreCalClient.Resources {
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>
public static byte[] arrow_right_blue {
public static byte[] arrow_right_green {
get {
object obj = ResourceManager.GetObject("arrow_right_blue", resourceCulture);
object obj = ResourceManager.GetObject("arrow_right_green", resourceCulture);
return ((byte[])(obj));
}
}
@ -93,9 +93,9 @@ namespace BreCalClient.Resources {
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>
public static byte[] arrow_up_green {
public static byte[] arrow_up_blue {
get {
object obj = ResourceManager.GetObject("arrow_up_green", resourceCulture);
object obj = ResourceManager.GetObject("arrow_up_blue", resourceCulture);
return ((byte[])(obj));
}
}
@ -150,6 +150,16 @@ namespace BreCalClient.Resources {
}
}
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>
public static byte[] delete {
get {
object obj = ResourceManager.GetObject("delete", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>
@ -225,6 +235,15 @@ namespace BreCalClient.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Berth remarks.
/// </summary>
public static string textBerthRemarks {
get {
return ResourceManager.GetString("textBerthRemarks", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Berths.
/// </summary>
@ -234,6 +253,15 @@ namespace BreCalClient.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to BSMD right to edit granted.
/// </summary>
public static string textBSMDGranted {
get {
return ResourceManager.GetString("textBSMDGranted", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Bunkering.
/// </summary>
@ -297,6 +325,33 @@ namespace BreCalClient.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Clear assignment.
/// </summary>
public static string textClearAssignment {
get {
return ResourceManager.GetString("textClearAssignment", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Clear filters.
/// </summary>
public static string textClearFilters {
get {
return ResourceManager.GetString("textClearFilters", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Clear value.
/// </summary>
public static string textClearValue {
get {
return ResourceManager.GetString("textClearValue", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Close.
/// </summary>
@ -306,6 +361,15 @@ namespace BreCalClient.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Confirmation.
/// </summary>
public static string textConfirmation {
get {
return ResourceManager.GetString("textConfirmation", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Departure terminal.
/// </summary>
@ -396,6 +460,15 @@ namespace BreCalClient.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Incoming.
/// </summary>
public static string textIncoming {
get {
return ResourceManager.GetString("textIncoming", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Interval.
/// </summary>
@ -405,6 +478,15 @@ namespace BreCalClient.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Length.
/// </summary>
public static string textLength {
get {
return ResourceManager.GetString("textLength", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to L/W.
/// </summary>
@ -513,6 +595,15 @@ namespace BreCalClient.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Outgoing.
/// </summary>
public static string textOutgoing {
get {
return ResourceManager.GetString("textOutgoing", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Participants.
/// </summary>
@ -531,6 +622,15 @@ namespace BreCalClient.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Password changed..
/// </summary>
public static string textPasswordChanged {
get {
return ResourceManager.GetString("textPasswordChanged", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Pier side.
/// </summary>
@ -630,6 +730,33 @@ namespace BreCalClient.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Shifting.
/// </summary>
public static string textShifting {
get {
return ResourceManager.GetString("textShifting", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Shifting from.
/// </summary>
public static string textShiftingFrom {
get {
return ResourceManager.GetString("textShiftingFrom", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Shifting to.
/// </summary>
public static string textShiftingTo {
get {
return ResourceManager.GetString("textShiftingTo", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Ship.
/// </summary>
@ -648,6 +775,15 @@ namespace BreCalClient.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Show cancelled calls.
/// </summary>
public static string textShowCancelledShipcalls {
get {
return ResourceManager.GetString("textShowCancelledShipcalls", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Sort order.
/// </summary>
@ -738,6 +874,15 @@ namespace BreCalClient.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Width.
/// </summary>
public static string textWidth {
get {
return ResourceManager.GetString("textWidth", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Zone entry.
/// </summary>

View File

@ -199,10 +199,10 @@
<data name="textEditTimes" xml:space="preserve">
<value>Zeiten bearbeiten</value>
</data>
<data name="textETABerth" xml:space="preserve">
<data name="textETABerth" xml:space="preserve">
<value>ETA Liegeplatz</value>
</data>
<data name="textETDBerth" xml:space="preserve">
<data name="textETDBerth" xml:space="preserve">
<value>ETD Liegeplatz</value>
</data>
<data name="textEnterKeyword" xml:space="preserve">
@ -226,7 +226,7 @@
<data name="textFixed" xml:space="preserve">
<value>Fest</value>
</data>
<data name="textLockTime" xml:space="preserve">
<data name="textLockTime" xml:space="preserve">
<value>Zeit Schleuse</value>
</data>
<data name="textOperationsEnd" xml:space="preserve">
@ -236,7 +236,7 @@
<value>Operation Start</value>
</data>
<data name="textMooredLock" xml:space="preserve">
<value>Festmacher in Schleuse</value>
<value>auch in Schleuse</value>
</data>
<data name="textMooring" xml:space="preserve">
<value>Festmacher</value>
@ -358,4 +358,52 @@
<data name="worker2" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>worker2.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="textClearAssignment" xml:space="preserve">
<value>Zuordnung entfernen</value>
</data>
<data name="textClearValue" xml:space="preserve">
<value>Eingabe löschen</value>
</data>
<data name="textConfirmation" xml:space="preserve">
<value>Bestätigung</value>
</data>
<data name="textPasswordChanged" xml:space="preserve">
<value>Passwort geändert.</value>
</data>
<data name="textClearFilters" xml:space="preserve">
<value>Filter löschen</value>
</data>
<data name="textShowCancelledShipcalls" xml:space="preserve">
<value>Stornierte anzeigen</value>
</data>
<data name="textBerthRemarks" xml:space="preserve">
<value>Liegeplatz Informationen</value>
</data>
<data name="textBSMDGranted" xml:space="preserve">
<value>Freigabe zur Bearb. f. BSMD erteilt</value>
</data>
<data name="textRemarks" xml:space="preserve">
<value>Info</value>
</data>
<data name="textIncoming" xml:space="preserve">
<value>Einkommend</value>
</data>
<data name="textOutgoing" xml:space="preserve">
<value>Ausgehend</value>
</data>
<data name="textShifting" xml:space="preserve">
<value>Verholung</value>
</data>
<data name="textLength" xml:space="preserve">
<value>Länge</value>
</data>
<data name="textShiftingFrom" xml:space="preserve">
<value>Verholung von</value>
</data>
<data name="textShiftingTo" xml:space="preserve">
<value>Verholung nach</value>
</data>
<data name="textWidth" xml:space="preserve">
<value>Breite</value>
</data>
</root>

View File

@ -124,11 +124,11 @@
<data name="arrow_down_red" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>arrow_down_red.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="arrow_right_blue" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>arrow_right_blue.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<data name="arrow_right_green" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>arrow_right_green.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="arrow_up_green" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>arrow_up_green.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<data name="arrow_up_blue" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>arrow_up_blue.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="arrow_up_red" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>arrow_up_red.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
@ -145,6 +145,9 @@
<data name="containership1" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>containership.ico;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="delete" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>delete.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="emergency_stop_button" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>emergency_stop_button.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
@ -169,9 +172,15 @@
<data name="textBerth" xml:space="preserve">
<value>Berth</value>
</data>
<data name="textBerthRemarks" xml:space="preserve">
<value>Berth remarks</value>
</data>
<data name="textBerths" xml:space="preserve">
<value>Berths</value>
</data>
<data name="textBSMDGranted" xml:space="preserve">
<value>BSMD right to edit granted</value>
</data>
<data name="textBunkering" xml:space="preserve">
<value>Bunkering</value>
</data>
@ -193,9 +202,21 @@
<data name="textChangePassword" xml:space="preserve">
<value>Change password</value>
</data>
<data name="textClearAssignment" xml:space="preserve">
<value>Clear assignment</value>
</data>
<data name="textClearFilters" xml:space="preserve">
<value>Clear filters</value>
</data>
<data name="textClearValue" xml:space="preserve">
<value>Clear value</value>
</data>
<data name="textClose" xml:space="preserve">
<value>Close</value>
</data>
<data name="textConfirmation" xml:space="preserve">
<value>Confirmation</value>
</data>
<data name="textDepartureTerminal" xml:space="preserve">
<value>Departure terminal</value>
</data>
@ -226,9 +247,15 @@
<data name="textFrom" xml:space="preserve">
<value>from</value>
</data>
<data name="textIncoming" xml:space="preserve">
<value>Incoming</value>
</data>
<data name="textInterval" xml:space="preserve">
<value>Interval</value>
</data>
<data name="textLength" xml:space="preserve">
<value>Length</value>
</data>
<data name="textLengthWidth" xml:space="preserve">
<value>L/W</value>
</data>
@ -265,12 +292,18 @@
<data name="textOperationsStart" xml:space="preserve">
<value>Operations start</value>
</data>
<data name="textOutgoing" xml:space="preserve">
<value>Outgoing</value>
</data>
<data name="textParticipants" xml:space="preserve">
<value>Participants</value>
</data>
<data name="textPassword" xml:space="preserve">
<value>Password</value>
</data>
<data name="textPasswordChanged" xml:space="preserve">
<value>Password changed.</value>
</data>
<data name="textPierside" xml:space="preserve">
<value>Pier side</value>
</data>
@ -304,12 +337,24 @@
<data name="textSearch" xml:space="preserve">
<value>Search</value>
</data>
<data name="textShifting" xml:space="preserve">
<value>Shifting</value>
</data>
<data name="textShiftingFrom" xml:space="preserve">
<value>Shifting from</value>
</data>
<data name="textShiftingTo" xml:space="preserve">
<value>Shifting to</value>
</data>
<data name="textShip" xml:space="preserve">
<value>Ship</value>
</data>
<data name="textShipLength" xml:space="preserve">
<value>Ship length</value>
</data>
<data name="textShowCancelledShipcalls" xml:space="preserve">
<value>Show cancelled calls</value>
</data>
<data name="textSortOrder" xml:space="preserve">
<value>Sort order</value>
</data>
@ -340,6 +385,9 @@
<data name="textVoyage" xml:space="preserve">
<value>Voyage</value>
</data>
<data name="textWidth" xml:space="preserve">
<value>Width</value>
</data>
<data name="textZoneEntryTime" xml:space="preserve">
<value>Zone entry</value>
</data>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -59,23 +59,23 @@
<ColumnDefinition Width="30" />
<ColumnDefinition Width=".5*" />
</Grid.ColumnDefinitions>
<DatePicker x:Name="datePickerETAFrom" Grid.Column="0" Margin="2" />
<DatePicker x:Name="datePickerETAFrom" Grid.Column="0" Margin="2" SelectedDateChanged="datePickerETAFrom_SelectedDateChanged" SelectedDate="{Binding Path=EtaFrom}"/>
<Label Grid.Column="1" Content="{x:Static p:Resources.textTo}" />
<DatePicker x:Name="datePickerETATo" Grid.Column="2" Margin="2" />
<DatePicker x:Name="datePickerETATo" Grid.Column="2" Margin="2" SelectedDateChanged="datePickerETATo_SelectedDateChanged" SelectedDate="{Binding Path=EtaTo}"/>
</Grid>
<xctk:CheckComboBox x:Name="comboBoxCategories" Grid.Column="4" Margin="2" />
<xctk:CheckComboBox x:Name="comboBoxCategories" Grid.Column="4" Margin="2" ItemSelectionChanged="comboBoxCategories_ItemSelectionChanged" />
<Grid Grid.Column="6" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".5*" />
<ColumnDefinition Width="30" />
<ColumnDefinition Width=".5*" />
</Grid.ColumnDefinitions>
<xctk:DoubleUpDown x:Name="upDownShiplengthFrom" Grid.Column="0" Margin="2" Minimum="0" Maximum="1000" />
<xctk:DoubleUpDown x:Name="upDownShiplengthFrom" Grid.Column="0" Margin="2" Minimum="0" Maximum="1000" ValueChanged="upDownShiplengthFrom_ValueChanged" Value="{Binding Path=ShipLengthFrom}" />
<Label Grid.Column="1" Content="{x:Static p:Resources.textTo}" />
<xctk:DoubleUpDown x:Name="upDownShiplengthTo" Grid.Column="2" Margin="2" Minimum="0" Maximum="1000"/>
<xctk:DoubleUpDown x:Name="upDownShiplengthTo" Grid.Column="2" Margin="2" Minimum="0" Maximum="1000" ValueChanged="upDownShiplengthTo_ValueChanged" Value="{Binding Path=ShipLengthTo}"/>
</Grid>
<xctk:WatermarkTextBox x:Name="textBoxSearch" Grid.Column="2" Grid.Row="1" Margin="2" Watermark="{x:Static p:Resources.textEnterKeyword}" />
<xctk:CheckComboBox x:Name="comboBoxBerths" DisplayMemberPath="Name" Grid.Column="4" Grid.Row="1" Margin="2" />
<xctk:CheckComboBox x:Name="comboBoxAgencies" DisplayMemberPath="Name" Grid.Column="6" Grid.Row="1" Margin="2" />
<xctk:WatermarkTextBox x:Name="textBoxSearch" Grid.Column="2" Grid.Row="1" Margin="2" Watermark="{x:Static p:Resources.textEnterKeyword}" PreviewTextInput="textBoxSearch_PreviewTextInput" DataObject.Pasting="textBoxSearch_Pasting" TextChanged="textBoxSearch_TextChanged" />
<xctk:CheckComboBox x:Name="comboBoxBerths" DisplayMemberPath="Name" Grid.Column="4" Grid.Row="1" Margin="2" ItemSelectionChanged="comboBoxBerths_ItemSelectionChanged" />
<xctk:CheckComboBox x:Name="comboBoxAgencies" DisplayMemberPath="Name" Grid.Column="6" Grid.Row="1" Margin="2" ItemSelectionChanged="comboBoxAgencies_ItemSelectionChanged" />
</Grid>
</UserControl>

View File

@ -16,23 +16,41 @@ namespace BreCalClient
public partial class SearchFilterControl : UserControl
{
#region private fields
private SearchFilterModel _model = new();
#endregion
#region Construction
public SearchFilterControl()
{
InitializeComponent();
this.DataContext = this._model;
}
#endregion
#region events
/// <summary>
/// historically we love a clickable logo and see what will happen
/// </summary>
public event Action? LogoImageClicked;
/// <summary>
/// if the user somewhat changes the filters trigger this
/// </summary>
internal event Action? SearchFilterChanged;
#endregion
#region Properties
public string FilterAsJson { get; set; } = "";
internal SearchFilterModel SearchFilter { get { return _model; } }
#endregion
@ -48,6 +66,53 @@ namespace BreCalClient
this.comboBoxAgencies.ItemsSource = agencies;
}
public void ClearFilters()
{
this._model = new SearchFilterModel();
this.comboBoxAgencies.UnSelectAll();
this.comboBoxBerths.UnSelectAll();
this.comboBoxCategories.UnSelectAll();
this.datePickerETAFrom.SelectedDate = null;
this.datePickerETATo.SelectedDate = null;
this.textBoxSearch.Clear();
this.upDownShiplengthFrom.Value = null;
this.upDownShiplengthTo.Value = null;
}
internal void SetFilterFromModel(SearchFilterModel sfm)
{
this.ClearFilters();
if(sfm.Berths != null)
{
foreach(Berth berth in this.comboBoxBerths.ItemsSource)
{
if (sfm.Berths.Contains(berth.Id)) this.comboBoxBerths.SelectedItems.Add(berth);
}
}
if(sfm.Agencies != null)
{
foreach(Participant p in this.comboBoxAgencies.ItemsSource)
{
if(sfm.Agencies.Contains(p.Id)) this.comboBoxAgencies.SelectedItems.Add(p);
}
}
if(sfm.Categories != null)
{
foreach(int category in sfm.Categories)
this.comboBoxCategories.SelectedItems.Add((Extensions.TypeEnum)category);
}
if (sfm.SearchString != null) this.textBoxSearch.Text = sfm.SearchString;
this.upDownShiplengthFrom.Value = sfm.ShipLengthFrom;
this.upDownShiplengthTo.Value = sfm.ShipLengthTo;
this.datePickerETAFrom.SelectedDate = sfm.EtaFrom;
this.datePickerETATo.SelectedDate = sfm.EtaTo;
this._model = sfm;
SearchFilterChanged?.Invoke();
}
#endregion
#region event handler
@ -62,6 +127,73 @@ namespace BreCalClient
this.comboBoxCategories.ItemsSource = Enum.GetValues(typeof(Extensions.TypeEnum));
}
private void datePickerETAFrom_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
{
this._model.EtaFrom = this.datePickerETAFrom.SelectedDate;
SearchFilterChanged?.Invoke();
}
private void datePickerETATo_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
{
this._model.EtaTo = datePickerETATo.SelectedDate;
SearchFilterChanged?.Invoke();
}
private void comboBoxCategories_ItemSelectionChanged(object sender, Xceed.Wpf.Toolkit.Primitives.ItemSelectionChangedEventArgs e)
{
_model.Categories.Clear();
foreach(int category in comboBoxCategories.SelectedItems)
_model.Categories.Add(category);
SearchFilterChanged?.Invoke();
}
private void upDownShiplengthFrom_ValueChanged(object sender, System.Windows.RoutedPropertyChangedEventArgs<object> e)
{
this._model.ShipLengthFrom = this.upDownShiplengthFrom.Value;
SearchFilterChanged?.Invoke();
}
private void upDownShiplengthTo_ValueChanged(object sender, System.Windows.RoutedPropertyChangedEventArgs<object> e)
{
this._model.ShipLengthTo = this.upDownShiplengthTo.Value;
SearchFilterChanged?.Invoke();
}
private void comboBoxBerths_ItemSelectionChanged(object sender, Xceed.Wpf.Toolkit.Primitives.ItemSelectionChangedEventArgs e)
{
_model.Berths.Clear();
foreach(Berth berth in comboBoxBerths.SelectedItems)
_model.Berths.Add(berth.Id);
SearchFilterChanged?.Invoke();
}
private void comboBoxAgencies_ItemSelectionChanged(object sender, Xceed.Wpf.Toolkit.Primitives.ItemSelectionChangedEventArgs e)
{
_model.Agencies.Clear();
foreach (Participant agency in comboBoxAgencies.SelectedItems)
_model.Agencies.Add(agency.Id);
SearchFilterChanged?.Invoke();
}
private void textBoxSearch_Pasting(object sender, System.Windows.DataObjectPastingEventArgs e)
{
this.SearchFilter.SearchString = e.SourceDataObject.ToString();
SearchFilterChanged?.Invoke();
}
private void textBoxSearch_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
this.SearchFilter.SearchString = this.textBoxSearch.Text + e.Text;
SearchFilterChanged?.Invoke();
}
private void textBoxSearch_TextChanged(object sender, TextChangedEventArgs e)
{
this.SearchFilter.SearchString = this.textBoxSearch.Text;
SearchFilterChanged?.Invoke();
}
#endregion
}

View File

@ -5,6 +5,7 @@
using BreCalClient.misc.Model;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace BreCalClient
{
@ -18,11 +19,11 @@ namespace BreCalClient
public DateTime? EtaTo { get; set; }
public IEnumerable<int>? Categories { get; set; }
public List<int> Categories { get; set; } = new();
public IEnumerable<Participant>? Agencies { get; set; }
public List<int> Agencies { get; set; } = new();
public IEnumerable<Berth>? Berths { get; set; }
public List<int> Berths { get; set; } = new();
public string? SearchString { get; set; }
@ -32,5 +33,15 @@ namespace BreCalClient
#endregion
public static SearchFilterModel? Deserialize(string json)
{
return (SearchFilterModel?) JsonConvert.DeserializeObject(json, typeof(SearchFilterModel));
}
public string Serialize()
{
return JsonConvert.SerializeObject(this, Formatting.Indented);
}
}
}

View File

@ -5,6 +5,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:BreCalClient"
xmlns:p = "clr-namespace:BreCalClient.Resources"
xmlns:sets="clr-namespace:BreCalClient.Properties"
xmlns:db="clr-namespace:BreCalClient;assembly=BreCalClient"
xmlns:db2="clr-namespace:BreCalClient.misc.Model;assembly=BreCalClient"
mc:Ignorable="d"
@ -46,7 +47,7 @@
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Margin="2" Grid.Column="0" PreviewMouseUp="Image_PreviewMouseUp" x:Name="imageShipcallType" />
<Label Grid.Column="1" FontSize="12" x:Name="labelShipName" Foreground="White" Background="#203864" VerticalAlignment="Stretch"
<Label Grid.Column="1" FontSize="12" x:Name="labelShipName" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" PreviewMouseUp="Image_PreviewMouseUp"/>
</Grid>
<Viewbox Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left">
@ -88,17 +89,17 @@
</Grid>
<Label Grid.Row="0" Grid.Column="1" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="#203864" VerticalAlignment="Stretch"
<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"
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="#203864" VerticalAlignment="Stretch"
<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"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelMooring" PreviewMouseUp="labelMooring_PreviewMouseUp"/>
<Label Grid.Row="0" Grid.Column="3" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="#203864" VerticalAlignment="Stretch"
<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"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelPortAuthority" PreviewMouseUp="labelPortAuthority_PreviewMouseUp" />
<Label Grid.Row="0" Grid.Column="4" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="#203864" VerticalAlignment="Stretch"
<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"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelPilot" PreviewMouseUp="labelPilot_PreviewMouseUp"/>
<Label Grid.Row="0" Grid.Column="5" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="#203864" VerticalAlignment="Stretch"
<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"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelTug" PreviewMouseUp="labelTug_PreviewMouseUp"/>
<Label Grid.Row="0" Grid.Column="6" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="#203864" 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="labelTerminal" PreviewMouseUp="labelTerminal_PreviewMouseUp" />
<Grid Grid.Row="2" Grid.Column="1">
@ -117,6 +118,7 @@
<Label Grid.Row="1" Grid.Column="0" Content="ETA" Padding="0" VerticalContentAlignment="Center" />
<Label Grid.Row="2" Grid.Column="0" Content="ETD" Padding="0" VerticalContentAlignment="Center" />
<Label Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" Content="{x:Static p:Resources.textRemarks}" Padding="0" VerticalContentAlignment="Center" FontSize="9"/>
<Label Grid.Row="0" Grid.Column="1" HorizontalContentAlignment="Left" x:Name="labelAgencyBerth" Padding="0" VerticalContentAlignment="Center" FontSize="9" />
<Label Grid.Row="1" Grid.Column="1" Padding="0" VerticalContentAlignment="Center" x:Name="labelAgencyETA" FontWeight="DemiBold"/>
<Label Grid.Row="2" Grid.Column="1" Padding="0" VerticalContentAlignment="Center" x:Name="labelAgencyETD" FontWeight="DemiBold"/>
<TextBlock Grid.Row="3" Grid.Column="1" Grid.RowSpan="2" Padding="0" TextWrapping="Wrap" VerticalAlignment="Top" x:Name="textBlockAgencyRemarks" />
@ -138,6 +140,7 @@
<Label Grid.Row="1" Grid.Column="0" Content="ETA" Padding="0" VerticalContentAlignment="Center" />
<Label Grid.Row="2" Grid.Column="0" Content="ETD" Padding="0" VerticalContentAlignment="Center" />
<Label Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" Content="{x:Static p:Resources.textRemarks}" Padding="0" VerticalContentAlignment="Center" FontSize="9"/>
<Label Grid.Row="0" Grid.Column="1" HorizontalContentAlignment="Left" x:Name="labelMooringBerth" Padding="0" VerticalContentAlignment="Center" FontSize="9" />
<Label Grid.Row="1" Grid.Column="1" Padding="0" VerticalContentAlignment="Center" x:Name="labelMooringETA" FontWeight="DemiBold"/>
<Label Grid.Row="2" Grid.Column="1" Padding="0" VerticalContentAlignment="Center" x:Name="labelMooringETD" FontWeight="DemiBold"/>
<TextBlock Grid.Row="3" Grid.Column="1" Grid.RowSpan="2" Padding="0" TextWrapping="Wrap" VerticalAlignment="Top" x:Name="textBlockMooringRemarks"/>
@ -158,6 +161,7 @@
<Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Content="{x:Static p:Resources.textBerth}" Padding="0" VerticalContentAlignment="Center" FontSize="9"/>
<Label Grid.Row="1" Grid.Column="0" Content="ETA" Padding="0" VerticalContentAlignment="Center" />
<Label Grid.Row="2" Grid.Column="0" Content="ETD" Padding="0" VerticalContentAlignment="Center" />
<Label Grid.Row="0" Grid.Column="1" HorizontalContentAlignment="Left" x:Name="labelPortAuthorityBerth" Padding="0" VerticalContentAlignment="Center" FontSize="9" />
<Label Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" Content="{x:Static p:Resources.textRemarks}" Padding="0" VerticalContentAlignment="Center" FontSize="9"/>
<Label Grid.Row="1" Grid.Column="1" Padding="0" VerticalContentAlignment="Center" x:Name="labelPortAuthorityETA" FontWeight="DemiBold"/>
<Label Grid.Row="2" Grid.Column="1" Padding="0" VerticalContentAlignment="Center" x:Name="labelPortAuthorityETD" FontWeight="DemiBold"/>
@ -179,6 +183,7 @@
<Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Content="{x:Static p:Resources.textBerth}" Padding="0" VerticalContentAlignment="Center" FontSize="9"/>
<Label Grid.Row="1" Grid.Column="0" Content="ETA" Padding="0" VerticalContentAlignment="Center" />
<Label Grid.Row="2" Grid.Column="0" Content="ETD" Padding="0" VerticalContentAlignment="Center" />
<Label Grid.Row="0" Grid.Column="1" HorizontalContentAlignment="Left" x:Name="labelPilotBerth" Padding="0" VerticalContentAlignment="Center" FontSize="9" />
<Label Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" Content="{x:Static p:Resources.textRemarks}" Padding="0" VerticalContentAlignment="Center" FontSize="9"/>
<Label Grid.Row="1" Grid.Column="1" Padding="0" VerticalContentAlignment="Center" x:Name="labelPilotETA" FontWeight="DemiBold"/>
<Label Grid.Row="2" Grid.Column="1" Padding="0" VerticalContentAlignment="Center" x:Name="labelPilotETD" FontWeight="DemiBold"/>
@ -200,6 +205,7 @@
<Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Content="{x:Static p:Resources.textBerth}" Padding="0" VerticalContentAlignment="Center" FontSize="9"/>
<Label Grid.Row="1" Grid.Column="0" Content="ETA" Padding="0" VerticalContentAlignment="Center" />
<Label Grid.Row="2" Grid.Column="0" Content="ETD" Padding="0" VerticalContentAlignment="Center" />
<Label Grid.Row="0" Grid.Column="1" HorizontalContentAlignment="Left" x:Name="labelTugBerth" Padding="0" VerticalContentAlignment="Center" FontSize="9" />
<Label Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" Content="{x:Static p:Resources.textRemarks}" Padding="0" VerticalContentAlignment="Center" FontSize="9"/>
<Label Grid.Row="1" Grid.Column="1" Padding="0" VerticalContentAlignment="Center" x:Name="labelTugETA" FontWeight="DemiBold"/>
<Label Grid.Row="2" Grid.Column="1" Padding="0" VerticalContentAlignment="Center" x:Name="labelTugETD" FontWeight="DemiBold"/>
@ -218,12 +224,13 @@
<RowDefinition Height="14" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Content="{x:Static p:Resources.textBerth}" Padding="0" VerticalContentAlignment="Center" FontSize="9"/>
<Label Grid.Row="1" Grid.Column="0" Content="ETA" Padding="0" VerticalContentAlignment="Center" />
<Label Grid.Row="2" Grid.Column="0" Content="ETD" Padding="0" VerticalContentAlignment="Center" />
<Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Padding="0" VerticalContentAlignment="Center" FontSize="9"/>
<Label Grid.Row="1" Grid.Column="0" Content="Start" Padding="0" VerticalContentAlignment="Center" />
<Label Grid.Row="2" Grid.Column="0" Content="End" Padding="0" VerticalContentAlignment="Center" />
<Label Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" Content="{x:Static p:Resources.textRemarks}" Padding="0" VerticalContentAlignment="Center" FontSize="9"/>
<Label Grid.Row="1" Grid.Column="1" Padding="0" VerticalContentAlignment="Center" x:Name="labelTerminalETA" FontWeight="DemiBold"/>
<Label Grid.Row="2" Grid.Column="1" Padding="0" VerticalContentAlignment="Center" x:Name="labelTerminalETD" FontWeight="DemiBold"/>
<Label Grid.Row="0" Grid.Column="1" HorizontalContentAlignment="Left" x:Name="labelTerminalBerth" Padding="0" VerticalContentAlignment="Center" FontSize="9" />
<Label Grid.Row="1" Grid.Column="1" Padding="0" VerticalContentAlignment="Center" x:Name="labelOperationsStart" FontWeight="DemiBold"/>
<Label Grid.Row="2" Grid.Column="1" Padding="0" VerticalContentAlignment="Center" x:Name="labelOperationsEnd" FontWeight="DemiBold"/>
<TextBlock Grid.Row="3" Grid.Column="1" Grid.RowSpan="2" Padding="0" TextWrapping="Wrap" VerticalAlignment="Top" x:Name="textBlockTerminalRemarks" />
</Grid>

View File

@ -4,12 +4,12 @@
using BreCalClient.misc.Model;
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace BreCalClient
{
/// <summary>
@ -17,6 +17,16 @@ namespace BreCalClient
/// </summary>
public partial class ShipcallControl : UserControl
{
#region Fields
Participant? _agency;
Participant? _pilot;
Participant? _mooring;
Participant? _terminal;
Participant? _tug;
Participant? _port_administration;
#endregion
#region Construction
@ -31,9 +41,9 @@ namespace BreCalClient
public event Action<ShipcallControl>? EditRequested;
public event Action<ShipcallControl, Times?>? EditTimesRequested;
public event Action<ShipcallControl, Times?>? EditAgencyRequested;
public event Action<ShipcallControl>? OpenExtraRequested;
internal event Action<ShipcallControl, Times?, Extensions.ParticipantType>? EditTimesRequested;
#endregion
@ -44,11 +54,6 @@ namespace BreCalClient
/// </summary>
public ShipcallControlModel? ShipcallControlModel { get; set; }
/// <summary>
/// these are all participants (currently loaded)
/// </summary>
public Dictionary<int, Participant>? ParticipantDict { get; set; }
#endregion
#region public methods
@ -58,74 +63,90 @@ namespace BreCalClient
if (this.ShipcallControlModel == null) return;
string agentName = "";
string? name;
name = this.ShipcallControlModel.GetParticipantNameForType(Extensions.ParticipantType.AGENCY);
if (name != null)
{
this.labelAgent.Content = name;
agentName = name;
}
name = this.ShipcallControlModel.GetParticipantNameForType(Extensions.ParticipantType.MOORING);
if (name != null)
this.labelMooring.Content = name;
name = this.ShipcallControlModel.GetParticipantNameForType(Extensions.ParticipantType.PILOT);
if (name != null)
this.labelPilot.Content = name;
name = this.ShipcallControlModel.GetParticipantNameForType(Extensions.ParticipantType.TUG);
if (name != null)
this.labelTug.Content = name;
name = this.ShipcallControlModel.GetParticipantNameForType(Extensions.ParticipantType.PORT_ADMINISTRATION);
if (name != null)
this.labelPortAuthority.Content = name;
name = this.ShipcallControlModel.GetParticipantNameForType(Extensions.ParticipantType.TERMINAL);
if (name != null)
this.labelTerminal.Content = name;
_agency = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.AGENCY);
name = _agency?.Name;
if (name != null) agentName = name;
this.labelAgent.Content = name ?? "- / -";
if(App.Participant.IsFlagSet(Extensions.ParticipantType.TERMINAL)) {
_mooring = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.MOORING);
name = _mooring?.Name;
this.labelMooring.Content = name ?? "- / -";
_pilot = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.PILOT);
name = _pilot?.Name;
this.labelPilot.Content = name ?? "- / - ";
_tug = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.TUG);
name = _tug?.Name;
this.labelTug.Content = name ?? "- / - ";
_port_administration = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.PORT_ADMINISTRATION);
name = _port_administration?.Name;
this.labelPortAuthority.Content = name ?? "- / - ";
_terminal = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.TERMINAL);
name = _terminal?.Name;
this.labelTerminal.Content = name ?? "- / - ";
if(App.Participant.IsTypeFlagSet(Extensions.ParticipantType.TERMINAL) && (App.Participant.Id == _terminal?.Id))
{
this.labelTerminal.FontWeight = FontWeights.Bold;
this.labelTerminal.Foreground = Brushes.LightYellow;
}
if(App.Participant.IsFlagSet(Extensions.ParticipantType.PILOT))
if(App.Participant.IsTypeFlagSet(Extensions.ParticipantType.PILOT) && (App.Participant.Id == _pilot?.Id))
{
this.labelPilot.FontWeight = FontWeights.Bold;
this.labelPilot.Foreground = Brushes.LightYellow;
}
if(App.Participant.IsFlagSet(Extensions.ParticipantType.AGENCY))
if((App.Participant.IsTypeFlagSet(Extensions.ParticipantType.AGENCY) && (App.Participant.Id == _agency?.Id)) ||
(App.Participant.IsTypeFlagSet(Extensions.ParticipantType.BSMD) && (_agency != null) && _agency.IsFlagSet(Extensions.ParticipantFlag.ALLOW_BSMD)))
{
this.labelAgent.FontWeight = FontWeights.Bold;
this.labelAgent.Foreground = Brushes.LightYellow;
}
if(App.Participant.IsFlagSet(Extensions.ParticipantType.MOORING))
if(App.Participant.IsTypeFlagSet(Extensions.ParticipantType.MOORING) && (App.Participant.Id == _mooring?.Id))
{
this.labelMooring.FontWeight = FontWeights.Bold;
this.labelMooring.Foreground = Brushes.LightYellow;
}
if(App.Participant.IsFlagSet(Extensions.ParticipantType.PORT_ADMINISTRATION))
if(App.Participant.IsTypeFlagSet(Extensions.ParticipantType.PORT_ADMINISTRATION) && (App.Participant.Id == _port_administration?.Id))
{
this.labelPortAuthority.FontWeight = FontWeights.Bold;
this.labelPortAuthority.Foreground = Brushes.LightYellow;
}
if (App.Participant.IsFlagSet(Extensions.ParticipantType.TUG))
if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.TUG) && (App.Participant.Id == _tug?.Id))
{
this.labelTug.FontWeight = FontWeights.Bold;
this.labelTug.Foreground = Brushes.LightYellow;
}
if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.BSMD))
{
this.labelShipName.FontWeight = FontWeights.Bold;
this.labelShipName.Foreground = Brushes.LightYellow;
}
this.labelShipName.Content = this.ShipcallControlModel?.Ship?.Name;
switch(this.ShipcallControlModel?.Shipcall?.Type)
{
case 1: // incoming
this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalClient;component/Resources/arrow_down_red.png"));
this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalTestClient;component/Resources/arrow_down_red.png"));
break;
case 2: // outgoing
this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalClient;component/Resources/arrow_up_green.png"));
this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalTestClient;component/Resources/arrow_up_blue.png"));
break;
case 3: // shifting
this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalClient;component/Resources/arrow_right_blue.png"));
this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalTestClient;component/Resources/arrow_right_green.png"));
break;
default:
break;
}
this.textBlockAgency.Text = this.ShipcallControlModel?.Agency;
this.textBlockBerth.Text = this.ShipcallControlModel?.Berth;
this.textBlockCallsign.Text = this.ShipcallControlModel?.Ship?.Callsign;
if ((this.ShipcallControlModel?.Shipcall?.Type == 1) || (this.ShipcallControlModel?.Shipcall?.Type == 3))
@ -142,51 +163,72 @@ namespace BreCalClient
this.textBlockLengthWidth.Text = $"{this.ShipcallControlModel?.Ship?.Length} / {this.ShipcallControlModel?.Ship?.Width}";
this.textBlockAgency.Text = agentName.TruncateDots(10);
if (this.ParticipantDict != null)
if (this.ShipcallControlModel != null)
{
if (this.ShipcallControlModel != null)
foreach (Times times in this.ShipcallControlModel.Times)
{
foreach (Times times in this.ShipcallControlModel.Times)
string? berthText = null;
if ((BreCalLists.Berths != null) && times.BerthId.HasValue)
{
if(this.ParticipantDict.ContainsKey(times.ParticipantId))
Berth? berth = BreCalLists.Berths.Find((x) => x.Id == times.BerthId);
berthText = berth?.Name;
}
if(berthText == null)
{
if (this.ShipcallControlModel.Shipcall?.Type == (int) Extensions.TypeEnum.Outgoing)
{
if (this.ParticipantDict[times.ParticipantId].IsFlagSet(Extensions.ParticipantType.AGENCY))
{
this.labelAgencyETA.Content = times.EtaBerth.HasValue ? times.EtaBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -";
this.labelAgencyETD.Content = times.EtdBerth.HasValue ? times.EtdBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -";
this.textBlockAgency.Text = times.Remarks;
}
if (this.ParticipantDict[times.ParticipantId].IsFlagSet(Extensions.ParticipantType.MOORING))
{
this.labelMooringETA.Content = times.EtaBerth.HasValue ? times.EtaBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -";
this.labelMooringETD.Content = times.EtdBerth.HasValue ? times.EtdBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -";
this.textBlockMooringRemarks.Text = times.Remarks;
}
if (this.ParticipantDict[times.ParticipantId].IsFlagSet(Extensions.ParticipantType.PORT_ADMINISTRATION))
{
this.labelPortAuthorityETA.Content = times.EtaBerth.HasValue ? times.EtaBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -";
this.labelPortAuthorityETD.Content = times.EtdBerth.HasValue ? times.EtdBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -";
this.textBlockPortAuthorityRemarks.Text = times.Remarks;
}
if (this.ParticipantDict[times.ParticipantId].IsFlagSet(Extensions.ParticipantType.PILOT))
{
this.labelPilotETA.Content = times.EtaBerth.HasValue ? times.EtaBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -";
this.labelPilotETD.Content = times.EtdBerth.HasValue ? times.EtdBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -";
this.textBlockPilotRemarks.Text = times.Remarks;
}
if (this.ParticipantDict[times.ParticipantId].IsFlagSet(Extensions.ParticipantType.TUG))
{
this.labelTugETA.Content = times.EtaBerth.HasValue ? times.EtaBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -";
this.labelTugETD.Content = times.EtdBerth.HasValue ? times.EtdBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -";
this.textBlockTugRemarks.Text = times.Remarks;
}
if (this.ParticipantDict[times.ParticipantId].IsFlagSet(Extensions.ParticipantType.TERMINAL))
{
this.labelTerminalETA.Content = times.EtaBerth.HasValue ? times.EtaBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -";
this.labelTerminalETD.Content = times.EtdBerth.HasValue ? times.EtdBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -";
this.textBlockTerminalRemarks.Text = times.Remarks;
}
Berth? berth = BreCalLists.Berths?.Find((x) => x.Id == this.ShipcallControlModel.Shipcall?.DepartureBerthId);
berthText = berth?.Name;
}
else
{
Berth? berth = BreCalLists.Berths?.Find((x) => x.Id == this.ShipcallControlModel.Shipcall?.ArrivalBerthId);
berthText = berth?.Name;
}
}
if (times.ParticipantType == (int)Extensions.ParticipantType.AGENCY)
{
this.labelAgencyBerth.Content = berthText;
this.labelAgencyETA.Content = times.EtaBerth.HasValue ? times.EtaBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -";
this.labelAgencyETD.Content = times.EtdBerth.HasValue ? times.EtdBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -";
this.textBlockAgencyRemarks.Text = times.Remarks;
}
if (times.ParticipantType == (int) Extensions.ParticipantType.MOORING)
{
this.labelMooringBerth.Content = berthText;
this.labelMooringETA.Content = times.EtaBerth.HasValue ? times.EtaBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -";
this.labelMooringETD.Content = times.EtdBerth.HasValue ? times.EtdBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -";
this.textBlockMooringRemarks.Text = times.Remarks;
}
if (times.ParticipantType == (int)Extensions.ParticipantType.PORT_ADMINISTRATION)
{
this.labelPortAuthorityBerth.Content = berthText;
this.labelPortAuthorityETA.Content = times.EtaBerth.HasValue ? times.EtaBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -";
this.labelPortAuthorityETD.Content = times.EtdBerth.HasValue ? times.EtdBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -";
this.textBlockPortAuthorityRemarks.Text = times.Remarks;
}
if (times.ParticipantType == (int)Extensions.ParticipantType.PILOT)
{
this.labelPilotBerth.Content = berthText;
this.labelPilotETA.Content = times.EtaBerth.HasValue ? times.EtaBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -";
this.labelPilotETD.Content = times.EtdBerth.HasValue ? times.EtdBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -";
this.textBlockPilotRemarks.Text = times.Remarks;
}
if (times.ParticipantType == (int)Extensions.ParticipantType.TUG)
{
this.labelTugBerth.Content = berthText;
this.labelTugETA.Content = times.EtaBerth.HasValue ? times.EtaBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -";
this.labelTugETD.Content = times.EtdBerth.HasValue ? times.EtdBerth.Value.ToString("dd.MM.yyyy HH:mm") : "- / -";
this.textBlockTugRemarks.Text = times.Remarks;
}
if (times.ParticipantType == (int)Extensions.ParticipantType.TERMINAL)
{
this.labelTerminalBerth.Content = berthText;
this.labelOperationsStart.Content = times.OperationsStart.HasValue ? times.OperationsStart.Value.ToString("dd.MM.yyyy HH:mm") : "- / -";
this.labelOperationsEnd.Content = times.OperationsEnd.HasValue ? times.OperationsEnd.Value.ToString("dd.MM.yyyy HH:mm") : "- / -";
this.textBlockTerminalRemarks.Text = times.Remarks;
}
}
}
@ -201,72 +243,69 @@ namespace BreCalClient
}
private void buttonEditShipcall_Click(object sender, RoutedEventArgs e)
private void buttonEditShipcall_Click(object? sender, RoutedEventArgs? e)
{
if(App.Participant.IsTypeFlagSet(Extensions.ParticipantType.BSMD))
this.EditRequested?.Invoke(this);
}
private void buttonOpenDropDown_Click(object sender, RoutedEventArgs e)
{
this.OpenExtraRequested?.Invoke(this);
}
private void Image_PreviewMouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
this.EditRequested?.Invoke(this);
this.buttonEditShipcall_Click(null, null);
}
private void labelAgent_PreviewMouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (App.Participant.IsFlagSet(Extensions.ParticipantType.AGENCY))
if ((App.Participant.IsTypeFlagSet(Extensions.ParticipantType.AGENCY) && (App.Participant.Id == _agency?.Id)) ||
(App.Participant.IsTypeFlagSet(Extensions.ParticipantType.BSMD) && (_agency != null) && _agency.IsFlagSet(Extensions.ParticipantFlag.ALLOW_BSMD)))
{
Times? times = this.ShipcallControlModel?.GetTimesForParticipantType(Extensions.ParticipantType.AGENCY);
this.EditTimesRequested?.Invoke(this, times);
this.EditAgencyRequested?.Invoke(this, times);
}
}
private void labelMooring_PreviewMouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (App.Participant.IsFlagSet(Extensions.ParticipantType.MOORING))
if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.MOORING) && (App.Participant.Id == _mooring?.Id))
{
Times? times = this.ShipcallControlModel?.GetTimesForParticipantType(Extensions.ParticipantType.MOORING);
this.EditTimesRequested?.Invoke(this, times);
this.EditTimesRequested?.Invoke(this, times, Extensions.ParticipantType.MOORING);
}
}
private void labelPortAuthority_PreviewMouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (App.Participant.IsFlagSet(Extensions.ParticipantType.PORT_ADMINISTRATION))
if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.PORT_ADMINISTRATION) && (App.Participant.Id == _port_administration?.Id))
{
Times? times = this.ShipcallControlModel?.GetTimesForParticipantType(Extensions.ParticipantType.PORT_ADMINISTRATION);
this.EditTimesRequested?.Invoke(this, times);
this.EditTimesRequested?.Invoke(this, times, Extensions.ParticipantType.PORT_ADMINISTRATION);
}
}
private void labelPilot_PreviewMouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (App.Participant.IsFlagSet(Extensions.ParticipantType.PILOT))
if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.PILOT) && (App.Participant.Id == _pilot?.Id))
{
Times? times = this.ShipcallControlModel?.GetTimesForParticipantType(Extensions.ParticipantType.PILOT);
this.EditTimesRequested?.Invoke(this, times);
this.EditTimesRequested?.Invoke(this, times, Extensions.ParticipantType.PILOT);
}
}
private void labelTug_PreviewMouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (App.Participant.IsFlagSet(Extensions.ParticipantType.TUG))
if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.TUG) && (App.Participant.Id == _tug?.Id))
{
Times? times = this.ShipcallControlModel?.GetTimesForParticipantType(Extensions.ParticipantType.TUG);
this.EditTimesRequested?.Invoke(this, times);
this.EditTimesRequested?.Invoke(this, times, Extensions.ParticipantType.TUG);
}
}
private void labelTerminal_PreviewMouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (App.Participant.IsFlagSet(Extensions.ParticipantType.TERMINAL))
if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.TERMINAL) && (App.Participant.Id == _terminal?.Id))
{
Times? times = this.ShipcallControlModel?.GetTimesForParticipantType(Extensions.ParticipantType.TERMINAL);
this.EditTimesRequested?.Invoke(this, times);
this.EditTimesRequested?.Invoke(this, times, Extensions.ParticipantType.TERMINAL);
}
}

View File

@ -42,13 +42,12 @@ namespace BreCalClient
#region Properties
public Shipcall? Shipcall { get; set; }
public Ship? Ship { get; set; }
public string? Agency { get; set; }
public Ship? Ship { get; set; }
public string? Berth { get; set; }
public Dictionary<int, Participant> AssignedParticipants { get; } = new();
internal Dictionary<Extensions.ParticipantType, Participant> AssignedParticipants { get; } = new();
public List<Times> Times { get; set; } = new();
@ -87,10 +86,14 @@ namespace BreCalClient
{
foreach (int participantId in Shipcall.Participants)
{
foreach(Participant participant in participants)
Participant? participant = participants.Find((x) => x.Id == participantId);
if (participant != null)
{
if(participant.Id == participantId)
AssignedParticipants[participant.Type] = participant;
foreach(Extensions.ParticipantType participantType in Enum.GetValues(typeof(Extensions.ParticipantType)))
{
if(participant.IsTypeFlagSet(participantType))
AssignedParticipants[participantType] = participant;
}
}
}
}
@ -99,27 +102,53 @@ namespace BreCalClient
internal Times? GetTimesForParticipantType(Extensions.ParticipantType type)
{
if (AssignedParticipants.ContainsKey((int)type)) {
int participantId = AssignedParticipants[(int)type].Id;
if (AssignedParticipants.ContainsKey(type)) {
int participantId = AssignedParticipants[type].Id;
foreach (Times times in this.Times)
{
if (times.ParticipantId == participantId)
if ((times.ParticipantId == participantId) && (times.ParticipantType == (int) type))
return times;
}
if(type == Extensions.ParticipantType.AGENCY)
{
// if I am BSMD and no agency entry was found this means we are editing the agency entry
if(App.Participant.Type == (int) Extensions.ParticipantType.BSMD)
{
foreach(Times times in this.Times)
{
if ((times.ParticipantId == App.Participant.Id) && (times.ParticipantType == (int) Extensions.ParticipantType.AGENCY))
return times;
}
}
}
}
return null;
}
public bool ContainsRemarkText(string text)
{
if(Shipcall != null)
{
foreach(Times times in this.Times)
{
if (times.Remarks == null) continue;
if(times.Remarks.Contains(text)) return true;
}
}
return false;
}
#endregion
#region helper
internal string? GetParticipantNameForType(Extensions.ParticipantType participantType)
internal Participant? GetParticipantForType(Extensions.ParticipantType participantType)
{
foreach(Participant p in AssignedParticipants.Values)
{
if (p.IsFlagSet(participantType))
return p.Name;
if (p.IsTypeFlagSet(participantType))
return p;
}
return null;
}

View File

@ -1,3 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="RoleEditor.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<RoleEditor.Properties.Settings>
<setting name="ConnectionString" serializeAs="String">
<value>Server=localhost;User ID=ds;Password=HalloWach_2323XXL!!;Database=bremen_calling;Port=33306</value>
</setting>
</RoleEditor.Properties.Settings>
</applicationSettings>
</configuration>

View File

@ -69,6 +69,10 @@
<CheckBox x:Name="checkboxParticipantActive" Grid.Row="4" Grid.Column="2" VerticalAlignment="Center" />
<xctk:CheckComboBox x:Name="comboBoxParticipantType" Grid.Row="5" Grid.Column="2" Margin="2" SelectedValue="Key" DisplayMemberPath="Value" />
<TextBox x:Name="textBoxParticipantCreated" Grid.Row="6" IsReadOnly="True" IsEnabled="False" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" />
<StackPanel Orientation="Horizontal" Grid.Row="7" Grid.Column="0">
<CheckBox x:Name="checkBoxParticipantAllowBSMD" VerticalAlignment="Center" />
<Label Content="Allow BSMD entries" />
</StackPanel>
<TextBox x:Name="textBoxParticipantModified" Grid.Row="7" IsReadOnly="True" IsEnabled="False" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" />
<Button x:Name="buttonParticipantSave" Grid.Row="8" Grid.Column="2" Click="buttonParticipantSave_Click" Margin="2">
<DockPanel>

View File

@ -50,10 +50,10 @@ namespace RoleEditor
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
// try database connection
try
{
DBManager.SetConnectionString(Properties.Settings.Default.ConnectionString);
// load all participants
List<Participant> participants = await Participant.LoadAll(_dbManager);
foreach(Participant p in participants)
@ -213,7 +213,7 @@ namespace RoleEditor
p.Street = this.textBoxParticipantStreet.Text.Trim();
p.PostalCode = this.textBoxParticipantPostalCode.Text.Trim();
p.City = this.textBoxParticipantCity.Text.Trim();
p.SetFlag(this.checkBoxParticipantAllowBSMD.IsChecked ?? false, Participant.ParticipantFlags.ALLOW_BSMD);
p.Type = 0;
for(int i = 0; i < this.comboBoxParticipantType?.SelectedItems.Count; i++)
{
@ -222,7 +222,7 @@ namespace RoleEditor
{
KeyValuePair<string, string> kvp = (KeyValuePair<string, string>)v;
Participant.ParticipantType pType = (Participant.ParticipantType)Enum.Parse(typeof(Participant.ParticipantType), kvp.Key);
p.SetFlag(true, pType);
p.SetTypeFlag(true, pType);
}
}
await p.Save(_dbManager);
@ -380,14 +380,16 @@ namespace RoleEditor
// this.checkboxParticipantActive.Checked = (p != null) ? p.
this.textBoxParticipantCreated.Text = (p != null) ? p.Created.ToString() : string.Empty;
this.textBoxParticipantModified.Text = (p != null) ? p.Modified.ToString() : string.Empty;
this.checkBoxParticipantAllowBSMD.IsChecked = (p != null) ? p.IsFlagSet(Participant.ParticipantFlags.ALLOW_BSMD) : null;
this.comboBoxParticipantType.SelectedItems.Clear();
bool hasAgencyType = false;
if (p != null)
{
foreach (Participant.ParticipantType pType in Enum.GetValues(typeof(Participant.ParticipantType)))
{
if (p.IsFlagSet(pType))
if (p.IsTypeFlagSet(pType))
{
if(pType == Participant.ParticipantType.AGENCY) hasAgencyType = true;
foreach (KeyValuePair<string, string> kvp in this.comboBoxParticipantType.Items)
{
if (kvp.Key.Equals(pType.ToString()))
@ -398,6 +400,8 @@ namespace RoleEditor
}
}
}
this.checkBoxParticipantAllowBSMD.IsEnabled = hasAgencyType;
// -> load users for this participant selection
this._users.Clear();
if (p != null)

View File

@ -0,0 +1,36 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace RoleEditor.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.5.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("Server=localhost;User ID=ds;Password=HalloWach_2323XXL!!;Database=bremen_calling;" +
"Port=33306")]
public string ConnectionString {
get {
return ((string)(this["ConnectionString"]));
}
}
}
}

View File

@ -0,0 +1,9 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="RoleEditor.Properties" GeneratedClassName="Settings">
<Profiles />
<Settings>
<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>
</Setting>
</Settings>
</SettingsFile>

43
src/RoleEditor/ReadMe.md Normal file
View File

@ -0,0 +1,43 @@
# Role Editor (Administration tool)
![logo](../../misc/logo_bremen_calling.png)
___
## Purpose
### Users and participants
* Create and administrate participants (companies) in the system
* Create users and assign them to participants
* Create securables
* Create mappings between users and securables (role management)
### Berths
* Create / edit / set mark deleted of berths (Liegeplätze)
* Excel mass import for berths
### Ships
* Create / edit / set mark deleted of ships
* Excel mass import for ships
## Prerequisites
### Installation
### SSH tunnel for database access
The database access works directly for everyone working with the tool. This means no remote access is possible since the server is configured to allow only local clients. Therefore a SSH tunnel must be used that maps the remote database server port to a local port.
[Setup of a ssh tunnel via putty](https://www.heise.de/tipps-tricks/SSH-Tunnel-nutzen-so-geht-s-4320041.html.)
For credentials please contact me directly.
### RoleEditor client
There will be no ClickOnce deployment for the role editor, since it is only intended for internal use by a few individuals.
For each release a ZIP file will be prepared that will be hosted on the site.

View File

@ -60,6 +60,11 @@
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Settings.Designer.cs">
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Update="Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
@ -74,4 +79,11 @@
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Update="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
</Project>

View File

@ -31,6 +31,13 @@ namespace brecal.model
TUG = 64,
}
[Flags]
public enum ParticipantFlags
{
[Description("allow BSMD initial info")]
ALLOW_BSMD = 1,
}
#endregion
#region Properties
@ -166,17 +173,28 @@ namespace brecal.model
#region public type flag funcs
public bool IsFlagSet(ParticipantType flag)
public bool IsTypeFlagSet(ParticipantType flag)
{
return (this.Type & (uint)flag) != 0;
}
public void SetFlag(bool value, ParticipantType flag)
public void SetTypeFlag(bool value, ParticipantType flag)
{
if (value) this.Type |= (uint)flag;
else this.Type &= (uint)~flag;
}
public bool IsFlagSet(ParticipantFlags flag)
{
return (this.Flags & (uint)flag) != 0;
}
public void SetFlag(bool value, ParticipantFlags flag)
{
if (value) this.Flags |= (uint)flag;
else this.Flags &= (uint)~flag;
}
#endregion
}

View File

@ -1,15 +1,19 @@
using brecal.model;
using MySqlConnector;
using System.Data;
using System.Runtime.CompilerServices;
using static brecal.model.IDBManager;
namespace brecal.mysql
{
public class DBManager : IDBManager
{
// TODO: remove this and use external configuration
private static readonly string _connectionString = "Server=localhost;User ID=ds;Password=HalloWach_2323XXL!!;Database=bremen_calling;Port=33306";
private static string _connectionString = "";
public static void SetConnectionString(string connectionString)
{
_connectionString = connectionString;
}
public async Task<List<DbEntity>> Load(QueryFunc prepareAction, LoadFunc<IDataReader> loadAction, params object?[] args)
{

View File

@ -28,7 +28,7 @@ def GetUser(options):
"user_name": data[0].user_name,
"user_phone": data[0].user_phone
}
token = jwt_handler.generate_jwt(payload=result, lifetime=60) # generate token valid 60 mins
token = jwt_handler.generate_jwt(payload=result, lifetime=120) # generate token valid 60 mins
result["token"] = token # add token to user data
return json.dumps(result), 200, {'Content-Type': 'application/json; charset=utf-8'}

View File

@ -19,7 +19,7 @@ def GetShipcalls(options):
commands = pydapper.using(pooledConnection)
data = commands.query("SELECT 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, created, modified FROM shipcall WHERE eta IS NULL OR eta >= DATE(NOW() - INTERVAL 2 DAY) " +
"anchored, moored_lock, canceled, evaluation, evaluation_message, created, modified FROM shipcall WHERE eta IS NULL OR eta >= DATE(NOW() - INTERVAL 2 DAY) " +
"ORDER BY eta", model=model.Shipcall)
for shipcall in data:
participant_query = "SELECT participant_id FROM shipcall_participant_map WHERE shipcall_id=?shipcall_id?";
@ -63,6 +63,10 @@ def PostShipcalls(schemaModel):
continue
if key == "modified":
continue
if key == "evaluation":
continue
if key == "evaluation_message":
continue
if isNotFirst:
query += ","
isNotFirst = True
@ -137,6 +141,10 @@ def PutShipcalls(schemaModel):
continue
if key == "modified":
continue
if key == "evaluation":
continue
if key == "evaluation_message":
continue
if isNotFirst:
query += ", "
isNotFirst = True

View File

@ -19,7 +19,8 @@ def GetTimes(options):
pooledConnection = local_db.getPoolConnection()
commands = pydapper.using(pooledConnection)
data = commands.query("SELECT id, eta_berth, eta_berth_fixed, etd_berth, etd_berth_fixed, lock_time, lock_time_fixed, " +
"zone_entry, zone_entry_fixed, operations_start, operations_end, remarks, shipcall_id, participant_id, created, modified FROM times " +
"zone_entry, zone_entry_fixed, operations_start, operations_end, remarks, shipcall_id, participant_id, " +
"berth_id, berth_info, pier_side, participant_type, created, modified FROM times " +
"WHERE times.shipcall_id = ?scid?", model=model.Times, param={"scid" : options["shipcall_id"]})
pooledConnection.close()
@ -123,10 +124,11 @@ def PutTimes(schemaModel):
pooledConnection.close()
if affected_rows == 1:
return json.dumps({"id" : schemaModel["id"]}), 200, {'Content-Type': 'application/json; charset=utf-8'}
# if affected_rows == 1: # this doesn't work as expected
return json.dumps("no such record"), 404, {'Content-Type': 'application/json; charset=utf-8'}
return json.dumps({"id" : schemaModel["id"]}), 200, {'Content-Type': 'application/json; charset=utf-8'}
# return json.dumps("no such record"), 404, {'Content-Type': 'application/json; charset=utf-8'}
except Exception as ex:
logging.error(ex)

View File

@ -85,11 +85,13 @@ class ShipcallSchema(Schema):
anchored = fields.Bool(Required = False, allow_none=True)
moored_lock = fields.Bool(Required = False, allow_none=True)
canceled = fields.Bool(Required = False, allow_none=True)
validation_state = fields.Str(Required = False, allow_none=True)
validation_state_changed = fields.DateTime(Required = False, allow_none=True)
evaluation = fields.Int(Required = False, allow_none=True)
evaluation_message = fields.Str(Required = False, allow_none=True)
participants = fields.List(fields.Int)
created = fields.DateTime(Required = False, allow_none=True)
modified = fields.DateTime(Required = False, allow_none=True)
validation_state = fields.Str(Required = False, allow_none=True)
validation_state_changed = fields.DateTime(Required = False, allow_none=True)
@dataclass
class Shipcall:
@ -117,10 +119,12 @@ class Shipcall:
anchored: bool
moored_lock: bool
canceled: bool
created: datetime
modified: datetime
validation_state: str
validation_state_changed: datetime
evaluation: int
evaluation_message: str
created: datetime
modified: datetime
participants: List[int] = field(default_factory=list)
class ShipcallId(Schema):
@ -146,7 +150,11 @@ class TimesSchema(Schema):
operations_end = fields.DateTime(Required = False, allow_none=True)
remarks = fields.String(Required = False, allow_none=True)
participant_id = fields.Int(Required = True)
berth_id = fields.Int(Required = False, allow_none = True)
berth_info = fields.String(Required = False, allow_none=True)
pier_side = fields.Bool(Required = False, allow_none = True)
shipcall_id = fields.Int(Required = True)
participant_type = fields.Int(Required = False, allow_none=True)
created = fields.DateTime(Required = False, allow_none=True)
modified = fields.DateTime(Required = False, allow_none=True)
@ -157,11 +165,11 @@ class UserSchema(Schema):
super().__init__(unknown=None)
pass
id = fields.Int(required=True)
first_name = fields.Str(required=False)
last_name = fields.Str(required=False)
user_phone = fields.Str(required=False)
old_password = fields.Str(required=False)
new_password = fields.Str(required=False)
first_name = fields.Str(Required=False, allow_none=True)
last_name = fields.Str(required=False, allow_none=True)
user_phone = fields.Str(required=False, allow_none=True)
old_password = fields.Str(required=False, allow_none=True)
new_password = fields.Str(required=False, allow_none=True)
@dataclass
class Times:
@ -179,6 +187,10 @@ class Times:
operations_end: datetime
remarks: str
participant_id: int
berth_id: int
berth_info: str
pier_side: bool
participant_type: int
shipcall_id: int
created: datetime
modified: datetime