Merge branch 'develop' of github.com:puls200/brecal into feature/removing_pandas_warning

This commit is contained in:
scopesorting 2023-11-04 10:04:07 +01:00
commit 0578efa799
49 changed files with 1084 additions and 405 deletions

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@ info:
servers: servers:
# tutorial: https://idratherbewriting.com/learnapidoc/pubapis_openapi_step3_servers_object.html # tutorial: https://idratherbewriting.com/learnapidoc/pubapis_openapi_step3_servers_object.html
- url: "https://brecaltest.bsmd-emswe.eu/" - url: "https://brecaldevel.bsmd-emswe.eu/"
description: "Test server hosted on vcup" description: "Test server hosted on vcup"
paths: paths:
@ -68,13 +68,13 @@ paths:
/shipcalls: /shipcalls:
get: get:
summary: Gets a list of ship calls summary: Gets a list of ship calls
#parameters: parameters:
# - name: participant_id - name: past_days
# in: query in: query
# required: true required: false
# description: "**Id of participant**. *Example: 2*. Id of participant entity requesting ship calls" description: "number of days in the past to include in the result. *Example: 7*."
# schema: schema:
# type: integer type: integer
responses: responses:
200: 200:
description: ship call list description: ship call list
@ -348,7 +348,7 @@ components:
required: required:
- id - id
- ship_id - ship_id
- type - type
properties: properties:
id: id:
$ref: "#/components/schemas/shipcallId" $ref: "#/components/schemas/shipcallId"
@ -696,6 +696,8 @@ components:
type: string type: string
user_phone: user_phone:
type: string type: string
user_email:
type: string
exp: exp:
type: number type: number
format: float format: float
@ -723,6 +725,9 @@ components:
user_phone: user_phone:
type: string type: string
nullable: true nullable: true
user_email:
type: string
nullable: true
Id: Id:
type: object type: object
description: A unique identifier for an entity description: A unique identifier for an entity

View File

@ -6,6 +6,14 @@ ___
## Client ## Client
Deployment of the productive client:
- create a branch release/pub_<version> from test release branch
- remove all text references to 'test' (changing target url in the process)
- rename application in settings
- change BG_COLOR in settings to #203864
- user deployment publish xml
## Database ## Database
## Backend / Flask app ## Backend / Flask app
@ -14,7 +22,7 @@ In order to not have complicated and error-prone copying manoevers a direct depl
### File structure ### File structure
### Steps ### Installation steps
1) Created a ssh-key for the user that does the installation on the server following the Github [instructions](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent). 1) Created a ssh-key for the user that does the installation on the server following the Github [instructions](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent).
2) Deploy generated key to the Github user account. 2) Deploy generated key to the Github user account.
@ -27,6 +35,8 @@ ssh-add ~/.ssh/od_ed25519
4) Change to deployment folder 4) Change to deployment folder
e.g.
```bash ```bash
cd /var/www/brecal_test cd /var/www/brecal_test
``` ```
@ -43,6 +53,12 @@ git checkout
6) Database credentials are stored outside the web root, we are using /var/www/secure. Here the file ```connection_data.json``` is placed, a different named copy for each instance. 6) Database credentials are stored outside the web root, we are using /var/www/secure. Here the file ```connection_data.json``` is placed, a different named copy for each instance.
### Changing Devel / Test / Prod Environment
Please note that in the "develop" branch the environment and paths are set to the "devel" setting. If a deployment is made (to testing or to the production) the scripts ```copytest.sh``` and ```copyprod.sh``` have to be run. These scripts will change the environment and paths to the respective settings.
There is also a script called ```bump-version.sh``` which can be used to upgrade all version entries in the repository.
### Installing Requirements ### Installing Requirements
Python 3.11 & Pip3.11 installation (linux), virtualenv package Python 3.11 & Pip3.11 installation (linux), virtualenv package

25
misc/bump-version.sh Normal file
View File

@ -0,0 +1,25 @@
#!/bin/bash
CURRENT_VERSION=$(cat version.txt)
NEW_VERSION="${1}"
if [ -z "${NEW_VERSION}" ]; then
echo "No new version given"
exit 1
fi
echo "Bumping version ${CURRENT_VERSION} to ${NEW_VERSION}"
CURRENT_VERSION=$(printf '%s\n' "$CURRENT_VERSION" | sed -e 's/[\/&]/\\&/g')
NEW_VERSION=$(printf '%s\n' "$NEW_VERSION" | sed -e 's/[\/&]/\\&/g')
echo "Found the following matching version strings:"
git grep -I "${CURRENT_VERSION}"
echo "Proceed? [N/y]"
read proceed
if [ "${proceed}" = "y" ]; then
git grep -Il "${CURRENT_VERSION}" | xargs sed --in-place -e "s/${CURRENT_VERSION}/${NEW_VERSION}/g"
git add $(git grep -Il "${NEW_VERSION}")
fi

42
misc/copyprod.sh Normal file
View File

@ -0,0 +1,42 @@
#!/bin/bash
# This script replaces all references to the development version with the test version
# 1) Database references and paths
git grep -I "connection_data_test.json"
git grep -I "/var/www/brecal_test/"
# 2) Color references
# Bar colors in client: (BG_COLOR)
# Devel: #1D751F
# Test: #751D1F
# Prod: #203864
git grep -I "#751D1F"
# 3) Assembly name references
git grep -I "BreCalTestClient"
echo "Proceed? [N/y]"
read proceed
# for color
if [ "${proceed}" = "y" ]; then
# 1. for database references and paths
git grep -I "connection_data_test.json" | xargs sed --in-place -e "s/connection_data_test.json/connection_data_prod.json/g"
git add $(git grep -I "connection_data_prod.json")
git grep -I "/var/www/brecal_test/" | xargs sed --in-place -e "s/\/var\/www\/brecal_test\//\/var\/www\/brecal\//g"
git add $(git grep -I "/var/www/brecal/")
# 2. for color
git grep -Il "#751D1F" | xargs sed --in-place -e "s/#751D1F/#203864/g"
git add $(git grep -Il "#203864")
# 3. for assembly name
git grep -I "BreCalTestClient" | xargs sed --in-place -e "s/BreCalTestClient/BreCalClient/g"
git add $(git grep -I "BreCalClient")
fi

42
misc/copytest.sh Normal file
View File

@ -0,0 +1,42 @@
#!/bin/bash
# This script replaces all references to the development version with the test version
# 1) Database references and paths
git grep -I "connection_data_devel.json"
git grep -I "/var/www/brecal_devel/"
# 2) Color references
# Bar colors in client: (BG_COLOR)
# Devel: #1D751F
# Test: #751D1F
# Prod: #203864
git grep -I "#1D751F"
# 3) Assembly name references
git grep -I "BreCalDevelClient"
echo "Proceed? [N/y]"
read proceed
# for color
if [ "${proceed}" = "y" ]; then
# 1. for database references and paths
git grep -I "connection_data_devel.json" | xargs sed --in-place -e "s/connection_data_devel.json/connection_data_test.json/g"
git add $(git grep -I "connection_data_test.json")
git grep -I "/var/www/brecal_devel/" | xargs sed --in-place -e "s/\/var\/www\/brecal_devel\//\/var\/www\/brecal_test\//g"
git add $(git grep -I "/var/www/brecal_test/")
# 2. for color
git grep -Il "#1D751F" | xargs sed --in-place -e "s/#1D751F/#751D1F/g"
git add $(git grep -Il "#751D1F")
# 3. for assembly name
git grep -I "BreCalDevelClient" | xargs sed --in-place -e "s/BreCalDevelClient/BreCalTestClient/g"
git add $(git grep -I "BreCalTestClient")
fi

192
misc/sample_static_data.sql Normal file
View File

@ -0,0 +1,192 @@
-- --------------------------------------------------------
-- Host: 127.0.0.1
-- Server Version: 8.0.34-0ubuntu0.22.04.1 - (Ubuntu)
-- Server Betriebssystem: Linux
-- HeidiSQL Version: 10.2.0.5599
-- --------------------------------------------------------
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET NAMES utf8 */;
/*!50503 SET NAMES utf8mb4 */;
/*!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' */;
-- Exportiere Daten aus Tabelle bremen_calling_test.berth: ~59 rows (ungefähr)
/*!40000 ALTER TABLE `berth` DISABLE KEYS */;
INSERT INTO `berth` (`id`, `name`, `lock`, `owner_id`, `authority_id`, `created`, `modified`, `deleted`) VALUES
(1, 'Roland Mühle', NULL, NULL, 11, '2023-06-26 14:01:40', '2023-10-06 15:04:08', b'1'),
(2, 'Stahlwerk', NULL, NULL, 11, '2023-06-26 14:01:40', '2023-10-06 15:04:08', b'1'),
(3, 'Kellogs', NULL, NULL, 11, '2023-06-26 14:01:40', '2023-10-06 15:04:08', b'1'),
(139, 'Avangard Dalben', NULL, 110, 136, '2023-08-21 08:23:35', '2023-10-06 16:06:01', b'0'),
(140, 'Avangard Kaje', NULL, 110, 11, '2023-08-21 08:23:35', '2023-10-06 15:04:08', b'0'),
(141, 'Baustelle 2', NULL, 111, 11, '2023-08-21 08:23:35', '2023-10-06 15:04:08', b'0'),
(142, 'BHW', NULL, 112, 11, '2023-08-21 08:23:36', '2023-10-06 15:04:08', b'0'),
(143, 'Dalben 2', NULL, 111, 11, '2023-08-21 08:23:36', '2023-10-06 15:04:08', b'0'),
(144, 'Dalben 3', NULL, 111, 11, '2023-08-21 08:23:36', '2023-10-06 15:04:08', b'0'),
(145, 'Egerland Kaje', NULL, 113, 11, '2023-08-21 08:23:36', '2023-10-06 15:04:08', b'0'),
(146, 'Getreideanlage Pier A', NULL, 114, 11, '2023-08-21 08:23:37', '2023-10-06 15:04:08', b'0'),
(147, 'Getreideanlage Pier D', NULL, 114, 11, '2023-08-21 08:23:37', '2023-10-06 15:04:08', b'0'),
(148, 'Griepe, Bnp Paribas', NULL, 115, 11, '2023-08-21 08:23:37', '2023-10-06 15:04:08', b'0'),
(149, 'Hafen F', NULL, 116, 11, '2023-08-21 08:23:37', '2023-10-06 15:04:08', b'0'),
(150, 'Hansa Landhandel', NULL, 117, 11, '2023-08-21 08:23:38', '2023-10-06 15:04:08', b'0'),
(151, 'Hansa Melasse', NULL, 118, 11, '2023-08-21 08:23:38', '2023-10-06 15:04:08', b'0'),
(152, 'Hansa-Mühle', NULL, 119, 11, '2023-08-21 08:23:38', '2023-10-06 15:04:08', b'0'),
(153, 'Heidelberger Sand', NULL, 120, 11, '2023-08-21 08:23:38', '2023-10-06 15:04:08', b'0'),
(154, 'HGM Bunkerstation', NULL, 121, 11, '2023-08-21 08:23:39', '2023-10-06 15:04:08', b'0'),
(155, 'HGM Tanklager', NULL, 121, 11, '2023-08-21 08:23:39', '2023-10-06 15:04:08', b'0'),
(156, 'Kap Horn Innen', NULL, 122, 11, '2023-08-21 08:23:39', '2023-10-06 15:04:08', b'0'),
(157, 'Kap Horn Weser', NULL, 122, 11, '2023-08-21 08:23:39', '2023-10-06 15:04:08', b'0'),
(158, 'Kap Horn Weser Bremer Recycling', NULL, 123, 11, '2023-08-21 08:23:40', '2023-10-06 15:04:08', b'0'),
(159, 'Kap Horn Weser -GHK-', NULL, 124, 11, '2023-08-21 08:23:40', '2023-10-06 15:04:08', b'0'),
(160, 'Kohlenhafen 2', NULL, 111, 11, '2023-08-21 08:23:40', '2023-10-06 15:04:08', b'0'),
(161, 'Kraftwerk Farge', NULL, 125, 11, '2023-08-21 08:23:40', '2023-10-06 15:04:08', b'0'),
(162, 'Kraftwerk Industriehafen', NULL, 126, 11, '2023-08-21 08:23:41', '2023-10-06 15:04:08', b'0'),
(163, 'Lankenau B', NULL, 111, 11, '2023-08-21 08:23:41', '2023-10-06 15:04:08', b'0'),
(164, 'Mibau, Bnp Paribas', NULL, 127, 11, '2023-08-21 08:23:41', '2023-10-06 15:04:08', b'0'),
(165, 'Müller Weser', NULL, 114, 11, '2023-08-21 08:23:41', '2023-10-06 15:04:08', b'0'),
(166, 'Osterort 5 Aussen', NULL, 111, 11, '2023-08-21 08:23:41', '2023-10-06 15:04:08', b'0'),
(167, 'Pier 2 Anleger', NULL, 128, 11, '2023-08-21 08:23:42', '2023-10-06 15:04:08', b'0'),
(168, 'Pier III', NULL, 129, 11, '2023-08-21 08:23:42', '2023-10-06 15:04:08', b'0'),
(169, 'Plump', NULL, 130, 11, '2023-08-21 08:23:42', '2023-10-06 15:04:08', b'0'),
(170, 'Rolandmühle', NULL, 131, 11, '2023-08-21 08:23:42', '2023-10-06 15:04:08', b'0'),
(171, 'Schleusenvorhafen Nord', NULL, 111, 11, '2023-08-21 08:23:43', '2023-10-06 15:04:08', b'0'),
(172, 'Schrägpier', NULL, 4, 11, '2023-08-21 08:23:43', '2023-10-06 15:04:08', b'0'),
(173, 'Schuppen 19', NULL, 132, 11, '2023-08-21 08:23:43', '2023-10-06 15:04:08', b'0'),
(174, 'Schuppen 20', NULL, 4, 11, '2023-08-21 08:23:43', '2023-10-06 15:04:08', b'0'),
(175, 'Schuppen 21', NULL, 4, 11, '2023-08-21 08:23:43', '2023-10-06 15:04:08', b'0'),
(176, 'Schuppen 22', NULL, 4, 11, '2023-08-21 08:23:43', '2023-10-06 15:04:08', b'0'),
(177, 'Schuppen 23', NULL, 4, 11, '2023-08-21 08:23:44', '2023-10-06 15:04:08', b'0'),
(178, 'Schuppen 24', NULL, 4, 11, '2023-08-21 08:23:44', '2023-10-06 15:04:08', b'0'),
(179, 'Seedalben Dlg-Seite', NULL, 111, 11, '2023-08-21 08:23:44', '2023-10-06 15:04:08', b'0'),
(180, 'Seedalben Kw-Seite', NULL, 111, 11, '2023-08-21 08:23:44', '2023-10-06 15:04:08', b'0'),
(181, 'Seehausen Spüler', NULL, 111, 11, '2023-08-21 08:23:44', '2023-10-06 15:04:08', b'0'),
(182, 'Tankschiffliegeplatz 1', NULL, 111, 11, '2023-08-21 08:23:44', '2023-10-06 15:04:08', b'0'),
(183, 'Tankschiffliegeplatz 2', NULL, 111, 11, '2023-08-21 08:23:44', '2023-10-06 15:04:08', b'0'),
(184, 'Terminal 1', NULL, 10, 11, '2023-08-21 08:23:44', '2023-10-06 15:04:08', b'0'),
(185, 'Terminal 2', NULL, 10, 11, '2023-08-21 08:23:45', '2023-10-06 15:04:08', b'0'),
(186, 'Terminal 3', NULL, 10, 11, '2023-08-21 08:23:45', '2023-10-06 15:04:08', b'0'),
(187, 'Terminal 4', NULL, 10, 11, '2023-08-21 08:23:45', '2023-10-06 15:04:08', b'0'),
(188, 'TSR Recycling', NULL, 133, 11, '2023-08-21 08:23:45', '2023-10-06 15:04:08', b'0'),
(189, 'Viehbrücke', NULL, 111, 11, '2023-08-21 08:23:45', '2023-10-06 15:04:08', b'0'),
(190, 'Vulkan Industriegebiet', NULL, 120, 11, '2023-08-21 08:23:46', '2023-10-06 15:04:08', b'0'),
(191, 'Weserbahnhof', NULL, 132, 11, '2023-08-21 08:23:46', '2023-10-06 15:04:08', b'0'),
(192, 'Weser-Petrol Holzhafen', NULL, 134, 11, '2023-08-21 08:23:46', '2023-10-06 15:04:08', b'0'),
(193, 'Weser-Petrol Kalihafen', NULL, 134, 11, '2023-08-21 08:23:46', '2023-10-06 15:04:08', b'0'),
(194, 'Wesertanking', NULL, 135, 11, '2023-08-21 08:23:46', '2023-10-06 15:04:08', b'0');
/*!40000 ALTER TABLE `berth` ENABLE KEYS */;
-- Exportiere Daten aus Tabelle bremen_calling_test.participant: ~40 rows (ungefähr)
/*!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-24 07:07:02', 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, 1, '2023-08-10 07:19:29', '2023-09-06 09:02:53', 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'),
(12, 'Nordenia Frachtkontor GmbH', '', '', '', 8, 0, '2023-08-21 06:52:04', NULL, b'0'),
(15, 'Extern', '', '', '', 0, 0, '2023-08-21 06:55:18', NULL, b'0'),
(16, 'FESTMA Vertäugesellschaft mbH', '', '', '', 16, 0, '2023-08-21 06:57:23', NULL, b'0'),
(110, 'Avangard', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:35', '2023-08-21 10:04:21', b'0'),
(111, 'Bremenports', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:35', '2023-08-21 10:04:21', b'0'),
(112, 'Bremer Holzwerke', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:36', '2023-08-21 10:04:21', b'0'),
(113, 'Egerland', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:36', '2023-08-21 10:04:21', b'0'),
(114, 'Müller J. Bremen', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:37', '2023-08-21 10:04:21', b'0'),
(115, 'Griepe', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:37', '2023-08-21 10:04:21', b'0'),
(116, 'Mseven Real Estate', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:37', '2023-08-21 10:04:21', b'0'),
(117, 'Hansa Landhandel', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:38', '2023-08-21 10:04:21', b'0'),
(118, 'Hansa Melasse', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:38', '2023-08-21 10:04:21', b'0'),
(119, 'Hansa-Mühle', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:38', '2023-08-21 10:04:21', b'0'),
(120, 'Heidelberger Sand Und Kies Gmbh', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:38', '2023-08-21 10:04:21', b'0'),
(121, 'HGM', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:39', '2023-08-21 10:04:21', b'0'),
(122, 'Kap-Horn Logistics Gmbh', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:39', '2023-08-21 10:04:21', b'0'),
(123, 'Bremer Recycling Kontor', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:39', '2023-08-21 10:04:21', b'0'),
(124, 'GHK', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:40', '2023-08-21 10:04:21', b'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', b'0'),
(126, 'Swb Erzeugung', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:40', '2023-08-21 10:04:21', b'0'),
(127, 'Mibau', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:41', '2023-08-21 10:04:21', b'0'),
(128, 'SWG', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:41', '2023-08-21 10:04:21', b'0'),
(129, 'Umweltschutz Nord Ganderkesee', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:42', '2023-08-21 10:04:21', b'0'),
(130, 'Nehlsen Industrieservice Gmbh & Co. KG', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:42', '2023-08-21 10:04:21', b'0'),
(131, 'Rolandmühle', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:42', '2023-08-21 10:04:21', b'0'),
(132, 'Wfb', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:43', '2023-08-21 10:04:21', b'0'),
(133, 'TSR', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:45', '2023-08-21 10:04:21', b'0'),
(134, 'Weser-Petrol', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:46', '2023-08-21 10:04:21', b'0'),
(135, 'Wesertanking', NULL, NULL, NULL, 2, 0, '2023-08-21 08:23:46', '2023-08-21 10:04:21', b'0'),
(136, 'TEST_BSMD', 'Überseetor 20', '28217', 'Bremen', 127, 1, '2023-10-04 11:54:36', '2023-10-13 11:37:51', b'0');
/*!40000 ALTER TABLE `participant` ENABLE KEYS */;
-- Exportiere Daten aus Tabelle bremen_calling_test.role: ~2 rows (ungefähr)
/*!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);
/*!40000 ALTER TABLE `role` ENABLE KEYS */;
-- Exportiere Daten aus Tabelle bremen_calling_test.securable: ~2 rows (ungefähr)
/*!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);
/*!40000 ALTER TABLE `securable` ENABLE KEYS */;
-- Exportiere Daten aus Tabelle bremen_calling_test.ship: ~12 rows (ungefähr)
/*!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'),
(3, 'AFRICAN HALCYON', 9343613, NULL, NULL, 177.13, 28.4, b'0', NULL, NULL, '2023-08-24 10:41:56', NULL, b'0'),
(4, 'AMIKO', 9125669, NULL, NULL, 99.98, 16.5, b'0', NULL, NULL, '2023-08-24 10:42:17', NULL, b'0'),
(5, 'ARKLOW BEACON', 9638795, NULL, NULL, 119.49, 14.99, b'0', NULL, NULL, '2023-08-24 10:42:17', NULL, b'0'),
(6, 'FWN ATLANTIDE', 9535620, NULL, NULL, 145.65, 18.25, b'0', NULL, NULL, '2023-08-24 10:42:17', NULL, b'0'),
(7, 'IONIAN SPIRIT', 9747235, NULL, NULL, 179.9, 30, b'0', NULL, NULL, '2023-08-24 10:42:17', NULL, b'0'),
(8, 'IRMA', 9180396, NULL, NULL, 199.9, 23.6, b'0', NULL, NULL, '2023-08-24 10:42:17', NULL, b'0'),
(9, 'JANA', 9330185, NULL, NULL, 69.34, 12, b'0', NULL, NULL, '2023-08-24 10:42:18', NULL, b'0'),
(10, 'MEDI PERTH', 9804552, NULL, NULL, 199.99, 32.24, b'0', NULL, NULL, '2023-08-24 10:42:18', NULL, b'0'),
(11, 'S NEPTUNE', 9634892, NULL, NULL, 169.99, 27, b'0', NULL, NULL, '2023-08-24 10:42:18', NULL, b'0'),
(12, 'WESER STAHL', 9186687, NULL, NULL, 192, 32.26, b'0', NULL, NULL, '2023-08-24 10:42:18', NULL, b'0'),
(13, 'BOTHNIABORG', 9267728, 'PBIO', NULL, 153.05, 21.8, b'0', NULL, NULL, '2023-10-04 11:52:32', NULL, b'0');
/*!40000 ALTER TABLE `ship` ENABLE KEYS */;
-- Exportiere Daten aus Tabelle bremen_calling_test.user: ~27 rows (ungefähr)
/*!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 2314', '$2b$12$8r1oGQiWdiuQNoGbzm.z.OoCOc8.4YACN93k7ge7YDWKjQ8tPuTrm', NULL, '2023-06-27 08:34:55', '2023-10-28 12:04:54'),
(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$evGJop3j19bNTkdg2GHrIeRedC7LG5SIHm8.hKhdUSrlXsp6sXBDG', '', '2023-08-10 07:12:05', '2023-10-04 11:48:13'),
(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),
(28, 136, 'Christin', 'Hollmann', 'chollmann', NULL, NULL, '$2b$12$pb1bWJ7hxOplFoqT/nIhyuRD39dxOpQ9t0LwZUI8CNOkTkE.eXiSO', '', '2023-10-04 11:55:05', NULL),
(29, 1, 'Max', 'Metz', 'maxm', NULL, NULL, '$2b$12$gm4EwjCF44Ls20vDHnlG/ew/cZ.DK4gcYed.OHER5J4OzZrA.9Jt.', '', '2023-10-06 13:02:56', '2023-10-13 11:53:35');
/*!40000 ALTER TABLE `user` ENABLE KEYS */;
/*!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 CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;

1
misc/version.txt Normal file
View File

@ -0,0 +1 @@
0.9.5.0

View File

@ -7,7 +7,7 @@
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit" xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:p = "clr-namespace:BreCalClient.Resources" xmlns:p = "clr-namespace:BreCalClient.Resources"
mc:Ignorable="d" mc:Ignorable="d"
Title="Help" Height="280" Width="500"> Title="Help" Height="374" Width="500" Loaded="Window_Loaded">
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="180" /> <ColumnDefinition Width="180" />
@ -20,6 +20,10 @@
<RowDefinition Height="28" /> <RowDefinition Height="28" />
<RowDefinition Height="28" /> <RowDefinition Height="28" />
<RowDefinition Height="28" /> <RowDefinition Height="28" />
<RowDefinition Height="10" />
<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" />
@ -39,14 +43,20 @@
</Hyperlink> </Hyperlink>
</TextBlock> </TextBlock>
<Label FontWeight="DemiBold" Grid.Row="3" Grid.Column="0" Content="{x:Static p:Resources.textChangePassword}" HorizontalContentAlignment="Right"/> <Label FontWeight="DemiBold" Grid.Row="3" Grid.Column="0" Content="{x:Static p:Resources.textChangeContactInfo}" HorizontalContentAlignment="Right"/>
<Label Grid.Row="4" Grid.Column="0" Content="{x:Static p:Resources.textEmail}" HorizontalContentAlignment="Right" />
<xctk:WatermarkPasswordBox Watermark="{x:Static p:Resources.textOldPassword}" Grid.Column="1" Grid.Row="3" Margin="2" x:Name="wpBoxOldPassword" TextChanged="wpBoxOldPassword_TextChanged"/> <Label Grid.Row="5" Grid.Column="0" Content="{x:Static p:Resources.textPhone}" HorizontalContentAlignment="Right" />
<xctk:WatermarkPasswordBox Watermark="{x:Static p:Resources.textNewPassword}" Grid.Column="1" Grid.Row="4" Margin="2" x:Name="wpBoxNewPassword" TextChanged="wpBoxOldPassword_TextChanged"/> <TextBox Name="textBoxUserEmail" Grid.Column="1" Grid.Row="4" Margin="2" VerticalContentAlignment="Center" />
<xctk:WatermarkPasswordBox Watermark="{x:Static p:Resources.textRepeatNewPassword}" Grid.Column="1" Grid.Row="5" Margin="2" x:Name="wpBoxNewPasswordRepeat" TextChanged="wpBoxOldPassword_TextChanged"/> <TextBox Name="textBoxUserPhone" Grid.Column="1" Grid.Row="5" Margin="2" VerticalContentAlignment="Center" />
<Button x:Name="buttonChangePassword" Click="buttonChangePassword_Click" Grid.Column="1" Grid.Row="6" Margin="2" Content="{x:Static p:Resources.textChange}" Width="80" HorizontalAlignment="Left" IsEnabled="False" />
<Button x:Name="buttonClose" Click="buttonClose_Click" Content="{x:Static p:Resources.textClose}" Width="80" Margin="2" Grid.Column="1" Grid.Row="8" HorizontalAlignment="Right" /> <Label FontWeight="DemiBold" Grid.Row="7" Grid.Column="0" Content="{x:Static p:Resources.textChangePassword}" HorizontalContentAlignment="Right"/>
<xctk:WatermarkPasswordBox Watermark="{x:Static p:Resources.textOldPassword}" Grid.Column="1" Grid.Row="7" Margin="2" x:Name="wpBoxOldPassword" TextChanged="wpBoxOldPassword_TextChanged"/>
<xctk:WatermarkPasswordBox Watermark="{x:Static p:Resources.textNewPassword}" Grid.Column="1" Grid.Row="8" Margin="2" x:Name="wpBoxNewPassword" TextChanged="wpBoxOldPassword_TextChanged"/>
<xctk:WatermarkPasswordBox Watermark="{x:Static p:Resources.textRepeatNewPassword}" Grid.Column="1" Grid.Row="9" Margin="2" x:Name="wpBoxNewPasswordRepeat" TextChanged="wpBoxOldPassword_TextChanged"/>
<Button x:Name="buttonChangePassword" Click="buttonChangePassword_Click" Grid.Column="1" Grid.Row="10" Margin="2" Content="{x:Static p:Resources.textChange}" Width="80" HorizontalAlignment="Left" IsEnabled="True" />
<Button x:Name="buttonClose" Click="buttonClose_Click" Content="{x:Static p:Resources.textClose}" Width="80" Margin="2" Grid.Column="1" Grid.Row="12" HorizontalAlignment="Right" />
</Grid> </Grid>
</Window> </Window>

View File

@ -2,6 +2,7 @@
// Description: Show about info and allow user detail editing // Description: Show about info and allow user detail editing
// //
using BreCalClient.misc.Model;
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Windows; using System.Windows;
@ -24,6 +25,12 @@ namespace BreCalClient
#endregion #endregion
#region Properties
public LoginResult? LoginResult { get; set; }
#endregion
#region events #region events
public event Action<string, string>? ChangePasswordRequested; public event Action<string, string>? ChangePasswordRequested;
@ -39,6 +46,12 @@ namespace BreCalClient
private void buttonChangePassword_Click(object sender, RoutedEventArgs e) private void buttonChangePassword_Click(object sender, RoutedEventArgs e)
{ {
if (this.LoginResult != null)
{
this.LoginResult.UserPhone = this.textBoxUserPhone.Text.Trim();
this.LoginResult.UserEmail = this.textBoxUserEmail.Text.Trim();
}
this.ChangePasswordRequested?.Invoke(this.wpBoxOldPassword.Password, this.wpBoxNewPassword.Password); this.ChangePasswordRequested?.Invoke(this.wpBoxOldPassword.Password, this.wpBoxNewPassword.Password);
} }
@ -56,9 +69,17 @@ namespace BreCalClient
(this.wpBoxNewPasswordRepeat.Password.Length > 0) && (this.wpBoxNewPasswordRepeat.Password.Length > 0) &&
this.wpBoxNewPassword.Password.Equals(this.wpBoxNewPasswordRepeat.Password) && this.wpBoxNewPassword.Password.Equals(this.wpBoxNewPasswordRepeat.Password) &&
(!this.wpBoxNewPassword.Password.Equals(this.wpBoxOldPassword.Password)); (!this.wpBoxNewPassword.Password.Equals(this.wpBoxOldPassword.Password));
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
if(LoginResult != null)
{
this.textBoxUserEmail.Text = LoginResult.UserEmail;
this.textBoxUserPhone.Text = LoginResult.UserPhone;
}
} }
#endregion #endregion
} }
} }

View File

@ -11,10 +11,10 @@
<applicationSettings> <applicationSettings>
<BreCalClient.Properties.Settings> <BreCalClient.Properties.Settings>
<setting name="API_URL" serializeAs="String"> <setting name="API_URL" serializeAs="String">
<value>https://brecaltest.bsmd-emswe.eu</value> <value>https://brecaldevel.bsmd-emswe.eu</value>
</setting> </setting>
<setting name="BG_COLOR" serializeAs="String"> <setting name="BG_COLOR" serializeAs="String">
<value>#751D1F</value> <value>#1D751F</value>
</setting> </setting>
<setting name="APP_TITLE" serializeAs="String"> <setting name="APP_TITLE" serializeAs="String">
<value>!!Bremen calling Testversion!!</value> <value>!!Bremen calling Testversion!!</value>

View File

@ -8,12 +8,12 @@
<SignAssembly>True</SignAssembly> <SignAssembly>True</SignAssembly>
<StartupObject>BreCalClient.App</StartupObject> <StartupObject>BreCalClient.App</StartupObject>
<AssemblyOriginatorKeyFile>..\..\misc\brecal.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>..\..\misc\brecal.snk</AssemblyOriginatorKeyFile>
<AssemblyVersion>0.9.3.0</AssemblyVersion> <AssemblyVersion>0.9.5.0</AssemblyVersion>
<FileVersion>0.9.3.0</FileVersion> <FileVersion>0.9.5.0</FileVersion>
<Title>Bremen calling client</Title> <Title>Bremen calling client</Title>
<Description>A Windows WPF client for the Bremen calling API.</Description> <Description>A Windows WPF client for the Bremen calling API.</Description>
<ApplicationIcon>containership.ico</ApplicationIcon> <ApplicationIcon>containership.ico</ApplicationIcon>
<AssemblyName>BreCalTestClient</AssemblyName> <AssemblyName>BreCalDevelClient</AssemblyName>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -58,9 +58,7 @@
<Label Content="ETD" Grid.Column="2" Grid.Row="3" 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"/> <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"/> <Label Content="{x:Static p:Resources.textBerth}" Grid.Column="2" Grid.Row="1" HorizontalContentAlignment="Right"/>
<Grid Grid.Row="1" Grid.Column="3"> <Grid Grid.Row="1" Grid.Column="3">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
@ -68,14 +66,14 @@
<ColumnDefinition Width=".5*" /> <ColumnDefinition Width=".5*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<ComboBox Name="comboBoxArrivalBerth" Grid.Column="0" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id"> <ComboBox Name="comboBoxArrivalBerth" Grid.Column="1" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id">
<ComboBox.ContextMenu> <ComboBox.ContextMenu>
<ContextMenu> <ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemArrivalBerth" Click="contextMenuItemArrivalBerth_Click" /> <MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemArrivalBerth" Click="contextMenuItemArrivalBerth_Click" />
</ContextMenu> </ContextMenu>
</ComboBox.ContextMenu> </ComboBox.ContextMenu>
</ComboBox> </ComboBox>
<ComboBox Name="comboBoxDepartureBerth" Grid.Column="1" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id"> <ComboBox Name="comboBoxDepartureBerth" Grid.Column="0" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id">
<ComboBox.ContextMenu> <ComboBox.ContextMenu>
<ContextMenu> <ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemDepartureBerth" Click="contextMenuItemDepartureBerth_Click" /> <MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemDepartureBerth" Click="contextMenuItemDepartureBerth_Click" />
@ -83,6 +81,9 @@
</ComboBox.ContextMenu> </ComboBox.ContextMenu>
</ComboBox> </ComboBox>
</Grid> </Grid>
<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.textAgency}" Grid.Column="2" Grid.Row="4" HorizontalContentAlignment="Right"/> <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 Name="comboBoxAgency" Grid.Column="3" Grid.Row="4" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id" SelectionChanged="comboBoxAgency_SelectionChanged">
@ -93,7 +94,6 @@
</ComboBox.ContextMenu> </ComboBox.ContextMenu>
</ComboBox> </ComboBox>
<Label x:Name="labelBSMDGranted" Grid.Row="14" Grid.Column="1" Grid.ColumnSpan="2" Content="{x:Static p:Resources.textBSMDGranted}" Visibility="Hidden" FontWeight="DemiBold" /> <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"> <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.textOK}" x:Name="buttonOK" Click="buttonOK_Click" IsEnabled="False" />

View File

@ -132,7 +132,7 @@
<TextBox x:Name="textBoxRemarks" Grid.Column="3" Grid.Row="10" Margin="2" Grid.RowSpan="2" VerticalContentAlignment="Top" AcceptsReturn="True" /> <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"> <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.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"/> <Button Width="80" Margin="2" Content="{x:Static p:Resources.textCancel}" x:Name="buttonCancel" Click="buttonCancel_Click"/>
</StackPanel> </StackPanel>
</Grid> </Grid>

View File

@ -261,6 +261,8 @@ namespace BreCalClient
this.checkBoxReplenishingTerminal.IsEnabled = isEnabled; this.checkBoxReplenishingTerminal.IsEnabled = isEnabled;
this.checkBoxReplenishingLock.IsEnabled = isEnabled; this.checkBoxReplenishingLock.IsEnabled = isEnabled;
this.textBoxRemarks.IsEnabled = isEnabled; this.textBoxRemarks.IsEnabled = isEnabled;
this.buttonOK.IsEnabled = isEnabled;
} }
#endregion #endregion

View File

@ -122,7 +122,7 @@
<TextBox x:Name="textBoxRemarks" Grid.Column="3" Grid.Row="8" Margin="2" Grid.RowSpan="3" VerticalContentAlignment="Top" AcceptsReturn="True" /> <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"> <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.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"/> <Button Width="80" Margin="2" Content="{x:Static p:Resources.textCancel}" x:Name="buttonCancel" Click="buttonCancel_Click"/>
</StackPanel> </StackPanel>
</Grid> </Grid>

View File

@ -246,6 +246,8 @@ namespace BreCalClient
this.comboBoxTerminal.IsEnabled = isEnabled; this.comboBoxTerminal.IsEnabled = isEnabled;
this.checkBoxRainsensitiveCargo.IsEnabled = isEnabled; this.checkBoxRainsensitiveCargo.IsEnabled = isEnabled;
this.textBoxRemarks.IsEnabled = isEnabled; this.textBoxRemarks.IsEnabled = isEnabled;
this.buttonOK.IsEnabled = isEnabled;
} }
#endregion #endregion

View File

@ -8,13 +8,13 @@
xmlns:db="clr-namespace:BreCalClient;assembly=BreCalClient" xmlns:db="clr-namespace:BreCalClient;assembly=BreCalClient"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit" xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
mc:Ignorable="d" mc:Ignorable="d"
Title="{x:Static p:Resources.textEditShipcall}" Height="460" Width="800" Loaded="Window_Loaded" ResizeMode="NoResize" Icon="Resources/containership.ico"> Title="{x:Static p:Resources.textEditShipcall}" Height="490" Width="800" Loaded="Window_Loaded" ResizeMode="NoResize" Icon="Resources/containership.ico">
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*"/> <ColumnDefinition Width="0.2*"/>
<ColumnDefinition Width=".3*" /> <ColumnDefinition Width=".3*" />
<ColumnDefinition Width="0.15*"/> <ColumnDefinition Width="0.2*"/>
<ColumnDefinition Width=".35*" /> <ColumnDefinition Width=".3*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="28" /> <RowDefinition Height="28" />
@ -32,6 +32,7 @@
<RowDefinition Height="28" /> <RowDefinition Height="28" />
<RowDefinition Height="28" /> <RowDefinition Height="28" />
<RowDefinition Height="28" /> <RowDefinition Height="28" />
<RowDefinition Height="28" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
@ -45,8 +46,18 @@
</Grid> </Grid>
<Label Content="ETD" Grid.Column="0" Grid.Row="1" HorizontalContentAlignment="Right"/> <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"/> <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"> <Label Content="{x:Static p:Resources.textTerminal}" Grid.Column="0" Grid.Row="2" HorizontalContentAlignment="Right"/>
<ComboBox Name="comboBoxTerminal" Grid.Column="1" Grid.Row="2" 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.textBerth}" Grid.Column="0" Grid.Row="3" HorizontalContentAlignment="Right" />
<ComboBox Name="comboBoxDepartureBerth" Grid.Column="1" Grid.Row="3" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id">
<ComboBox.ContextMenu> <ComboBox.ContextMenu>
<ContextMenu> <ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemDepartureBerth" Click="contextMenuItemDepartureBerth_Click" /> <MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemDepartureBerth" Click="contextMenuItemDepartureBerth_Click" />
@ -54,14 +65,14 @@
</ComboBox.ContextMenu> </ComboBox.ContextMenu>
</ComboBox> </ComboBox>
<Label Content="{x:Static p:Resources.textDraft}" Grid.Column="0" Grid.Row="3" HorizontalContentAlignment="Right" /> <Label Content="{x:Static p:Resources.textDraft}" Grid.Column="0" Grid.Row="4" HorizontalContentAlignment="Right" />
<xctk:DoubleUpDown x:Name="doubleUpDownDraft" Grid.Column="1" Grid.Row="3" Margin="2" FormatString="N2" Minimum="0" /> <xctk:DoubleUpDown x:Name="doubleUpDownDraft" Grid.Column="1" Grid.Row="4" 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.textTidalWindow}" FontWeight="DemiBold" Grid.Column="0" Grid.Row="5" HorizontalContentAlignment="Right"/>
<Label Content="{x:Static p:Resources.textFrom}" Grid.Column="0" Grid.Row="5" HorizontalContentAlignment="Right"/> <Label Content="{x:Static p:Resources.textFrom}" Grid.Column="0" Grid.Row="6" HorizontalContentAlignment="Right"/>
<Label Content="{x:Static p:Resources.textTo}" Grid.Column="0" Grid.Row="6" HorizontalContentAlignment="Right"/> <Label Content="{x:Static p:Resources.textTo}" Grid.Column="0" Grid.Row="7" 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="datePickerTidalWindowFrom" Grid.Column="1" Grid.Row="6" 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"/> <xctk:DateTimePicker Name="datePickerTidalWindowTo" Grid.Column="1" Grid.Row="7" Margin="2" Format="Custom" FormatString="dd.MM. yyyy HH:mm"/>
<Grid Grid.Row="7" Grid.Column="0"> <Grid Grid.Row="8" Grid.Column="0">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
<ColumnDefinition Width="30" /> <ColumnDefinition Width="30" />
@ -69,25 +80,26 @@
<Label Grid.Column="0" Grid.Row="0" Content="{x:Static p:Resources.textShiftingTo}" FontWeight="DemiBold"/> <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" /> <Image Margin="2" Grid.Column="1" Source="Resources/arrow_right_green.png" />
</Grid> </Grid>
<Label Content="ETA" Grid.Column="0" Grid.Row="8" HorizontalContentAlignment="Right"/> <Label Content="ETA" Grid.Column="0" Grid.Row="9" HorizontalContentAlignment="Right"/>
<xctk:DateTimePicker x:Name="datePickerETA" Grid.Column="1" Grid.Row="8" Margin="2" Format="Custom" FormatString="dd.MM. yyyy HH:mm"/> <xctk:DateTimePicker x:Name="datePickerETA" Grid.Column="1" Grid.Row="9" 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"> <Label Content="{x:Static p:Resources.textBerth}" Grid.Column="0" Grid.Row="10" HorizontalContentAlignment="Right"/>
<ComboBox Name="comboBoxArrivalBerth" Grid.Column="1" Grid.Row="10" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id">
<ComboBox.ContextMenu> <ComboBox.ContextMenu>
<ContextMenu> <ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemArrivalBerth" Click="contextMenuItemArrivalBerth_Click" /> <MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemArrivalBerth" Click="contextMenuItemArrivalBerth_Click" />
</ContextMenu> </ContextMenu>
</ComboBox.ContextMenu> </ComboBox.ContextMenu>
</ComboBox> </ComboBox>
<Label Content="{x:Static p:Resources.textPierside}" Grid.Column="0" Grid.Row="10" HorizontalContentAlignment="Right" /> <Label Content="{x:Static p:Resources.textPierside}" Grid.Column="0" Grid.Row="11" HorizontalContentAlignment="Right" />
<ComboBox x:Name="comboBoxPiersideArrival" Grid.Column="1" Grid.Row="10" Margin="2" > <ComboBox x:Name="comboBoxPiersideArrival" Grid.Column="1" Grid.Row="11" Margin="2" >
<ComboBoxItem Content="{x:Static p:Resources.textNotRotated}" /> <ComboBoxItem Content="{x:Static p:Resources.textNotRotated}" />
<ComboBoxItem Content="{x:Static p:Resources.textRotated}" /> <ComboBoxItem Content="{x:Static p:Resources.textRotated}" />
</ComboBox> </ComboBox>
<Label Content="{x:Static p:Resources.textBerthRemarks}" Grid.Column="0" Grid.Row="11" HorizontalContentAlignment="Right" /> <Label Content="{x:Static p:Resources.textBerthRemarks}" Grid.Column="0" Grid.Row="12" HorizontalContentAlignment="Right" />
<TextBox x:Name="textBoxBerthRemarksArrival" Grid.Column="1" Grid.Row="11" Margin="2,1,2,3" Grid.RowSpan="2" VerticalContentAlignment="Top" AcceptsReturn="True" /> <TextBox x:Name="textBoxBerthRemarksArrival" Grid.Column="1" Grid.Row="12" 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" /> <Label Content="{x:Static p:Resources.textCancelled}" Grid.Column="0" Grid.Row="14" HorizontalContentAlignment="Right" />
<CheckBox x:Name="checkBoxCanceled" Grid.Column="1" Grid.Row="13" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,4,0" /> <CheckBox x:Name="checkBoxCanceled" Grid.Column="1" Grid.Row="14" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,4,0" />
<Label Content="{x:Static p:Resources.textTugRequired}" Grid.Column="2" Grid.Row="1" HorizontalContentAlignment="Right"/> <Label Content="{x:Static p:Resources.textTugRequired}" Grid.Column="2" Grid.Row="1" HorizontalContentAlignment="Right"/>
@ -132,21 +144,14 @@
</ComboBox> </ComboBox>
<Label Content="{x:Static p:Resources.textMooredLock}" Grid.Column="2" Grid.Row="5" HorizontalContentAlignment="Right" /> <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" /> <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"> <Label Content="{x:Static p:Resources.textRainSensitiveCargo}" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="6" HorizontalAlignment="Right" />
<ComboBox.ContextMenu> <CheckBox x:Name="checkBoxRainsensitiveCargo" Grid.Column="3" Grid.Row="6" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,4,0" />
<ContextMenu> <Label Content="{x:Static p:Resources.textRemarks}" Grid.Column="2" Grid.Row="7" HorizontalContentAlignment="Right" />
<MenuItem Header="{x:Static p:Resources.textClearAssignment}" Name="contextMenuItemClearTerminal" Click="contextMenuItemClearTerminal_Click" /> <TextBox x:Name="textBoxRemarks" Grid.Column="3" Grid.Row="7" Margin="2,1,2,3" Grid.RowSpan="7" VerticalContentAlignment="Top" AcceptsReturn="True" />
</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"> <StackPanel Grid.Row="15" 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.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"/> <Button Width="80" Margin="2" Content="{x:Static p:Resources.textCancel}" x:Name="buttonCancel" Click="buttonCancel_Click"/>
</StackPanel> </StackPanel>
</Grid> </Grid>

View File

@ -263,6 +263,8 @@ namespace BreCalClient
this.comboBoxTerminal.IsEnabled = isEnabled; this.comboBoxTerminal.IsEnabled = isEnabled;
this.checkBoxRainsensitiveCargo.IsEnabled = isEnabled; this.checkBoxRainsensitiveCargo.IsEnabled = isEnabled;
this.textBoxRemarks.IsEnabled = isEnabled; this.textBoxRemarks.IsEnabled = isEnabled;
this.buttonOK.IsEnabled = isEnabled;
} }
#endregion #endregion

View File

@ -81,9 +81,9 @@
</xctk:DateTimePicker> </xctk:DateTimePicker>
<CheckBox IsEnabled="False" Grid.Row="4" Grid.Column="2" Margin="4,0,0,0" Name="checkBoxZoneEntryFixed" VerticalAlignment="Center" /> <CheckBox IsEnabled="False" Grid.Row="4" Grid.Column="2" Margin="4,0,0,0" Name="checkBoxZoneEntryFixed" VerticalAlignment="Center" />
<TextBox Grid.Row="5" Grid.Column="1" Margin="2" Name="textBoxRemarks" 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" IsEnabled="False"/>
<StackPanel Grid.Row="6" Grid.Column="1" Grid.ColumnSpan="2" Orientation="Horizontal" HorizontalAlignment="Right"> <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.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"/> <Button Width="80" Margin="2" Content="{x:Static p:Resources.textCancel}" x:Name="buttonCancel" Click="buttonCancel_Click"/>
</StackPanel> </StackPanel>

View File

@ -87,6 +87,7 @@ namespace BreCalClient
private void EnableControls() private void EnableControls()
{ {
Extensions.ParticipantType pType = (Extensions.ParticipantType) (this.Times.ParticipantType ?? 0); Extensions.ParticipantType pType = (Extensions.ParticipantType) (this.Times.ParticipantType ?? 0);
if (this.Times.ParticipantId != App.Participant.Id) return; // if this is not "my" entry, there is no editing!
switch (pType) switch (pType)
{ {
@ -115,6 +116,7 @@ namespace BreCalClient
this.textBoxRemarks.IsEnabled = true; this.textBoxRemarks.IsEnabled = true;
break; break;
} }
this.buttonOK.IsEnabled = true;
} }
#endregion #endregion

View File

@ -32,7 +32,7 @@
<Label Grid.Row="5" Grid.Column="0" Content="{x:Static p:Resources.textRemarks}" 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 Grid.Row="0" Grid.Column="1" Margin="2" Name="datePickerOperationStart" Format="Custom" FormatString="dd.MM. yyyy HH:mm" IsEnabled="False">
<xctk:DateTimePicker.ContextMenu> <xctk:DateTimePicker.ContextMenu>
<ContextMenu> <ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemClearOperationStart" Click="contextMenuItemClearOperationStart_Click" > <MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemClearOperationStart" Click="contextMenuItemClearOperationStart_Click" >
@ -43,7 +43,7 @@
</ContextMenu> </ContextMenu>
</xctk:DateTimePicker.ContextMenu> </xctk:DateTimePicker.ContextMenu>
</xctk:DateTimePicker> </xctk:DateTimePicker>
<xctk:DateTimePicker Grid.Row="1" Grid.Column="1" Margin="2" Name="datePickerOperationEnd" Format="Custom" FormatString="dd.MM. yyyy HH:mm"> <xctk:DateTimePicker Grid.Row="1" Grid.Column="1" Margin="2" Name="datePickerOperationEnd" Format="Custom" FormatString="dd.MM. yyyy HH:mm" IsEnabled="False">
<xctk:DateTimePicker.ContextMenu> <xctk:DateTimePicker.ContextMenu>
<ContextMenu> <ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemClearOperationEnd" Click="contextMenuItemClearOperationEnd_Click" > <MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemClearOperationEnd" Click="contextMenuItemClearOperationEnd_Click" >
@ -54,21 +54,21 @@
</ContextMenu> </ContextMenu>
</xctk:DateTimePicker.ContextMenu> </xctk:DateTimePicker.ContextMenu>
</xctk:DateTimePicker> </xctk:DateTimePicker>
<ComboBox Name="comboBoxBerth" Grid.Column="1" Grid.Row="2" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id"> <ComboBox Name="comboBoxBerth" Grid.Column="1" Grid.Row="2" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id" IsEnabled="False">
<ComboBox.ContextMenu> <ComboBox.ContextMenu>
<ContextMenu> <ContextMenu>
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemBerth" Click="contextMenuItemBerth_Click" /> <MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemBerth" Click="contextMenuItemBerth_Click" />
</ContextMenu> </ContextMenu>
</ComboBox.ContextMenu> </ComboBox.ContextMenu>
</ComboBox> </ComboBox>
<ComboBox x:Name="comboBoxPierside" Grid.Column="1" Grid.Row="3" Margin="2" > <ComboBox x:Name="comboBoxPierside" Grid.Column="1" Grid.Row="3" Margin="2" IsEnabled="False">
<ComboBoxItem Content="{x:Static p:Resources.textNotRotated}" /> <ComboBoxItem Content="{x:Static p:Resources.textNotRotated}" />
<ComboBoxItem Content="{x:Static p:Resources.textRotated}" /> <ComboBoxItem Content="{x:Static p:Resources.textRotated}" />
</ComboBox> </ComboBox>
<TextBox Grid.Row="4" Grid.Column="1" Margin="2" Name="textBoxBerthRemarks" TextWrapping="Wrap" AcceptsReturn="True" SpellCheck.IsEnabled="True" AcceptsTab="True" /> <TextBox Grid.Row="4" Grid.Column="1" Margin="2" Name="textBoxBerthRemarks" TextWrapping="Wrap" AcceptsReturn="True" SpellCheck.IsEnabled="True" AcceptsTab="True" IsEnabled="False" />
<TextBox Grid.Row="5" Grid.Column="1" Margin="2" Name="textBoxRemarks" 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" IsEnabled="False" />
<StackPanel Grid.Row="6" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right"> <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.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"/> <Button Width="80" Margin="2" Content="{x:Static p:Resources.textCancel}" x:Name="buttonCancel" Click="buttonCancel_Click"/>
</StackPanel> </StackPanel>

View File

@ -94,12 +94,15 @@ namespace BreCalClient
private void EnableControls() private void EnableControls()
{ {
if (this.Times.ParticipantId != App.Participant.Id) return;
this.datePickerOperationStart.IsEnabled = (CallType == Extensions.TypeEnum.Incoming) || (CallType == Extensions.TypeEnum.Shifting); this.datePickerOperationStart.IsEnabled = (CallType == Extensions.TypeEnum.Incoming) || (CallType == Extensions.TypeEnum.Shifting);
this.datePickerOperationEnd.IsEnabled = (CallType == Extensions.TypeEnum.Outgoing) || (CallType == Extensions.TypeEnum.Shifting); this.datePickerOperationEnd.IsEnabled = (CallType == Extensions.TypeEnum.Outgoing) || (CallType == Extensions.TypeEnum.Shifting);
this.comboBoxBerth.IsEnabled = (CallType == Extensions.TypeEnum.Incoming) || (CallType == Extensions.TypeEnum.Shifting); this.comboBoxBerth.IsEnabled = (CallType == Extensions.TypeEnum.Incoming) || (CallType == Extensions.TypeEnum.Shifting);
this.comboBoxPierside.IsEnabled = (CallType == Extensions.TypeEnum.Incoming) || (CallType == Extensions.TypeEnum.Shifting); this.comboBoxPierside.IsEnabled = (CallType == Extensions.TypeEnum.Incoming) || (CallType == Extensions.TypeEnum.Shifting);
this.textBoxBerthRemarks.IsEnabled = (CallType == Extensions.TypeEnum.Incoming) || (CallType == Extensions.TypeEnum.Shifting); this.textBoxBerthRemarks.IsEnabled = (CallType == Extensions.TypeEnum.Incoming) || (CallType == Extensions.TypeEnum.Shifting);
this.textBoxRemarks.IsEnabled = true; this.textBoxRemarks.IsEnabled = true;
this.buttonOK.IsEnabled = true;
} }
#endregion #endregion

View File

@ -46,7 +46,9 @@ namespace BreCalClient
private bool _refreshImmediately = false; private bool _refreshImmediately = false;
private bool? _showCanceled = null; private bool? _showCanceled = null;
private SortOrder? _sortOrder; private SortOrder _sortOrder = SortOrder.ETA_ETD;
private int searchPastDays = 0;
// private bool _filterChanged = false; // private bool _filterChanged = false;
// private bool _sequenceChanged = false; // private bool _sequenceChanged = false;
@ -88,6 +90,7 @@ namespace BreCalClient
Process.Start("explorer", Properties.Settings.Default.LOGO_IMAGE_URL); Process.Start("explorer", Properties.Settings.Default.LOGO_IMAGE_URL);
}; };
this.comboBoxSortOrder.ItemsSource = Enum.GetValues(typeof(Extensions.SortOrder)); this.comboBoxSortOrder.ItemsSource = Enum.GetValues(typeof(Extensions.SortOrder));
this.comboBoxSortOrder.SelectedIndex = (int)_sortOrder;
} }
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
@ -190,6 +193,7 @@ namespace BreCalClient
private void buttonInfo_Click(object sender, RoutedEventArgs e) private void buttonInfo_Click(object sender, RoutedEventArgs e)
{ {
AboutDialog ad = new(); AboutDialog ad = new();
ad.LoginResult = this._loginResult;
ad.ChangePasswordRequested += async (oldPw, newPw) => ad.ChangePasswordRequested += async (oldPw, newPw) =>
{ {
if (_loginResult != null) if (_loginResult != null)
@ -200,6 +204,7 @@ namespace BreCalClient
FirstName = _loginResult.FirstName, FirstName = _loginResult.FirstName,
LastName = _loginResult.LastName, LastName = _loginResult.LastName,
UserPhone = _loginResult.UserPhone, UserPhone = _loginResult.UserPhone,
UserEmail = _loginResult.UserEmail,
OldPassword = oldPw, OldPassword = oldPw,
NewPassword = newPw NewPassword = newPw
}; };
@ -293,7 +298,11 @@ namespace BreCalClient
List<Shipcall>? shipcalls = null; List<Shipcall>? shipcalls = null;
try try
{ {
shipcalls = await _api.ShipcallsGetAsync(); if(this.searchPastDays != 0)
shipcalls = await _api.ShipcallsGetAsync(this.searchPastDays);
else
shipcalls = await _api.ShipcallsGetAsync();
this.Dispatcher.Invoke(new Action(() => this.Dispatcher.Invoke(new Action(() =>
{ {
labelGeneralStatus.Text = $"Connection {ConnectionStatus.SUCCESSFUL}"; labelGeneralStatus.Text = $"Connection {ConnectionStatus.SUCCESSFUL}";
@ -374,8 +383,16 @@ namespace BreCalClient
Shipcall shipcall = scm.Shipcall; Shipcall shipcall = scm.Shipcall;
if (BreCalLists.ShipLookupDict.ContainsKey(shipcall.ShipId)) if (BreCalLists.ShipLookupDict.ContainsKey(shipcall.ShipId))
scm.Ship = BreCalLists.ShipLookupDict[shipcall.ShipId]; scm.Ship = BreCalLists.ShipLookupDict[shipcall.ShipId];
if (BreCalLists.BerthLookupDict.ContainsKey(shipcall.ArrivalBerthId ?? 0)) if (shipcall.Type == 1)
scm.Berth = BreCalLists.BerthLookupDict[shipcall.ArrivalBerthId ?? 0].Name; {
if (BreCalLists.BerthLookupDict.ContainsKey(shipcall.ArrivalBerthId ?? 0))
scm.Berth = BreCalLists.BerthLookupDict[shipcall.ArrivalBerthId ?? 0].Name;
}
else
{
if (BreCalLists.BerthLookupDict.ContainsKey(shipcall.DepartureBerthId ?? 0))
scm.Berth = BreCalLists.BerthLookupDict[shipcall.DepartureBerthId ?? 0].Name;
}
scm.AssignParticipants(); scm.AssignParticipants();
this.Dispatcher.Invoke(() => this.Dispatcher.Invoke(() =>
@ -399,8 +416,16 @@ namespace BreCalClient
Shipcall shipcall = scm.Shipcall; Shipcall shipcall = scm.Shipcall;
if (BreCalLists.ShipLookupDict.ContainsKey(shipcall.ShipId)) if (BreCalLists.ShipLookupDict.ContainsKey(shipcall.ShipId))
scm.Ship = BreCalLists.ShipLookupDict[shipcall.ShipId]; scm.Ship = BreCalLists.ShipLookupDict[shipcall.ShipId];
if (BreCalLists.BerthLookupDict.ContainsKey(shipcall.ArrivalBerthId ?? 0)) if (shipcall.Type == 1)
scm.Berth = BreCalLists.BerthLookupDict[shipcall.ArrivalBerthId ?? 0].Name; {
if (BreCalLists.BerthLookupDict.ContainsKey(shipcall.ArrivalBerthId ?? 0))
scm.Berth = BreCalLists.BerthLookupDict[shipcall.ArrivalBerthId ?? 0].Name;
}
else
{
if (BreCalLists.BerthLookupDict.ContainsKey(shipcall.DepartureBerthId ?? 0))
scm.Berth = BreCalLists.BerthLookupDict[shipcall.DepartureBerthId ?? 0].Name;
}
scm.AssignParticipants(); scm.AssignParticipants();
} }
@ -422,6 +447,21 @@ namespace BreCalClient
{ {
SearchFilterModel sfm = this.searchFilterControl.SearchFilter; SearchFilterModel sfm = this.searchFilterControl.SearchFilter;
if( sfm.EtaFrom.HasValue && sfm.EtaFrom < DateTime.Now.AddDays(-2))
{
int daysInThePast = (int)Math.Ceiling((DateTime.Now - sfm.EtaFrom.Value).TotalDays);
if (this.searchPastDays != daysInThePast)
{
this.searchPastDays = daysInThePast;
_refreshImmediately = true; // set flag to avoid timer loop termination
_tokenSource.Cancel(); // force timer loop end
}
}
else
{
searchPastDays = 0;
}
this._visibleControlModels.Clear(); this._visibleControlModels.Clear();
// first add everything // first add everything
this._visibleControlModels.AddRange(_allShipcallsDict.Values); this._visibleControlModels.AddRange(_allShipcallsDict.Values);
@ -480,31 +520,28 @@ namespace BreCalClient
{ {
_ = this._visibleControlModels.RemoveAll(x => x.Shipcall?.Canceled ?? false); _ = this._visibleControlModels.RemoveAll(x => x.Shipcall?.Canceled ?? false);
} }
if (this._sortOrder != null) switch(this._sortOrder)
{ {
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); });
case Extensions.SortOrder.SHIP_NAME: break;
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); }); case Extensions.SortOrder.MODIFIED:
break; 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); });
case Extensions.SortOrder.MODIFIED: break;
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); }); case Extensions.SortOrder.ETA_ETD:
break; this._visibleControlModels.Sort((x, y) =>
case Extensions.SortOrder.ETA_ETD: {
this._visibleControlModels.Sort((x, y) => if (x.Shipcall == null) return 0;
{ if (y.Shipcall == null) return 0;
if (x.Shipcall == null) return 0; DateTime xDate = (x.Shipcall.Type == (int) Extensions.TypeEnum.Incoming) ? x.Shipcall.Eta ?? DateTime.Now : x.Shipcall.Etd ?? DateTime.Now;
if (y.Shipcall == null) return 0; DateTime yDate = (y.Shipcall.Type == (int) Extensions.TypeEnum.Incoming) ? y.Shipcall.Eta ?? DateTime.Now : y.Shipcall.Etd ?? DateTime.Now;
DateTime xDate = (x.Shipcall.Type == (int) Extensions.TypeEnum.Incoming) ? x.Shipcall.Eta ?? DateTime.Now : x.Shipcall.Etd ?? DateTime.Now; return DateTime.Compare(xDate, yDate);
DateTime yDate = (y.Shipcall.Type == (int) Extensions.TypeEnum.Incoming) ? y.Shipcall.Eta ?? DateTime.Now : y.Shipcall.Etd ?? DateTime.Now; });
return DateTime.Compare(xDate, yDate); break;
}); default:
break; break;
default: }
break;
}
}
} }

View File

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

View File

@ -5,7 +5,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<ApplicationRevision>0</ApplicationRevision> <ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>0.9.3.0</ApplicationVersion> <ApplicationVersion>0.9.5.0</ApplicationVersion>
<BootstrapperEnabled>False</BootstrapperEnabled> <BootstrapperEnabled>False</BootstrapperEnabled>
<Configuration>Release</Configuration> <Configuration>Release</Configuration>
<CreateWebPageOnPublish>True</CreateWebPageOnPublish> <CreateWebPageOnPublish>True</CreateWebPageOnPublish>
@ -19,12 +19,12 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<MapFileExtensions>True</MapFileExtensions> <MapFileExtensions>True</MapFileExtensions>
<OpenBrowserOnPublish>False</OpenBrowserOnPublish> <OpenBrowserOnPublish>False</OpenBrowserOnPublish>
<Platform>Any CPU</Platform> <Platform>Any CPU</Platform>
<PublishDir>bin\Release\net6.0-windows\app.publish\</PublishDir> <PublishDir>bin\Release\net6.0-windows\win-x64\app.publish\</PublishDir>
<PublishUrl>bin\publish\</PublishUrl> <PublishUrl>bin\publish\</PublishUrl>
<PublishProtocol>ClickOnce</PublishProtocol> <PublishProtocol>ClickOnce</PublishProtocol>
<PublishReadyToRun>False</PublishReadyToRun> <PublishReadyToRun>False</PublishReadyToRun>
<PublishSingleFile>False</PublishSingleFile> <PublishSingleFile>True</PublishSingleFile>
<SelfContained>False</SelfContained> <SelfContained>True</SelfContained>
<SignatureAlgorithm>(none)</SignatureAlgorithm> <SignatureAlgorithm>(none)</SignatureAlgorithm>
<SignManifests>False</SignManifests> <SignManifests>False</SignManifests>
<TargetFramework>net6.0-windows</TargetFramework> <TargetFramework>net6.0-windows</TargetFramework>
@ -38,11 +38,18 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<PublisherName>Informatikbüro Daniel Schick</PublisherName> <PublisherName>Informatikbüro Daniel Schick</PublisherName>
<SuiteName>Bremen calling client</SuiteName> <SuiteName>Bremen calling client</SuiteName>
<SupportUrl>https://www.bsmd-emswe.eu/</SupportUrl> <SupportUrl>https://www.bsmd-emswe.eu/</SupportUrl>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<SkipPublishVerification>false</SkipPublishVerification>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<BootstrapperPackage Include="Microsoft.NetCore.DesktopRuntime.6.0.x64"> <PublishFile Include="containership.ico">
<Install>true</Install> <Group>
<ProductName>.NET Desktop Runtime 6.0.16 (x64)</ProductName> </Group>
</BootstrapperPackage> <TargetPath>
</TargetPath>
<PublishState>Include</PublishState>
<IncludeHash>true</IncludeHash>
<FileType>File</FileType>
</PublishFile>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

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

View File

@ -34,7 +34,7 @@ namespace BreCalClient.Properties {
[global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("#751D1F")] [global::System.Configuration.DefaultSettingValueAttribute("#1D751F")]
public string BG_COLOR { public string BG_COLOR {
get { get {
return ((string)(this["BG_COLOR"])); return ((string)(this["BG_COLOR"]));

View File

@ -6,7 +6,7 @@
<Value Profile="(Default)">https://brecal.bsmd-emswe.eu</Value> <Value Profile="(Default)">https://brecal.bsmd-emswe.eu</Value>
</Setting> </Setting>
<Setting Name="BG_COLOR" Type="System.String" Scope="Application"> <Setting Name="BG_COLOR" Type="System.String" Scope="Application">
<Value Profile="(Default)">#751D1F</Value> <Value Profile="(Default)">#1D751F</Value>
</Setting> </Setting>
<Setting Name="APP_TITLE" Type="System.String" Scope="Application"> <Setting Name="APP_TITLE" Type="System.String" Scope="Application">
<Value Profile="(Default)">!!Bremen calling Testversion!!</Value> <Value Profile="(Default)">!!Bremen calling Testversion!!</Value>

View File

@ -346,6 +346,15 @@ namespace BreCalClient.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Update contact info.
/// </summary>
public static string textChangeContactInfo {
get {
return ResourceManager.GetString("textChangeContactInfo", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Change password. /// Looks up a localized string similar to Change password.
/// </summary> /// </summary>
@ -436,6 +445,15 @@ namespace BreCalClient.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to E-mail.
/// </summary>
public static string textEmail {
get {
return ResourceManager.GetString("textEmail", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Enter keyword. /// Looks up a localized string similar to Enter keyword.
/// </summary> /// </summary>
@ -661,6 +679,15 @@ namespace BreCalClient.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Phone.
/// </summary>
public static string textPhone {
get {
return ResourceManager.GetString("textPhone", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Pier side. /// Looks up a localized string similar to Pier side.
/// </summary> /// </summary>

View File

@ -406,4 +406,13 @@
<data name="textWidth" xml:space="preserve"> <data name="textWidth" xml:space="preserve">
<value>Breite</value> <value>Breite</value>
</data> </data>
<data name="textChangeContactInfo" xml:space="preserve">
<value>Kontaktdaten bearbeiten</value>
</data>
<data name="textEmail" xml:space="preserve">
<value>E-Mail</value>
</data>
<data name="textPhone" xml:space="preserve">
<value>Telefon</value>
</data>
</root> </root>

View File

@ -208,6 +208,9 @@
<data name="textChange" xml:space="preserve"> <data name="textChange" xml:space="preserve">
<value>Change</value> <value>Change</value>
</data> </data>
<data name="textChangeContactInfo" xml:space="preserve">
<value>Update contact info</value>
</data>
<data name="textChangePassword" xml:space="preserve"> <data name="textChangePassword" xml:space="preserve">
<value>Change password</value> <value>Change password</value>
</data> </data>
@ -238,6 +241,9 @@
<data name="textEditTimes" xml:space="preserve"> <data name="textEditTimes" xml:space="preserve">
<value>Edit times</value> <value>Edit times</value>
</data> </data>
<data name="textEmail" xml:space="preserve">
<value>E-mail</value>
</data>
<data name="textEnterKeyword" xml:space="preserve"> <data name="textEnterKeyword" xml:space="preserve">
<value>Enter keyword</value> <value>Enter keyword</value>
</data> </data>
@ -313,6 +319,9 @@
<data name="textPasswordChanged" xml:space="preserve"> <data name="textPasswordChanged" xml:space="preserve">
<value>Password changed.</value> <value>Password changed.</value>
</data> </data>
<data name="textPhone" xml:space="preserve">
<value>Phone</value>
</data>
<data name="textPierside" xml:space="preserve"> <data name="textPierside" xml:space="preserve">
<value>Pier side</value> <value>Pier side</value>
</data> </data>

View File

@ -5,7 +5,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:p = "clr-namespace:BreCalClient.Resources" xmlns:p = "clr-namespace:BreCalClient.Resources"
xmlns:sets="clr-namespace:BreCalClient.Properties" xmlns:sets="clr-namespace:BreCalClient.Properties"
xmlns:db="clr-namespace:BreCalClient;assembly=BreCalTestClient" xmlns:db="clr-namespace:BreCalClient;assembly=BreCalDevelClient"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="120" d:DesignWidth="800" Loaded="UserControl_Loaded"> d:DesignHeight="120" d:DesignWidth="800" Loaded="UserControl_Loaded">
<Border BorderBrush="LightGray" Margin="1" BorderThickness="1"> <Border BorderBrush="LightGray" Margin="1" BorderThickness="1">
@ -106,17 +106,18 @@
<ColumnDefinition Width="0.7*" /> <ColumnDefinition Width="0.7*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="14" />
<RowDefinition Height="20" /> <RowDefinition Height="20" />
<RowDefinition Height=".5*" /> <RowDefinition Height=".5*" />
<RowDefinition Height="14" />
<RowDefinition Height=".5*" /> <RowDefinition Height=".5*" />
</Grid.RowDefinitions> </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" x:Name="labelETAETDAgent" Padding="0" VerticalContentAlignment="Center" /> <Label Grid.Row="0" Grid.Column="0" Content = "ETA" x:Name="labelETAETDAgent" Padding="0" VerticalContentAlignment="Center" />
<Label Grid.Row="2" Grid.Column="0" Content="{x:Static p:Resources.textRemarks}" Padding="0" VerticalContentAlignment="Center" FontSize="9"/> <Label Grid.Row="1" Grid.Column="0" 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="11" FontWeight="SemiBold" /> <Label Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Content="{x:Static p:Resources.textBerth}" Padding="0" VerticalContentAlignment="Center" FontSize="9"/>
<Label Grid.Row="1" Grid.Column="1" Padding="0" VerticalContentAlignment="Center" x:Name="labelAgencyETAETDValue" FontWeight="DemiBold"/> <Label Grid.Row="0" Grid.Column="1" Padding="0" VerticalContentAlignment="Center" x:Name="labelAgencyETAETDValue" FontWeight="DemiBold"/>
<TextBlock Grid.Row="2" Grid.Column="1" Grid.RowSpan="1" Padding="0" TextWrapping="Wrap" VerticalAlignment="Top" x:Name="textBlockAgencyRemarks" FontSize="10"/> <TextBlock Grid.Row="1" Grid.Column="1" Grid.RowSpan="1" Padding="0" TextWrapping="Wrap" VerticalAlignment="Top" x:Name="textBlockAgencyRemarks" FontSize="10"/>
<Label Grid.Row="2" Grid.Column="1" HorizontalContentAlignment="Left" x:Name="labelAgencyBerth" Padding="0" VerticalContentAlignment="Center" FontSize="11" FontWeight="SemiBold" />
<TextBlock Grid.Row="3" Grid.Column="0" Text="{x:Static p:Resources.textBerthRemarks}" Padding="0" VerticalAlignment="Top" TextWrapping="Wrap" FontSize="9"/> <TextBlock Grid.Row="3" Grid.Column="0" Text="{x:Static p:Resources.textBerthRemarks}" Padding="0" VerticalAlignment="Top" TextWrapping="Wrap" FontSize="9"/>
<TextBlock Grid.Row="3" Grid.Column="1" Grid.RowSpan="1" Padding="0" TextWrapping="Wrap" VerticalAlignment="Top" x:Name="textBlockAgencyBerthRemarks" FontSize="10"/> <TextBlock Grid.Row="3" Grid.Column="1" Grid.RowSpan="1" Padding="0" TextWrapping="Wrap" VerticalAlignment="Top" x:Name="textBlockAgencyBerthRemarks" FontSize="10"/>
</Grid> </Grid>
@ -198,17 +199,17 @@
<ColumnDefinition Width="0.7*" /> <ColumnDefinition Width="0.7*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="14" />
<RowDefinition Height="20" /> <RowDefinition Height="20" />
<RowDefinition Height=".5*" /> <RowDefinition Height=".5*" />
<RowDefinition Height="14" />
<RowDefinition Height=".5*" /> <RowDefinition Height=".5*" />
</Grid.RowDefinitions> </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="0" Grid.Column="0" Content="{x:Static p:Resources.textOperationsStart}" x:Name="labelETAETDTerminal" Padding="0" VerticalContentAlignment="Center" FontSize="9"/>
<Label Grid.Row="0" Grid.Column="1" HorizontalContentAlignment="Left" x:Name="labelTerminalBerth" Padding="0" VerticalContentAlignment="Center" FontSize="11" FontWeight="SemiBold" /> <Label Grid.Row="0" Grid.Column="1" Padding="0" VerticalContentAlignment="Center" x:Name="labelOperationsStart" FontWeight="DemiBold"/>
<Label Grid.Row="1" Grid.Column="0" Content="{x:Static p:Resources.textOperationsStart}" x:Name="labelETAETDTerminal" Padding="0" VerticalContentAlignment="Center" FontSize="9"/> <Label Grid.Row="1" Grid.Column="0" Content="{x:Static p:Resources.textRemarks}" Padding="0" VerticalContentAlignment="Top" FontSize="9"/>
<Label Grid.Row="1" Grid.Column="1" Padding="0" VerticalContentAlignment="Center" x:Name="labelOperationsStart" FontWeight="DemiBold"/> <TextBlock Grid.Row="1" Grid.Column="1" Padding="0" TextWrapping="Wrap" VerticalAlignment="Top" x:Name="textBlockTerminalRemarks" FontSize="10"/>
<Label Grid.Row="2" Grid.Column="0" Content="{x:Static p:Resources.textRemarks}" Padding="0" VerticalContentAlignment="Top" FontSize="9"/> <Label Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Content="{x:Static p:Resources.textBerth}" Padding="0" VerticalContentAlignment="Center" FontSize="9"/>
<TextBlock Grid.Row="2" Grid.Column="1" Padding="0" TextWrapping="Wrap" VerticalAlignment="Top" x:Name="textBlockTerminalRemarks" FontSize="10"/> <Label Grid.Row="2" Grid.Column="1" HorizontalContentAlignment="Left" x:Name="labelTerminalBerth" Padding="0" VerticalContentAlignment="Center" FontSize="11" FontWeight="SemiBold" />
<TextBlock Grid.Row="3" Grid.Column="0" Text="{x:Static p:Resources.textBerthRemarks}" TextWrapping="Wrap" Padding="0" VerticalAlignment="Top" FontSize="9"/> <TextBlock Grid.Row="3" Grid.Column="0" Text="{x:Static p:Resources.textBerthRemarks}" TextWrapping="Wrap" Padding="0" VerticalAlignment="Top" FontSize="9"/>
<TextBlock Grid.Row="3" Grid.Column="1" Padding="0" TextWrapping="Wrap" VerticalAlignment="Top" x:Name="textBlockTerminalBerthRemarks" FontSize="10"/> <TextBlock Grid.Row="3" Grid.Column="1" Padding="0" TextWrapping="Wrap" VerticalAlignment="Top" x:Name="textBlockTerminalBerthRemarks" FontSize="10"/>
</Grid> </Grid>

View File

@ -139,13 +139,13 @@ namespace BreCalClient
switch (this.ShipcallControlModel?.Shipcall?.Type) switch (this.ShipcallControlModel?.Shipcall?.Type)
{ {
case 1: // incoming case 1: // incoming
this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalTestClient;component/Resources/arrow_down_red.png")); this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalDevelClient;component/Resources/arrow_down_red.png"));
break; break;
case 2: // outgoing case 2: // outgoing
this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalTestClient;component/Resources/arrow_up_blue.png")); this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalDevelClient;component/Resources/arrow_up_blue.png"));
break; break;
case 3: // shifting case 3: // shifting
this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalTestClient;component/Resources/arrow_right_green.png")); this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalDevelClient;component/Resources/arrow_right_green.png"));
break; break;
default: default:
break; break;
@ -154,13 +154,13 @@ namespace BreCalClient
switch(this.ShipcallControlModel?.LightMode) switch(this.ShipcallControlModel?.LightMode)
{ {
case ShipcallControlModel.TrafficLightMode.GREEN: case ShipcallControlModel.TrafficLightMode.GREEN:
this.imageEvaluation.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalTestClient;component/Resources/check.png")); this.imageEvaluation.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalDevelClient;component/Resources/check.png"));
break; break;
case ShipcallControlModel.TrafficLightMode.YELLOW: case ShipcallControlModel.TrafficLightMode.YELLOW:
this.imageEvaluation.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalTestClient;component/Resources/sign_warning.png")); this.imageEvaluation.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalDevelClient;component/Resources/sign_warning.png"));
break; break;
case ShipcallControlModel.TrafficLightMode.RED: case ShipcallControlModel.TrafficLightMode.RED:
this.imageEvaluation.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalTestClient;component/Resources/delete2.png")); this.imageEvaluation.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalDevelClient;component/Resources/delete2.png"));
break; break;
default: default:
break; break;
@ -191,11 +191,11 @@ namespace BreCalClient
this.textBlockBerth.Text = this.ShipcallControlModel?.Berth; this.textBlockBerth.Text = this.ShipcallControlModel?.Berth;
this.textBlockCallsign.Text = this.ShipcallControlModel?.Ship?.Callsign; this.textBlockCallsign.Text = this.ShipcallControlModel?.Ship?.Callsign;
if ((this.ShipcallControlModel?.Shipcall?.Type == 1) || (this.ShipcallControlModel?.Shipcall?.Type == 3)) if (this.ShipcallControlModel?.Shipcall?.Type == 1)
{ {
this.textBlockETA.Text = this.ShipcallControlModel?.Shipcall?.Eta?.ToString("dd.MM. HH:mm"); this.textBlockETA.Text = this.ShipcallControlModel?.Shipcall?.Eta?.ToString("dd.MM. HH:mm");
} }
if (this.ShipcallControlModel?.Shipcall?.Type == 2) if ((this.ShipcallControlModel?.Shipcall?.Type == 2) || (this.ShipcallControlModel?.Shipcall?.Type == 3))
{ {
this.labelETA.Text = "ETD"; this.labelETA.Text = "ETD";
this.textBlockETA.Text = this.ShipcallControlModel?.Shipcall?.Etd?.ToString("dd.MM. HH:mm"); this.textBlockETA.Text = this.ShipcallControlModel?.Shipcall?.Etd?.ToString("dd.MM. HH:mm");
@ -222,21 +222,21 @@ namespace BreCalClient
foreach (Times times in this.ShipcallControlModel.Times) foreach (Times times in this.ShipcallControlModel.Times)
{ {
string? berthText = null; string? berthText = null;
if ((BreCalLists.Berths != null) && times.BerthId.HasValue) if ((BreCalLists.Berths != null) && times.BerthId.HasValue && (this.ShipcallControlModel?.Shipcall?.Type != (int) Extensions.TypeEnum.Shifting))
{ {
Berth? berth = BreCalLists.Berths.Find((x) => x.Id == times.BerthId); Berth? berth = BreCalLists.Berths.Find((x) => x.Id == times.BerthId);
berthText = berth?.Name; berthText = berth?.Name;
} }
if (berthText == null) if (berthText == null)
{ {
if (this.ShipcallControlModel?.Shipcall?.Type == (int)Extensions.TypeEnum.Outgoing) if (this.ShipcallControlModel?.Shipcall?.Type == (int)Extensions.TypeEnum.Incoming)
{ {
Berth? berth = BreCalLists.Berths?.Find((x) => x.Id == this.ShipcallControlModel.Shipcall?.DepartureBerthId); Berth? berth = BreCalLists.Berths?.Find((x) => x.Id == this.ShipcallControlModel.Shipcall?.ArrivalBerthId);
berthText = berth?.Name; berthText = berth?.Name;
} }
else else
{ {
Berth? berth = BreCalLists.Berths?.Find((x) => x.Id == this.ShipcallControlModel?.Shipcall?.ArrivalBerthId); Berth? berth = BreCalLists.Berths?.Find((x) => x.Id == this.ShipcallControlModel?.Shipcall?.DepartureBerthId);
berthText = berth?.Name; berthText = berth?.Name;
} }
} }

View File

@ -8,7 +8,7 @@
<applicationSettings> <applicationSettings>
<RoleEditor.Properties.Settings> <RoleEditor.Properties.Settings>
<setting name="ConnectionString" serializeAs="String"> <setting name="ConnectionString" serializeAs="String">
<value>Server=localhost;User ID=ds;Password=HalloWach_2323XXL!!;Database=bremen_calling;Port=33306</value> <value>Server=localhost;User ID=ds;Password=HalloWach_2323XXL!!;Database=bremen_calling_devel;Port=33306</value>
</setting> </setting>
</RoleEditor.Properties.Settings> </RoleEditor.Properties.Settings>
</applicationSettings> </applicationSettings>

View File

@ -6,7 +6,7 @@
xmlns:local="clr-namespace:RoleEditor" xmlns:local="clr-namespace:RoleEditor"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit" xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
mc:Ignorable="d" mc:Ignorable="d"
Title="Bremen calling admin editor" Height="650" Width="800" Icon="Resources/lock_preferences.ico" Loaded="Window_Loaded"> Title="Bremen calling admin editor" Height="670" Width="800" Icon="Resources/lock_preferences.ico" Loaded="Window_Loaded">
<Grid> <Grid>
<TabControl> <TabControl>
<TabItem Header="Participant, users and roles"> <TabItem Header="Participant, users and roles">
@ -121,19 +121,23 @@
<Label Grid.Row="1" Grid.Column="1" Content="Last name" HorizontalAlignment="Right"/> <Label Grid.Row="1" Grid.Column="1" Content="Last name" HorizontalAlignment="Right"/>
<Label Grid.Row="2" Grid.Column="1" Content="User name" HorizontalAlignment="Right"/> <Label Grid.Row="2" Grid.Column="1" Content="User name" HorizontalAlignment="Right"/>
<Label Grid.Row="3" Grid.Column="1" Content="Password" HorizontalAlignment="Right"/> <Label Grid.Row="3" Grid.Column="1" Content="Password" HorizontalAlignment="Right"/>
<Label Grid.Row="4" Grid.Column="1" Content="API Key" HorizontalAlignment="Right"/> <Label Grid.Row="4" Grid.Column="1" Content="E-Mail" HorizontalAlignment="Right" />
<Label Content="Created" Grid.Row="5" Grid.Column="1" HorizontalAlignment="Right"/> <Label Grid.Row="5" Grid.Column="1" Content="Phone" HorizontalAlignment="Right" />
<Label Content="Modified" Grid.Row="6" Grid.Column="1" HorizontalAlignment="Right"/> <Label Grid.Row="6" Grid.Column="1" Content="API Key" HorizontalAlignment="Right"/>
<Label Content="Created" Grid.Row="7" Grid.Column="1" HorizontalAlignment="Right"/>
<Label Content="Modified" Grid.Row="8" Grid.Column="1" HorizontalAlignment="Right"/>
<TextBox x:Name="textBoxUserFirstName" Grid.Row="0" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" /> <TextBox x:Name="textBoxUserFirstName" Grid.Row="0" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" />
<TextBox x:Name="textBoxUserLastName" Grid.Row="1" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" /> <TextBox x:Name="textBoxUserLastName" Grid.Row="1" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" />
<TextBox x:Name="textBoxUserUserName" Grid.Row="2" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" /> <TextBox x:Name="textBoxUserUserName" Grid.Row="2" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" />
<TextBox x:Name="textBoxUserPassword" Grid.Row="3" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" /> <TextBox x:Name="textBoxUserPassword" Grid.Row="3" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" />
<TextBox x:Name="textBoxUserAPIKey" Grid.Row="4" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" /> <TextBox x:Name="textBoxUserEMail" Grid.Row="4" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" />
<TextBox x:Name="textBoxUserCreated" Grid.Row="5" IsReadOnly="True" IsEnabled="False" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" /> <TextBox x:Name="textBoxUserPhone" Grid.Row="5" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" />
<TextBox x:Name="textBoxUserModified" Grid.Row="6" IsReadOnly="True" IsEnabled="False" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" /> <TextBox x:Name="textBoxUserAPIKey" Grid.Row="6" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" />
<TextBox x:Name="textBoxUserCreated" Grid.Row="7" IsReadOnly="True" IsEnabled="False" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" />
<TextBox x:Name="textBoxUserModified" Grid.Row="8" IsReadOnly="True" IsEnabled="False" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" />
<Button x:Name="buttonUserSave" Grid.Row="7" Grid.Column="2" Click="buttonUserSave_Click" Margin="2"> <Button x:Name="buttonUserSave" Grid.Row="9" Grid.Column="2" Click="buttonUserSave_Click" Margin="2">
<DockPanel> <DockPanel>
<Image Source="./Resources/disk_blue.png" Margin="0,0,5,0" Height="24" DockPanel.Dock="Left" Width="16"/> <Image Source="./Resources/disk_blue.png" Margin="0,0,5,0" Height="24" DockPanel.Dock="Left" Width="16"/>
<TextBlock Text="Save" VerticalAlignment="Center" DockPanel.Dock="Right"/> <TextBlock Text="Save" VerticalAlignment="Center" DockPanel.Dock="Right"/>

View File

@ -253,6 +253,8 @@ namespace RoleEditor
u.Firstname = this.textBoxUserFirstName.Text.Trim(); u.Firstname = this.textBoxUserFirstName.Text.Trim();
u.Lastname = this.textBoxUserLastName.Text.Trim(); u.Lastname = this.textBoxUserLastName.Text.Trim();
u.Username = this.textBoxUserUserName.Text.Trim(); u.Username = this.textBoxUserUserName.Text.Trim();
u.EMail = this.textBoxUserEMail.Text.Trim();
u.Phone = this.textBoxUserPhone.Text.Trim();
if(this.textBoxUserPassword.Text.Trim().Length > 0 ) if(this.textBoxUserPassword.Text.Trim().Length > 0 )
{ {
string passwortText = this.textBoxUserPassword.Text.Trim(); string passwortText = this.textBoxUserPassword.Text.Trim();
@ -455,6 +457,8 @@ namespace RoleEditor
this.textBoxUserFirstName.Text = (u != null) ? u.Firstname : string.Empty; this.textBoxUserFirstName.Text = (u != null) ? u.Firstname : string.Empty;
this.textBoxUserLastName.Text = (u != null) ? u.Lastname : string.Empty; this.textBoxUserLastName.Text = (u != null) ? u.Lastname : string.Empty;
this.textBoxUserUserName.Text = (u != null) ? u.Username : string.Empty; this.textBoxUserUserName.Text = (u != null) ? u.Username : string.Empty;
this.textBoxUserEMail.Text = (u != null) ? u.EMail : string.Empty;
this.textBoxUserPhone.Text = (u != null) ? u.Phone : string.Empty;
this.textBoxUserAPIKey.Text = (u != null) ? u.APIKey : string.Empty; this.textBoxUserAPIKey.Text = (u != null) ? u.APIKey : string.Empty;
this.textBoxUserCreated.Text = (u != null) ? u.Created.ToString() : string.Empty; this.textBoxUserCreated.Text = (u != null) ? u.Created.ToString() : string.Empty;
this.textBoxUserModified.Text = (u != null) ? u.Modified.ToString() : string.Empty; this.textBoxUserModified.Text = (u != null) ? u.Modified.ToString() : string.Empty;

View File

@ -12,6 +12,10 @@ namespace brecal.model
public string Username { get; set; } = ""; public string Username { get; set; } = "";
public string EMail { get; set; } = "";
public string Phone { get; set; } = "";
public string? PasswordHash { get; set; } public string? PasswordHash { get; set; }
public string? APIKey { get; set; } public string? APIKey { get; set; }
@ -33,7 +37,7 @@ namespace brecal.model
public static void SetLoadQuery(IDbCommand cmd, params object?[] args) public static void SetLoadQuery(IDbCommand cmd, params object?[] args)
{ {
cmd.CommandText = "SELECT id, first_name, last_name, user_name, api_key, created, modified FROM user WHERE participant_id = @PID"; cmd.CommandText = "SELECT id, first_name, last_name, user_name, user_email, user_phone, api_key, created, modified FROM user WHERE participant_id = @PID";
if (args.Length != 1 || !(args[0] is Participant)) if (args.Length != 1 || !(args[0] is Participant))
throw new ArgumentException("loader needs single partipant as argument"); throw new ArgumentException("loader needs single partipant as argument");
IDataParameter pid = cmd.CreateParameter(); IDataParameter pid = cmd.CreateParameter();
@ -53,9 +57,11 @@ namespace brecal.model
if (!reader.IsDBNull(1)) u.Firstname = reader.GetString(1); if (!reader.IsDBNull(1)) u.Firstname = reader.GetString(1);
if (!reader.IsDBNull(2)) u.Lastname = reader.GetString(2); if (!reader.IsDBNull(2)) u.Lastname = reader.GetString(2);
if (!reader.IsDBNull(3)) u.Username = reader.GetString(3); if (!reader.IsDBNull(3)) u.Username = reader.GetString(3);
if (!reader.IsDBNull(4)) u.APIKey = reader.GetString(4); if (!reader.IsDBNull(4)) u.EMail = reader.GetString(4);
if (!reader.IsDBNull(5)) u.Created = reader.GetDateTime(5); if (!reader.IsDBNull(5)) u.Phone = reader.GetString(5);
if (!reader.IsDBNull(6)) u.Modified = reader.GetDateTime(6); if (!reader.IsDBNull(6)) u.APIKey = reader.GetString(6);
if (!reader.IsDBNull(7)) u.Created = reader.GetDateTime(7);
if (!reader.IsDBNull(8)) u.Modified = reader.GetDateTime(8);
result.Add(u); result.Add(u);
} }
return result; return result;
@ -68,15 +74,15 @@ namespace brecal.model
public override void SetUpdate(IDbCommand cmd) public override void SetUpdate(IDbCommand cmd)
{ {
if(!string.IsNullOrEmpty(this.PasswordHash)) if(!string.IsNullOrEmpty(this.PasswordHash))
cmd.CommandText = "UPDATE user SET first_name = @FIRSTNAME, last_name = @LASTNAME, user_name = @USERNAME, password_hash = @PWHASH, api_key = @APIKEY WHERE id = @ID"; cmd.CommandText = "UPDATE user SET first_name = @FIRSTNAME, last_name = @LASTNAME, user_name = @USERNAME, password_hash = @PWHASH, api_key = @APIKEY, user_email = @USEREMAIL, user_phone = @USERPHONE WHERE id = @ID";
else else
cmd.CommandText = "UPDATE user SET first_name = @FIRSTNAME, last_name = @LASTNAME, user_name = @USERNAME, api_key = @APIKEY WHERE id = @ID"; cmd.CommandText = "UPDATE user SET first_name = @FIRSTNAME, last_name = @LASTNAME, user_name = @USERNAME, api_key = @APIKEY, user_email = @USEREMAIL, user_phone = @USERPHONE WHERE id = @ID";
this.SetParameters(cmd); this.SetParameters(cmd);
} }
public override void SetCreate(IDbCommand cmd) public override void SetCreate(IDbCommand cmd)
{ {
cmd.CommandText = "INSERT INTO user (participant_id, first_name, last_name, user_name, password_hash, api_key) VALUES ( @PID, @FIRSTNAME, @LASTNAME, @USERNAME, @PWHASH, @APIKEY)"; cmd.CommandText = "INSERT INTO user (participant_id, first_name, last_name, user_name, password_hash, api_key, user_email, user_phone) VALUES ( @PID, @FIRSTNAME, @LASTNAME, @USERNAME, @PWHASH, @APIKEY, @USEREMAIL, @USERPHONE)";
this.SetParameters(cmd); this.SetParameters(cmd);
} }
@ -126,6 +132,16 @@ namespace brecal.model
username.Value = this.Username; username.Value = this.Username;
cmd.Parameters.Add(username); cmd.Parameters.Add(username);
IDbDataParameter email = cmd.CreateParameter();
email.ParameterName = "USEREMAIL";
email.Value = this.EMail;
cmd.Parameters.Add(email);
IDbDataParameter phone = cmd.CreateParameter();
phone.ParameterName = "USERPHONE";
phone.Value = this.Phone;
cmd.Parameters.Add(phone);
IDbDataParameter pwhash = cmd.CreateParameter(); IDbDataParameter pwhash = cmd.CreateParameter();
pwhash.ParameterName = "PWHASH"; pwhash.ParameterName = "PWHASH";
pwhash.Value = this.PasswordHash; pwhash.Value = this.PasswordHash;

View File

@ -17,6 +17,7 @@ def GetShipcalls():
token = request.headers.get('Authorization') token = request.headers.get('Authorization')
options = {} options = {}
options["participant_id"] = request.args.get("participant_id") options["participant_id"] = request.args.get("participant_id")
options["past_days"] = request.args.get("past_days", default=2, type=int)
return impl.shipcalls.GetShipcalls(options) return impl.shipcalls.GetShipcalls(options)
else: else:

View File

@ -15,7 +15,7 @@ def GetBerths(token):
try: try:
pooledConnection = local_db.getPoolConnection() pooledConnection = local_db.getPoolConnection()
commands = pydapper.using(pooledConnection) commands = pydapper.using(pooledConnection)
data = commands.query("SELECT id, name, participant_id, `lock`, owner_id, authority_id, created, modified, deleted FROM berth WHERE deleted = 0 ORDER BY name", model=model.Berth) data = commands.query("SELECT id, name, `lock`, owner_id, authority_id, created, modified, deleted FROM berth WHERE deleted = 0 ORDER BY name", model=model.Berth)
pooledConnection.close() pooledConnection.close()
except Exception as ex: except Exception as ex:

View File

@ -26,7 +26,8 @@ def GetUser(options):
"first_name": data[0].first_name, "first_name": data[0].first_name,
"last_name": data[0].last_name, "last_name": data[0].last_name,
"user_name": data[0].user_name, "user_name": data[0].user_name,
"user_phone": data[0].user_phone "user_phone": data[0].user_phone,
"user_email": data[0].user_email
} }
token = jwt_handler.generate_jwt(payload=result, lifetime=120) # 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 result["token"] = token # add token to user data

View File

@ -19,10 +19,13 @@ def GetShipcalls(options):
pooledConnection = local_db.getPoolConnection() pooledConnection = local_db.getPoolConnection()
commands = pydapper.using(pooledConnection) 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, " + 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, " + "flags, pier_side, bunkering, replenishing_terminal, replenishing_lock, draft, tidal_window_from, tidal_window_to, rain_sensitive_cargo, recommended_tugs, "
"anchored, moored_lock, canceled, evaluation, evaluation_message, 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 ((type = 1 OR type = 3) AND eta >= DATE(NOW() - INTERVAL %d DAY)"
"ORDER BY eta", model=model.Shipcall) "OR (type = 2 AND etd >= DATE(NOW() - INTERVAL %d DAY))) "
"ORDER BY eta") % (options["past_days"], options["past_days"])
data = commands.query(query, model=model.Shipcall)
for shipcall in data: for shipcall in data:
participant_query = "SELECT participant_id, type FROM shipcall_participant_map WHERE shipcall_id=?shipcall_id?"; participant_query = "SELECT participant_id, type FROM shipcall_participant_map WHERE shipcall_id=?shipcall_id?";
for record in commands.query(participant_query, model=dict, param={"shipcall_id" : shipcall.id}, buffered=False): for record in commands.query(participant_query, model=dict, param={"shipcall_id" : shipcall.id}, buffered=False):

View File

@ -27,7 +27,7 @@ def PutUser(schemaModel):
return json.dumps("no such record"), 404, {'Content-Type': 'application/json; charset=utf-8'} return json.dumps("no such record"), 404, {'Content-Type': 'application/json; charset=utf-8'}
# see if we need to update public fields # see if we need to update public fields
if "first_name" in schemaModel or "last_name" in schemaModel or "user_phone" in schemaModel: if "first_name" in schemaModel or "last_name" in schemaModel or "user_phone" in schemaModel or "user_email" in schemaModel:
query = "UPDATE user SET " query = "UPDATE user SET "
isNotFirst = False isNotFirst = False
for key in schemaModel.keys(): for key in schemaModel.keys():

View File

@ -10,7 +10,7 @@ def initPool(instancePath):
try: try:
global config_path global config_path
if(config_path == None): if(config_path == None):
config_path = os.path.join(instancePath,'../../../secure/connection_data_test.json'); config_path = os.path.join(instancePath,'../../../secure/connection_data_devel.json');
print (config_path) print (config_path)

View File

@ -179,6 +179,7 @@ class UserSchema(Schema):
first_name = fields.Str(Required=False, allow_none=True) first_name = fields.Str(Required=False, allow_none=True)
last_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) user_phone = fields.Str(required=False, allow_none=True)
user_email = fields.Str(required=False, allow_none=True)
old_password = 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) new_password = fields.Str(required=False, allow_none=True)

View File

@ -7,6 +7,43 @@ from BreCal.validators.time_logic import TimeLogic
from BreCal.database.enums import StatusFlags from BreCal.database.enums import StatusFlags
#from BreCal.validators.schema_validation import validation_state_and_validation_name #from BreCal.validators.schema_validation import validation_state_and_validation_name
# a human interpretable dictionary for error messages. In this case, the English language is preferred
error_message_dict = {
# 0001 A-M
"validation_rule_fct_missing_time_agency_berth_eta":"The shipcall arrives in less than 20 hours, but there are still missing times by the agency. Please add the estimated time of arrival (ETA) {Rule #0001A}", # A
"validation_rule_fct_missing_time_agency_berth_etd":"The shipcall departs in less than 20 hours, but there are still missing times by the agency. Please add the estimated time of departure (ETD) {Rule #0001B}", # B
"validation_rule_fct_missing_time_mooring_berth_eta":"The shipcall arrives in less than 16 hours, but there are still missing times by the mooring. Please add the estimated time of arrival (ETA) {Rule #0001C}", # C
"validation_rule_fct_missing_time_mooring_berth_etd":"The shipcall departs in less than 16 hours, but there are still missing times by the mooring. Please add the estimated time of departure (ETD) {Rule #0001D}", # D
"validation_rule_fct_missing_time_portadministration_berth_eta":"The shipcall arrives in less than 16 hours, but there are still missing times by the port administration. Please add the estimated time of arrival (ETA) {Rule #0001F}", # F
"validation_rule_fct_missing_time_portadministration_berth_etd":"The shipcall departs in less than 16 hours, but there are still missing times by the port administration. Please add the estimated time of departure (ETD) {Rule #0001G}", # G
"validation_rule_fct_missing_time_pilot_berth_eta":"The shipcall arrives in less than 16 hours, but there are still missing times by the pilot. Please add the estimated time of arrival (ETA) {Rule #0001H}", # H
"validation_rule_fct_missing_time_pilot_berth_etd":"The shipcall departs in less than 16 hours, but there are still missing times by the pilot. Please add the estimated time of departure (ETD) {Rule #0001I}", # I
"validation_rule_fct_missing_time_tug_berth_eta":"The shipcall arrives in less than 16 hours, but there are still missing times by the tugs. Please add the estimated time of arrival (ETA) {Rule #0001J}", # J
"validation_rule_fct_missing_time_tug_berth_etd":"The shipcall departs in less than 16 hours, but there are still missing times by the tugs. Please add the estimated time of departure (ETD) {Rule #0001K}", # K
"validation_rule_fct_missing_time_terminal_berth_eta":"The shipcall arrives in less than 16 hours, but there are still missing times by the terminal. Please add the estimated time of arrival (ETA) {Rule #0001L}", # L
"validation_rule_fct_missing_time_terminal_berth_etd":"The shipcall departs in less than 16 hours, but there are still missing times by the terminal. Please add the estimated time of departure (ETD) {Rule #0001M}", # M
# 0002 A+B+C
"validation_rule_fct_shipcall_incoming_participants_disagree_on_eta":"There are deviating times between agency, mooring, port authority, pilot and tug for the estimated time of arrival (ETA) {Rule #0002A}",
"validation_rule_fct_shipcall_outgoing_participants_disagree_on_etd":"There are deviating times between agency, mooring, port authority, pilot and tug for the estimated time of departure (ETD) {Rule #0002B}",
"validation_rule_fct_shipcall_shifting_participants_disagree_on_eta_or_etd":"There are deviating times between agency, mooring, port authority, pilot and tug for ETA and ETD {Rule #0002C}",
# 0003 A+B
"validation_rule_fct_eta_time_not_in_operation_window":"The estimated time of arrival will be AFTER the planned start of operations. {Rule #0003A}",
"validation_rule_fct_etd_time_not_in_operation_window":"The estimated time of departure is supposed to be AFTER the planned end of operations. {Rule #0003D}",
# 0004 A+B
"validation_rule_fct_eta_time_not_in_tidal_window":"The tidal window does not fit to the agency's estimated time of arrival (ETA) {Rule #0004A}",
"validation_rule_fct_etd_time_not_in_tidal_window":"The tidal window does not fit to the agency's estimated time of departure (ETD) {Rule #0004B}",
# 0005 A+B
"validation_rule_fct_too_many_identical_eta_times":"There are more than three ships with the same planned time of arrival (ETA) {Rule #0005A}",
"validation_rule_fct_too_many_identical_etd_times":"There are more than three ships with the same planned time of departure (ETD) {Rule #0005B}",
# 0006 A+B
"validation_rule_fct_agency_and_terminal_berth_id_disagreement":"Agency and Terminal are planning with different berths (the berth_id deviates). {Rule #0006A}",
"validation_rule_fct_agency_and_terminal_pier_side_disagreement":"Agency and Terminal are planning with different pier sides (the pier_side deviates). {Rule #0006B}",
}
class ValidationRuleBaseFunctions(): class ValidationRuleBaseFunctions():
""" """
@ -16,6 +53,16 @@ class ValidationRuleBaseFunctions():
def __init__(self, sql_handler): def __init__(self, sql_handler):
self.sql_handler = sql_handler self.sql_handler = sql_handler
self.time_logic = TimeLogic() self.time_logic = TimeLogic()
self.error_message_dict = error_message_dict
def describe_error_message(self, key)->str:
"""
Takes any error message, which typically is the validation rule's function name and returns a description of the error.
In case that the error code is not defined in self.error_message_dict, return the cryptic error code instead
returns: string
"""
return self.error_message_dict.get(key,key)
def check_time_delta_violation_query_time_to_now(self, query_time:pd.Timestamp, key_time:pd.Timestamp, threshold:float)->bool: def check_time_delta_violation_query_time_to_now(self, query_time:pd.Timestamp, key_time:pd.Timestamp, threshold:float)->bool:
""" """
@ -36,7 +83,7 @@ class ValidationRuleBaseFunctions():
threshold: threshold where a time difference becomes crucial. When the delta is below the threshold, a violation might occur threshold: threshold where a time difference becomes crucial. When the delta is below the threshold, a violation might occur
""" """
# rule is not applicable -> return 'GREEN' # rule is not applicable -> return 'GREEN'
if key_time is not None: if self.check_is_not_a_time_or_is_none(key_time) or self.check_is_not_a_time_or_is_none(query_time):
return False return False
# otherwise, this rule applies and the difference between 'now' and the query time is measured # otherwise, this rule applies and the difference between 'now' and the query time is measured
@ -62,6 +109,8 @@ class ValidationRuleBaseFunctions():
Instead of comparing each individual result, this function counts the amount of unique instances. Instead of comparing each individual result, this function counts the amount of unique instances.
When there is not only one unique value, there are deviating time estimates, and a violation occurs When there is not only one unique value, there are deviating time estimates, and a violation occurs
To reduce the potential of false violations, the agreement is rounded (e.g., by minute).
returns: violation_state (bool) returns: violation_state (bool)
""" """
# shipcall type filter: consider only shipcalls, where the type matches # shipcall type filter: consider only shipcalls, where the type matches
@ -73,19 +122,23 @@ class ValidationRuleBaseFunctions():
participant_types = [ParticipantType.AGENCY.value, ParticipantType.MOORING.value, ParticipantType.PORT_ADMINISTRATION.value, ParticipantType.PILOT.value, ParticipantType.TUG.value] participant_types = [ParticipantType.AGENCY.value, ParticipantType.MOORING.value, ParticipantType.PORT_ADMINISTRATION.value, ParticipantType.PILOT.value, ParticipantType.TUG.value]
df_times = df_times.loc[df_times["participant_type"].isin(participant_types),:] df_times = df_times.loc[df_times["participant_type"].isin(participant_types),:]
# exclude missing entries # exclude missing entries and consider only pd.Timestamp entries (which ignores pd.NaT/null entries)
df_times.loc[~df_times[query].isnull(),:] estimated_times = [time_ for time_ in df_times.loc[:,query].tolist() if isinstance(time_, pd.Timestamp)] # df_times = df_times.loc[~df_times[query].isnull(),:]
# apply rounding. For example, the agreement of different participants may be required to match minute-wise
# '15min' rounds to 'every 15 minutes'. E.g., '2023-09-22 08:18:49' becomes '2023-09-22 08:15:00'
estimated_times = [time_.round("15min") for time_ in estimated_times]
# when there are no entries left (no entries are provided), skip # when there are no entries left (no entries are provided), skip
if len(df_times)==0: if len(estimated_times)==0:
violation_state = False violation_state = False
return violation_state return violation_state
# there should only be one eta_berth, when all participants have provided the same time # there should only be one eta_berth, when all participants have provided the same time
# this equates to the same criteria as checking, whether # this equates to the same criteria as checking, whether
# times_agency.eta_berth==times_mooring.eta_berth==times_portadministration.eta_berth==times_pilot.eta_berth==times_tug.eta_berth # times_agency.eta_berth==times_mooring.eta_berth==times_portadministration.eta_berth==times_pilot.eta_berth==times_tug.eta_berth
unique_times = len(pd.unique(df_times.loc[:,query])) n_unique_times = len(np.unique(estimated_times))
violation_state = unique_times!=1 violation_state = n_unique_times!=1
return violation_state return violation_state
def check_unique_shipcall_counts(self, query:str, rounding="min", maximum_threshold=3)->bool: def check_unique_shipcall_counts(self, query:str, rounding="min", maximum_threshold=3)->bool:
@ -106,6 +159,11 @@ class ValidationRuleBaseFunctions():
violation_state = np.any(np.greater(counts, maximum_threshold)) violation_state = np.any(np.greater(counts, maximum_threshold))
return violation_state return violation_state
def check_is_not_a_time_or_is_none(self, value)->bool:
"""checks, if a provided value is either None or NaT"""
return (value is None) or (value is pd.NaT)
class ValidationRuleFunctions(ValidationRuleBaseFunctions): class ValidationRuleFunctions(ValidationRuleBaseFunctions):
""" """
@ -460,12 +518,12 @@ class ValidationRuleFunctions(ValidationRuleBaseFunctions):
def validation_rule_fct_missing_time_terminal_berth_etd(self, shipcall, df_times, *args, **kwargs): def validation_rule_fct_missing_time_terminal_berth_etd(self, shipcall, df_times, *args, **kwargs):
""" """
Code: #0001-K Code: #0001-M
Type: Local Rule Type: Local Rule
Description: this validation checks, whether there is a missing time. When the difference between an event (e.g., the shipcall eta) is below Description: this validation checks, whether there is a missing time. When the difference between an event (e.g., the shipcall eta) is below
a certain threshold (e.g., 20 hours), a violation occurs a certain threshold (e.g., 20 hours), a violation occurs
0001-K: 0001-M:
- Checks, if times_terminal.etd_berth is filled in. - Checks, if times_terminal.etd_berth is filled in.
- Measures the difference between 'now' and 'times_agency.etd_berth'. - Measures the difference between 'now' and 'times_agency.etd_berth'.
""" """
@ -589,7 +647,7 @@ class ValidationRuleFunctions(ValidationRuleBaseFunctions):
times_agency = self.sql_handler.get_times_for_participant_type(df_times, participant_type=ParticipantType.AGENCY.value) times_agency = self.sql_handler.get_times_for_participant_type(df_times, participant_type=ParticipantType.AGENCY.value)
times_terminal = self.sql_handler.get_times_for_participant_type(df_times, participant_type=ParticipantType.TERMINAL.value) times_terminal = self.sql_handler.get_times_for_participant_type(df_times, participant_type=ParticipantType.TERMINAL.value)
if (times_terminal.operations_end is pd.NaT) or (times_agency.etd_berth is pd.NaT): if self.check_is_not_a_time_or_is_none(times_terminal.operations_start) or self.check_is_not_a_time_or_is_none(times_agency.eta_berth):
return (StatusFlags.GREEN, None) return (StatusFlags.GREEN, None)
# check, whether the start of operations is AFTER the estimated arrival time # check, whether the start of operations is AFTER the estimated arrival time
@ -601,7 +659,7 @@ class ValidationRuleFunctions(ValidationRuleBaseFunctions):
else: else:
return (StatusFlags.GREEN, None) return (StatusFlags.GREEN, None)
def validation_rule_fct_eta_time_not_in_operation_window(self, shipcall, df_times, *args, **kwargs): def validation_rule_fct_etd_time_not_in_operation_window(self, shipcall, df_times, *args, **kwargs):
""" """
Code: #0003-B Code: #0003-B
Type: Local Rule Type: Local Rule
@ -618,7 +676,7 @@ class ValidationRuleFunctions(ValidationRuleBaseFunctions):
times_agency = self.sql_handler.get_times_for_participant_type(df_times, participant_type=ParticipantType.AGENCY.value) times_agency = self.sql_handler.get_times_for_participant_type(df_times, participant_type=ParticipantType.AGENCY.value)
times_terminal = self.sql_handler.get_times_for_participant_type(df_times, participant_type=ParticipantType.TERMINAL.value) times_terminal = self.sql_handler.get_times_for_participant_type(df_times, participant_type=ParticipantType.TERMINAL.value)
if (times_terminal.operations_end is pd.NaT) or (times_agency.etd_berth is pd.NaT): if self.check_is_not_a_time_or_is_none(times_terminal.operations_end) or self.check_is_not_a_time_or_is_none(times_agency.etd_berth):
return (StatusFlags.GREEN, None) return (StatusFlags.GREEN, None)
# check, whether the end of operations is AFTER the estimated departure time # check, whether the end of operations is AFTER the estimated departure time
@ -645,11 +703,11 @@ class ValidationRuleFunctions(ValidationRuleBaseFunctions):
times_agency = self.sql_handler.get_times_for_participant_type(df_times, participant_type=ParticipantType.AGENCY.value) times_agency = self.sql_handler.get_times_for_participant_type(df_times, participant_type=ParticipantType.AGENCY.value)
# requirements: tidal window (from & to) is filled in # requirements: tidal window (from & to) is filled in
if (shipcall.tidal_window_from is pd.NaT) or (shipcall.tidal_window_to is pd.NaT) or (df_times.eta_berth is pd.NaT): if self.check_is_not_a_time_or_is_none(shipcall.tidal_window_from) or self.check_is_not_a_time_or_is_none(shipcall.tidal_window_to) or self.check_is_not_a_time_or_is_none(times_agency.eta_berth): # 202310310: note: this should check times_agency, shouldn't it?
return (StatusFlags.GREEN, None) return (StatusFlags.GREEN, None)
# check, whether the query time is between start & end time # check, whether the query time is between start & end time
# a violation is observed, when the is NOT between start & end # a violation is observed, when the time is NOT between start & end
violation_state = not self.time_logic.time_inbetween(query_time=times_agency.eta_berth, start_time=shipcall.tidal_window_from, end_time=shipcall.tidal_window_to) violation_state = not self.time_logic.time_inbetween(query_time=times_agency.eta_berth, start_time=shipcall.tidal_window_from, end_time=shipcall.tidal_window_to)
if violation_state: if violation_state:
@ -673,11 +731,11 @@ class ValidationRuleFunctions(ValidationRuleBaseFunctions):
times_agency = self.sql_handler.get_times_for_participant_type(df_times, participant_type=ParticipantType.AGENCY.value) times_agency = self.sql_handler.get_times_for_participant_type(df_times, participant_type=ParticipantType.AGENCY.value)
# requirements: tidal window (from & to) is filled in # requirements: tidal window (from & to) is filled in
if (shipcall.tidal_window_from is pd.NaT) or (shipcall.tidal_window_to is pd.NaT) or (df_times.eta_berth is pd.NaT): if self.check_is_not_a_time_or_is_none(shipcall.tidal_window_from) or self.check_is_not_a_time_or_is_none(shipcall.tidal_window_to) or self.check_is_not_a_time_or_is_none(times_agency.etd_berth): # 202310310: note: this should check times_agency, shouldn't it?
return (StatusFlags.GREEN, None) return (StatusFlags.GREEN, None)
# check, whether the query time is between start & end time # check, whether the query time is between start & end time
# a violation is observed, when the is NOT between start & end # a violation is observed, when the time is NOT between start & end
violation_state = not self.time_logic.time_inbetween(query_time=times_agency.etd_berth, start_time=shipcall.tidal_window_from, end_time=shipcall.tidal_window_to) violation_state = not self.time_logic.time_inbetween(query_time=times_agency.etd_berth, start_time=shipcall.tidal_window_from, end_time=shipcall.tidal_window_to)
if violation_state: if violation_state:
@ -692,6 +750,10 @@ class ValidationRuleFunctions(ValidationRuleBaseFunctions):
Type: Global Rule Type: Global Rule
Description: this validation rule checks, whether there are too many shipcalls with identical ETA times. Description: this validation rule checks, whether there are too many shipcalls with identical ETA times.
""" """
# check, if the header is filled in (agency)
if len(df_times.loc[df_times["participant_type"].isin([ParticipantType.AGENCY.value])]) != 1:
return (StatusFlags.GREEN, None)
# when ANY of the unique values exceeds the threshold, a violation is observed # when ANY of the unique values exceeds the threshold, a violation is observed
query = "eta_berth" query = "eta_berth"
violation_state = self.check_unique_shipcall_counts(query, rounding=rounding, maximum_threshold=maximum_threshold) violation_state = self.check_unique_shipcall_counts(query, rounding=rounding, maximum_threshold=maximum_threshold)
@ -708,6 +770,10 @@ class ValidationRuleFunctions(ValidationRuleBaseFunctions):
Type: Global Rule Type: Global Rule
Description: this validation rule checks, whether there are too many shipcalls with identical ETD times. Description: this validation rule checks, whether there are too many shipcalls with identical ETD times.
""" """
# check, if the header is filled in (agency)
if len(df_times.loc[df_times["participant_type"].isin([ParticipantType.AGENCY.value])]) != 1:
return (StatusFlags.GREEN, None)
# when ANY of the unique values exceeds the threshold, a violation is observed # when ANY of the unique values exceeds the threshold, a violation is observed
query = "etd_berth" query = "etd_berth"
violation_state = self.check_unique_shipcall_counts(query, rounding=rounding, maximum_threshold=maximum_threshold) violation_state = self.check_unique_shipcall_counts(query, rounding=rounding, maximum_threshold=maximum_threshold)
@ -731,6 +797,10 @@ class ValidationRuleFunctions(ValidationRuleBaseFunctions):
times_agency = self.sql_handler.get_times_for_participant_type(df_times, participant_type=ParticipantType.AGENCY.value) times_agency = self.sql_handler.get_times_for_participant_type(df_times, participant_type=ParticipantType.AGENCY.value)
times_terminal = self.sql_handler.get_times_for_participant_type(df_times, participant_type=ParticipantType.TERMINAL.value) times_terminal = self.sql_handler.get_times_for_participant_type(df_times, participant_type=ParticipantType.TERMINAL.value)
# when one of the two values is null, the state is GREEN
if (times_agency.berth_id is None) or (times_terminal.berth_id is None):
return (StatusFlags.GREEN, None)
violation_state = times_agency.berth_id!=times_terminal.berth_id violation_state = times_agency.berth_id!=times_terminal.berth_id
if violation_state: if violation_state:
@ -752,6 +822,10 @@ class ValidationRuleFunctions(ValidationRuleBaseFunctions):
times_agency = self.sql_handler.get_times_for_participant_type(df_times, participant_type=ParticipantType.AGENCY.value) times_agency = self.sql_handler.get_times_for_participant_type(df_times, participant_type=ParticipantType.AGENCY.value)
times_terminal = self.sql_handler.get_times_for_participant_type(df_times, participant_type=ParticipantType.TERMINAL.value) times_terminal = self.sql_handler.get_times_for_participant_type(df_times, participant_type=ParticipantType.TERMINAL.value)
# when one of the two values is null, the state is GREEN
if (times_agency.pier_side is None) or (times_terminal.pier_side is None):
return (StatusFlags.GREEN, None)
violation_state = times_agency.pier_side!=times_terminal.pier_side violation_state = times_agency.pier_side!=times_terminal.pier_side
if violation_state: if violation_state:

View File

@ -41,6 +41,9 @@ class ValidationRules(ValidationRuleFunctions):
# filter out all 'None' results, which indicate that no violation occured. # filter out all 'None' results, which indicate that no violation occured.
evaluation_results = [evaluation_result for evaluation_result in evaluation_results if evaluation_result[1] is not None] evaluation_results = [evaluation_result for evaluation_result in evaluation_results if evaluation_result[1] is not None]
# 'translate' all error codes into readable, human-understandable format.
evaluation_results = [(state, self.describe_error_message(msg)) for (state, msg) in evaluation_results]
""" # deprecated """ # deprecated
# check, if ANY of the evaluation results (evaluation_state) is larger than the .GREEN state. This means, that .YELLOW and .RED # check, if ANY of the evaluation results (evaluation_state) is larger than the .GREEN state. This means, that .YELLOW and .RED
# would return 'True'. Numpy arrays and functions are used to accelerate the comparison. # would return 'True'. Numpy arrays and functions are used to accelerate the comparison.

View File

@ -2,7 +2,7 @@ import os
import sys import sys
import logging import logging
sys.path.insert(0, '/var/www/brecal_test/src/server') sys.path.insert(0, '/var/www/brecal_devel/src/server')
sys.path.insert(0, '/var/www/venv/lib/python3.10/site-packages/') sys.path.insert(0, '/var/www/venv/lib/python3.10/site-packages/')
# set the key # set the key

View File

@ -156,4 +156,12 @@ def test_validation_rule_fct_agency_and_terminal_berth_id_agreement(build_sql_pr
def test_all_validation_rule_fcts_have_a_description():
from BreCal.validators.validation_rule_functions import error_message_dict, ValidationRuleFunctions
import types
vr = ValidationRuleFunctions(sql_handler=None)
assert all(
[mthd_ in list(error_message_dict.keys()) for mthd_ in dir(vr) if ('validation_rule_fct' in mthd_)]
), f"one of the validation_rule_fcts is currently not defined in the error_message_dict and will create cryptic descriptions! Please add it to the error_message_dict BreCal.validators.validation_rule_functions"
return