Updated to Version 0.9.6 for public version
This commit is contained in:
parent
e77c9264b9
commit
902cb9d90d
322
.gitignore
vendored
322
.gitignore
vendored
@ -1,44 +1,3 @@
|
|||||||
|
|
||||||
Skip to content
|
|
||||||
Pull requests
|
|
||||||
Issues
|
|
||||||
Codespaces
|
|
||||||
Marketplace
|
|
||||||
Explore
|
|
||||||
@danielschick
|
|
||||||
github /
|
|
||||||
gitignore
|
|
||||||
Public
|
|
||||||
|
|
||||||
Fork your own copy of github/gitignore
|
|
||||||
|
|
||||||
Code
|
|
||||||
Pull requests 371
|
|
||||||
Actions
|
|
||||||
Security
|
|
||||||
|
|
||||||
Insights
|
|
||||||
|
|
||||||
Beta Try the new code view
|
|
||||||
gitignore/VisualStudio.gitignore
|
|
||||||
@n0099
|
|
||||||
n0099 [VisualStudio.gitignore] remove a trailing space
|
|
||||||
Latest commit 491040e Jan 26, 2022
|
|
||||||
History
|
|
||||||
165 contributors
|
|
||||||
@shiftkey
|
|
||||||
@arcresu
|
|
||||||
@aroben
|
|
||||||
@bbodenmiller
|
|
||||||
@HassanHashemi
|
|
||||||
@haacked
|
|
||||||
@niik
|
|
||||||
@AArnott
|
|
||||||
@sayedihashimi
|
|
||||||
@saschanaz
|
|
||||||
@bdougie
|
|
||||||
@OsirisTerje
|
|
||||||
398 lines (319 sloc) 6.7 KB
|
|
||||||
## Ignore Visual Studio temporary files, build results, and
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
## files generated by popular Visual Studio add-ons.
|
## files generated by popular Visual Studio add-ons.
|
||||||
##
|
##
|
||||||
@ -75,40 +34,11 @@ bld/
|
|||||||
|
|
||||||
# Visual Studio 2015/2017 cache/options directory
|
# Visual Studio 2015/2017 cache/options directory
|
||||||
.vs/
|
.vs/
|
||||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
|
||||||
#wwwroot/
|
|
||||||
|
|
||||||
# Visual Studio 2017 auto generated files
|
|
||||||
Generated\ Files/
|
|
||||||
|
|
||||||
# MSTest test Results
|
# MSTest test Results
|
||||||
[Tt]est[Rr]esult*/
|
[Tt]est[Rr]esult*/
|
||||||
[Bb]uild[Ll]og.*
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
# NUnit
|
|
||||||
*.VisualState.xml
|
|
||||||
TestResult.xml
|
|
||||||
nunit-*.xml
|
|
||||||
|
|
||||||
# Build Results of an ATL Project
|
|
||||||
[Dd]ebugPS/
|
|
||||||
[Rr]eleasePS/
|
|
||||||
dlldata.c
|
|
||||||
|
|
||||||
# Benchmark Results
|
|
||||||
BenchmarkDotNet.Artifacts/
|
|
||||||
|
|
||||||
# .NET Core
|
|
||||||
project.lock.json
|
|
||||||
project.fragment.lock.json
|
|
||||||
artifacts/
|
|
||||||
|
|
||||||
# ASP.NET Scaffolding
|
|
||||||
ScaffoldingReadMe.txt
|
|
||||||
|
|
||||||
# StyleCop
|
|
||||||
StyleCopReport.xml
|
|
||||||
|
|
||||||
# Files built by Visual Studio
|
# Files built by Visual Studio
|
||||||
*_i.c
|
*_i.c
|
||||||
*_p.c
|
*_p.c
|
||||||
@ -139,20 +69,6 @@ StyleCopReport.xml
|
|||||||
*.svclog
|
*.svclog
|
||||||
*.scc
|
*.scc
|
||||||
|
|
||||||
# Chutzpah Test files
|
|
||||||
_Chutzpah*
|
|
||||||
|
|
||||||
# Visual C++ cache files
|
|
||||||
ipch/
|
|
||||||
*.aps
|
|
||||||
*.ncb
|
|
||||||
*.opendb
|
|
||||||
*.opensdf
|
|
||||||
*.sdf
|
|
||||||
*.cachefile
|
|
||||||
*.VC.db
|
|
||||||
*.VC.VC.opendb
|
|
||||||
|
|
||||||
# Visual Studio profiler
|
# Visual Studio profiler
|
||||||
*.psess
|
*.psess
|
||||||
*.vsp
|
*.vsp
|
||||||
@ -162,108 +78,9 @@ ipch/
|
|||||||
# Visual Studio Trace Files
|
# Visual Studio Trace Files
|
||||||
*.e2e
|
*.e2e
|
||||||
|
|
||||||
# TFS 2012 Local Workspace
|
|
||||||
$tf/
|
|
||||||
|
|
||||||
# Guidance Automation Toolkit
|
|
||||||
*.gpState
|
|
||||||
|
|
||||||
# ReSharper is a .NET coding add-in
|
|
||||||
_ReSharper*/
|
|
||||||
*.[Rr]e[Ss]harper
|
|
||||||
*.DotSettings.user
|
|
||||||
|
|
||||||
# TeamCity is a build add-in
|
|
||||||
_TeamCity*
|
|
||||||
|
|
||||||
# DotCover is a Code Coverage Tool
|
|
||||||
*.dotCover
|
|
||||||
|
|
||||||
# AxoCover is a Code Coverage Tool
|
|
||||||
.axoCover/*
|
|
||||||
!.axoCover/settings.json
|
|
||||||
|
|
||||||
# Coverlet is a free, cross platform Code Coverage Tool
|
|
||||||
coverage*.json
|
|
||||||
coverage*.xml
|
|
||||||
coverage*.info
|
|
||||||
|
|
||||||
# Visual Studio code coverage results
|
|
||||||
*.coverage
|
|
||||||
*.coveragexml
|
|
||||||
|
|
||||||
# NCrunch
|
|
||||||
_NCrunch_*
|
|
||||||
.*crunch*.local.xml
|
|
||||||
nCrunchTemp_*
|
|
||||||
|
|
||||||
# MightyMoose
|
|
||||||
*.mm.*
|
|
||||||
AutoTest.Net/
|
|
||||||
|
|
||||||
# Web workbench (sass)
|
|
||||||
.sass-cache/
|
|
||||||
|
|
||||||
# Installshield output folder
|
|
||||||
[Ee]xpress/
|
|
||||||
|
|
||||||
# DocProject is a documentation generator add-in
|
|
||||||
DocProject/buildhelp/
|
|
||||||
DocProject/Help/*.HxT
|
|
||||||
DocProject/Help/*.HxC
|
|
||||||
DocProject/Help/*.hhc
|
|
||||||
DocProject/Help/*.hhk
|
|
||||||
DocProject/Help/*.hhp
|
|
||||||
DocProject/Help/Html2
|
|
||||||
DocProject/Help/html
|
|
||||||
|
|
||||||
# Click-Once directory
|
# Click-Once directory
|
||||||
publish/
|
publish/
|
||||||
|
|
||||||
# Publish Web Output
|
|
||||||
*.[Pp]ublish.xml
|
|
||||||
*.azurePubxml
|
|
||||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
|
||||||
# but database connection strings (with potential passwords) will be unencrypted
|
|
||||||
# *.pubxml
|
|
||||||
*.publishproj
|
|
||||||
|
|
||||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
|
||||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
|
||||||
# in these scripts will be unencrypted
|
|
||||||
PublishScripts/
|
|
||||||
|
|
||||||
# NuGet Packages
|
|
||||||
*.nupkg
|
|
||||||
# NuGet Symbol Packages
|
|
||||||
*.snupkg
|
|
||||||
# The packages folder can be ignored because of Package Restore
|
|
||||||
**/[Pp]ackages/*
|
|
||||||
# except build/, which is used as an MSBuild target.
|
|
||||||
!**/[Pp]ackages/build/
|
|
||||||
# Uncomment if necessary however generally it will be regenerated when needed
|
|
||||||
#!**/[Pp]ackages/repositories.config
|
|
||||||
# NuGet v3's project.json files produces more ignorable files
|
|
||||||
*.nuget.props
|
|
||||||
*.nuget.targets
|
|
||||||
|
|
||||||
# Microsoft Azure Build Output
|
|
||||||
csx/
|
|
||||||
*.build.csdef
|
|
||||||
|
|
||||||
# Microsoft Azure Emulator
|
|
||||||
ecf/
|
|
||||||
rcf/
|
|
||||||
|
|
||||||
# Windows Store app package directories and files
|
|
||||||
AppPackages/
|
|
||||||
BundleArtifacts/
|
|
||||||
Package.StoreAssociation.xml
|
|
||||||
_pkginfo.txt
|
|
||||||
*.appx
|
|
||||||
*.appxbundle
|
|
||||||
*.appxupload
|
|
||||||
|
|
||||||
# Visual Studio cache files
|
# Visual Studio cache files
|
||||||
# files ending in .cache can be ignored
|
# files ending in .cache can be ignored
|
||||||
*.[Cc]ache
|
*.[Cc]ache
|
||||||
@ -279,158 +96,33 @@ ClientBin/
|
|||||||
*.jfm
|
*.jfm
|
||||||
*.pfx
|
*.pfx
|
||||||
*.publishsettings
|
*.publishsettings
|
||||||
orleans.codegen.cs
|
|
||||||
|
|
||||||
# Including strong name files can present a security risk
|
|
||||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
|
||||||
#*.snk
|
|
||||||
|
|
||||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
|
||||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
|
||||||
#bower_components/
|
|
||||||
|
|
||||||
# RIA/Silverlight projects
|
|
||||||
Generated_Code/
|
|
||||||
|
|
||||||
# Backup & report files from converting an old project file
|
|
||||||
# to a newer Visual Studio version. Backup files are not needed,
|
|
||||||
# because we have git ;-)
|
|
||||||
_UpgradeReport_Files/
|
|
||||||
Backup*/
|
|
||||||
UpgradeLog*.XML
|
|
||||||
UpgradeLog*.htm
|
|
||||||
ServiceFabricBackup/
|
|
||||||
*.rptproj.bak
|
|
||||||
|
|
||||||
# SQL Server files
|
# SQL Server files
|
||||||
*.mdf
|
*.mdf
|
||||||
*.ldf
|
*.ldf
|
||||||
*.ndf
|
*.ndf
|
||||||
|
|
||||||
# Business Intelligence projects
|
|
||||||
*.rdl.data
|
|
||||||
*.bim.layout
|
|
||||||
*.bim_*.settings
|
|
||||||
*.rptproj.rsuser
|
|
||||||
*- [Bb]ackup.rdl
|
|
||||||
*- [Bb]ackup ([0-9]).rdl
|
|
||||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
|
||||||
|
|
||||||
# Microsoft Fakes
|
|
||||||
FakesAssemblies/
|
|
||||||
|
|
||||||
# GhostDoc plugin setting file
|
|
||||||
*.GhostDoc.xml
|
|
||||||
|
|
||||||
# Node.js Tools for Visual Studio
|
# Node.js Tools for Visual Studio
|
||||||
.ntvs_analysis.dat
|
.ntvs_analysis.dat
|
||||||
node_modules/
|
node_modules/
|
||||||
|
|
||||||
# Visual Studio 6 build log
|
|
||||||
*.plg
|
|
||||||
|
|
||||||
# Visual Studio 6 workspace options file
|
|
||||||
*.opt
|
|
||||||
|
|
||||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
|
||||||
*.vbw
|
|
||||||
|
|
||||||
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
|
|
||||||
*.vbp
|
|
||||||
|
|
||||||
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
|
|
||||||
*.dsw
|
|
||||||
*.dsp
|
|
||||||
|
|
||||||
# Visual Studio 6 technical files
|
|
||||||
*.ncb
|
|
||||||
*.aps
|
|
||||||
|
|
||||||
# Visual Studio LightSwitch build output
|
|
||||||
**/*.HTMLClient/GeneratedArtifacts
|
|
||||||
**/*.DesktopClient/GeneratedArtifacts
|
|
||||||
**/*.DesktopClient/ModelManifest.xml
|
|
||||||
**/*.Server/GeneratedArtifacts
|
|
||||||
**/*.Server/ModelManifest.xml
|
|
||||||
_Pvt_Extensions
|
|
||||||
|
|
||||||
# Paket dependency manager
|
|
||||||
.paket/paket.exe
|
|
||||||
paket-files/
|
|
||||||
|
|
||||||
# FAKE - F# Make
|
|
||||||
.fake/
|
|
||||||
|
|
||||||
# CodeRush personal settings
|
|
||||||
.cr/personal
|
|
||||||
|
|
||||||
# Python Tools for Visual Studio (PTVS)
|
# Python Tools for Visual Studio (PTVS)
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.pyc
|
*.pyc
|
||||||
|
|
||||||
# Cake - Uncomment if you are using it
|
|
||||||
# tools/**
|
|
||||||
# !tools/packages.config
|
|
||||||
|
|
||||||
# Tabs Studio
|
|
||||||
*.tss
|
|
||||||
|
|
||||||
# Telerik's JustMock configuration file
|
|
||||||
*.jmconfig
|
|
||||||
|
|
||||||
# BizTalk build output
|
|
||||||
*.btp.cs
|
|
||||||
*.btm.cs
|
|
||||||
*.odx.cs
|
|
||||||
*.xsd.cs
|
|
||||||
|
|
||||||
# OpenCover UI analysis results
|
|
||||||
OpenCover/
|
|
||||||
|
|
||||||
# Azure Stream Analytics local run output
|
|
||||||
ASALocalRun/
|
|
||||||
|
|
||||||
# MSBuild Binary and Structured Log
|
|
||||||
*.binlog
|
|
||||||
|
|
||||||
# NVidia Nsight GPU debugger configuration file
|
|
||||||
*.nvuser
|
|
||||||
|
|
||||||
# MFractors (Xamarin productivity tool) working folder
|
|
||||||
.mfractor/
|
|
||||||
|
|
||||||
# Local History for Visual Studio
|
|
||||||
.localhistory/
|
|
||||||
|
|
||||||
# Visual Studio History (VSHistory) files
|
# Visual Studio History (VSHistory) files
|
||||||
.vshistory/
|
.vshistory/
|
||||||
|
|
||||||
# BeatPulse healthcheck temp database
|
|
||||||
healthchecksdb
|
|
||||||
|
|
||||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
|
||||||
MigrationBackup/
|
|
||||||
|
|
||||||
# Ionide (cross platform F# VS Code tools) working folder
|
|
||||||
.ionide/
|
|
||||||
|
|
||||||
# Fody - auto-generated XML schema
|
|
||||||
FodyWeavers.xsd
|
|
||||||
|
|
||||||
# VS Code files for those working on multiple tools
|
# VS Code files for those working on multiple tools
|
||||||
.vscode/*
|
.vscode/
|
||||||
!.vscode/settings.json
|
|
||||||
!.vscode/tasks.json
|
#!.vscode/settings.json
|
||||||
!.vscode/launch.json
|
#!.vscode/tasks.json
|
||||||
!.vscode/extensions.json
|
#!.vscode/launch.json
|
||||||
*.code-workspace
|
#!.vscode/extensions.json
|
||||||
|
#*.code-workspace
|
||||||
|
|
||||||
# Local History for Visual Studio Code
|
# Local History for Visual Studio Code
|
||||||
.history/
|
.history/
|
||||||
|
|
||||||
# Windows Installer files from build outputs
|
|
||||||
*.cab
|
|
||||||
*.msi
|
|
||||||
*.msix
|
|
||||||
*.msm
|
|
||||||
*.msp
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
//----------------------
|
//----------------------
|
||||||
// <auto-generated>
|
// <auto-generated>
|
||||||
// Generated REST API Client Code Generator v1.8.4.0 on 23.10.2023 09:06:40
|
// Generated REST API Client Code Generator v1.8.4.0 on 01.11.2023 15:27:09
|
||||||
// Using the tool OpenAPI Generator v7.0.0
|
// Using the tool OpenAPI Generator v7.0.0
|
||||||
// </auto-generated>
|
// </auto-generated>
|
||||||
//----------------------
|
//----------------------
|
||||||
|
|||||||
@ -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
25
misc/bump-version.sh
Normal 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
42
misc/copyprod.sh
Normal 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" -- '..' ':(exclude)*.sh'
|
||||||
|
git grep -I "/var/www/brecal_test/" -- '..' ':(exclude)*.sh'
|
||||||
|
|
||||||
|
# 2) Color references
|
||||||
|
# Bar colors in client: (BG_COLOR)
|
||||||
|
# Devel: #1D751F
|
||||||
|
# Test: #751D1F
|
||||||
|
# Prod: #203864
|
||||||
|
|
||||||
|
git grep -I "#751D1F" -- '..' ':(exclude)*.sh'
|
||||||
|
|
||||||
|
# 3) Assembly name references
|
||||||
|
|
||||||
|
git grep -I "BreCalTestClient" -- '..' ':(exclude)*.sh'
|
||||||
|
|
||||||
|
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" -- '..' ':(exclude)*.sh' | xargs sed --in-place -e "s/connection_data_test.json/connection_data_prod.json/g"
|
||||||
|
git add $(git grep -Il "connection_data_prod.json" -- '..' ':(exclude)*.sh')
|
||||||
|
git grep -I "/var/www/brecal_test/" -- '..' ':(exclude)*.sh' | xargs sed --in-place -e "s/\/var\/www\/brecal_test\//\/var\/www\/brecal\//g"
|
||||||
|
git add $(git grep -Il "/var/www/brecal/" -- '..' ':(exclude)*.sh')
|
||||||
|
|
||||||
|
# 2. for color
|
||||||
|
git grep -Il "#751D1F" -- '..' ':(exclude)*.sh' | xargs sed --in-place -e "s/#751D1F/#203864/g"
|
||||||
|
git add $(git grep -Il "#203864" -- '..' ':(exclude)*.sh')
|
||||||
|
|
||||||
|
# 3. for assembly name
|
||||||
|
|
||||||
|
git grep -I "BreCalTestClient" -- '..' ':(exclude)*.sh' | xargs sed --in-place -e "s/BreCalTestClient/BreCalClient/g"
|
||||||
|
git add $(git grep -Il "BreCalClient" -- '..' ':(exclude)*.sh')
|
||||||
|
|
||||||
|
fi
|
||||||
42
misc/copytest.sh
Normal file
42
misc/copytest.sh
Normal 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" -- '..' ':(exclude)*.sh'
|
||||||
|
git grep -I "/var/www/brecal_devel/" -- '..' ':(exclude)*.sh'
|
||||||
|
|
||||||
|
# 2) Color references
|
||||||
|
# Bar colors in client: (BG_COLOR)
|
||||||
|
# Devel: #1D751F
|
||||||
|
# Test: #751D1F
|
||||||
|
# Prod: #203864
|
||||||
|
|
||||||
|
git grep -I "#1D751F" -- '..' ':(exclude)*.sh'
|
||||||
|
|
||||||
|
# 3) Assembly name references
|
||||||
|
|
||||||
|
git grep -I "BreCalDevelClient" -- '..' ':(exclude)*.sh'
|
||||||
|
|
||||||
|
echo "Proceed? [N/y]"
|
||||||
|
read proceed
|
||||||
|
|
||||||
|
# for color
|
||||||
|
|
||||||
|
if [ "${proceed}" = "y" ]; then
|
||||||
|
|
||||||
|
# 1. for database references and paths
|
||||||
|
git grep -Il "connection_data_devel.json" -- '..' ':(exclude)*.sh' | xargs sed --in-place -e "s/connection_data_devel.json/connection_data_test.json/g"
|
||||||
|
git add $(git grep -Il "connection_data_test.json" -- '..' ':(exclude)*.sh')
|
||||||
|
git grep -Il "/var/www/brecal_devel/" -- '..' ':(exclude)*.sh' | xargs sed --in-place -e "s/\/var\/www\/brecal_devel\//\/var\/www\/brecal_test\//g"
|
||||||
|
git add $(git grep -Il "/var/www/brecal_test/" -- '..' ':(exclude)*.sh')
|
||||||
|
|
||||||
|
# 2. for color
|
||||||
|
git grep -Il "#1D751F" -- '..' ':(exclude)*.sh' | xargs sed --in-place -e "s/#1D751F/#751D1F/g"
|
||||||
|
git add $(git grep -Il "#751D1F" -- '..' ':(exclude)*.sh')
|
||||||
|
|
||||||
|
# 3. for assembly name
|
||||||
|
|
||||||
|
git grep -Il "BreCalDevelClient" -- '..' ':(exclude)*.sh' | xargs sed --in-place -e "s/BreCalDevelClient/BreCalTestClient/g"
|
||||||
|
git add $(git grep -Il "BreCalTestClient" -- '..' ':(exclude)*.sh')
|
||||||
|
|
||||||
|
fi
|
||||||
192
misc/sample_static_data.sql
Normal file
192
misc/sample_static_data.sql
Normal 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
1
misc/version.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
0.9.6.0
|
||||||
@ -54,7 +54,7 @@
|
|||||||
<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.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.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"/>
|
<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="False" />
|
<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" />
|
<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" />
|
||||||
|
|
||||||
|
|||||||
@ -8,8 +8,8 @@
|
|||||||
<SignAssembly>True</SignAssembly>
|
<SignAssembly>True</SignAssembly>
|
||||||
<StartupObject>BreCalClient.App</StartupObject>
|
<StartupObject>BreCalClient.App</StartupObject>
|
||||||
<AssemblyOriginatorKeyFile>..\..\misc\brecal.snk</AssemblyOriginatorKeyFile>
|
<AssemblyOriginatorKeyFile>..\..\misc\brecal.snk</AssemblyOriginatorKeyFile>
|
||||||
<AssemblyVersion>0.9.4.0</AssemblyVersion>
|
<AssemblyVersion>0.9.6.0</AssemblyVersion>
|
||||||
<FileVersion>0.9.4.0</FileVersion>
|
<FileVersion>0.9.6.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>
|
||||||
|
|||||||
@ -65,21 +65,20 @@
|
|||||||
<ColumnDefinition Width=".5*" />
|
<ColumnDefinition Width=".5*" />
|
||||||
<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>
|
|
||||||
<ContextMenu>
|
|
||||||
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemArrivalBerth" Click="contextMenuItemArrivalBerth_Click" />
|
|
||||||
</ContextMenu>
|
|
||||||
</ComboBox.ContextMenu>
|
|
||||||
</ComboBox>
|
|
||||||
<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" />
|
||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
</ComboBox.ContextMenu>
|
</ComboBox.ContextMenu>
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
|
<ComboBox Name="comboBoxDepartureBerth" Grid.Column="1" Margin="2" DisplayMemberPath="Name" SelectedValuePath="Id">
|
||||||
|
<ComboBox.ContextMenu>
|
||||||
|
<ContextMenu>
|
||||||
|
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemArrivalBerth" Click="contextMenuItemArrivalBerth_Click" />
|
||||||
|
</ContextMenu>
|
||||||
|
</ComboBox.ContextMenu>
|
||||||
|
</ComboBox>
|
||||||
</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="datePickerETA" Grid.Column="3" Grid.Row="2" Margin="2" Format="Custom" FormatString="dd.MM. yyyy HH:mm" IsEnabled="False"/>
|
||||||
|
|||||||
@ -159,9 +159,17 @@ namespace BreCalClient
|
|||||||
|
|
||||||
this.ShipcallModel.Shipcall.ShipId = ((Ship)this.comboBoxShip.SelectedItem).Id;
|
this.ShipcallModel.Shipcall.ShipId = ((Ship)this.comboBoxShip.SelectedItem).Id;
|
||||||
this.ShipcallModel.Ship = (Ship)this.comboBoxShip.SelectedItem;
|
this.ShipcallModel.Ship = (Ship)this.comboBoxShip.SelectedItem;
|
||||||
this.ShipcallModel.Shipcall.ArrivalBerthId = (this.comboBoxArrivalBerth.SelectedItem != null) ? ((Berth)this.comboBoxArrivalBerth.SelectedItem).Id : null;
|
|
||||||
this.ShipcallModel.Shipcall.DepartureBerthId = (this.comboBoxDepartureBerth.SelectedItem != null) ? ((Berth)this.comboBoxDepartureBerth.SelectedItem).Id : null;
|
|
||||||
|
|
||||||
|
if (this.ShipcallModel.Shipcall.Type != 3) // incoming, outgoing
|
||||||
|
{
|
||||||
|
this.ShipcallModel.Shipcall.ArrivalBerthId = (this.comboBoxArrivalBerth.SelectedItem != null) ? ((Berth)this.comboBoxArrivalBerth.SelectedItem).Id : null;
|
||||||
|
this.ShipcallModel.Shipcall.DepartureBerthId = (this.comboBoxDepartureBerth.SelectedItem != null) ? ((Berth)this.comboBoxDepartureBerth.SelectedItem).Id : null;
|
||||||
|
}
|
||||||
|
else // shifting
|
||||||
|
{
|
||||||
|
this.ShipcallModel.Shipcall.DepartureBerthId = (this.comboBoxArrivalBerth.SelectedItem != null) ? ((Berth)this.comboBoxArrivalBerth.SelectedItem).Id : null;
|
||||||
|
this.ShipcallModel.Shipcall.ArrivalBerthId = (this.comboBoxDepartureBerth.SelectedItem != null) ? ((Berth)this.comboBoxDepartureBerth.SelectedItem).Id : null;
|
||||||
|
}
|
||||||
|
|
||||||
Participant? participant;
|
Participant? participant;
|
||||||
participant = (Participant?)this.comboBoxAgency.SelectedItem;
|
participant = (Participant?)this.comboBoxAgency.SelectedItem;
|
||||||
@ -225,8 +233,17 @@ namespace BreCalClient
|
|||||||
// this.textBoxVoyage.Text = this.ShipcallModel.Shipcall.Voyage;
|
// this.textBoxVoyage.Text = this.ShipcallModel.Shipcall.Voyage;
|
||||||
this.datePickerETD.Value = this.ShipcallModel.Shipcall.Etd;
|
this.datePickerETD.Value = this.ShipcallModel.Shipcall.Etd;
|
||||||
this.comboBoxShip.SelectedValue = this.ShipcallModel.Shipcall.ShipId;
|
this.comboBoxShip.SelectedValue = this.ShipcallModel.Shipcall.ShipId;
|
||||||
this.comboBoxArrivalBerth.SelectedValue = this.ShipcallModel.Shipcall.ArrivalBerthId;
|
|
||||||
this.comboBoxDepartureBerth.SelectedValue = this.ShipcallModel.Shipcall.DepartureBerthId;
|
if (this.ShipcallModel.Shipcall.Type != 3) // incoming, outgoing
|
||||||
|
{
|
||||||
|
this.comboBoxArrivalBerth.SelectedValue = this.ShipcallModel.Shipcall.ArrivalBerthId;
|
||||||
|
this.comboBoxDepartureBerth.SelectedValue = this.ShipcallModel.Shipcall.DepartureBerthId;
|
||||||
|
}
|
||||||
|
else // shifting
|
||||||
|
{
|
||||||
|
this.comboBoxArrivalBerth.SelectedValue = this.ShipcallModel.Shipcall.DepartureBerthId;
|
||||||
|
this.comboBoxDepartureBerth.SelectedValue = this.ShipcallModel.Shipcall.ArrivalBerthId;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.ShipcallModel.Shipcall.Participants == null) this.ShipcallModel.Shipcall.Participants = new();
|
if (this.ShipcallModel.Shipcall.Participants == null) this.ShipcallModel.Shipcall.Participants = new();
|
||||||
|
|
||||||
|
|||||||
@ -47,6 +47,7 @@ namespace BreCalClient
|
|||||||
this.comboBoxArrivalBerth.ItemsSource = BreCalLists.Berths;
|
this.comboBoxArrivalBerth.ItemsSource = BreCalLists.Berths;
|
||||||
this.CopyToControls();
|
this.CopyToControls();
|
||||||
|
|
||||||
|
this.Title = this.ShipcallModel.Title;
|
||||||
|
|
||||||
Participant? p = null;
|
Participant? p = null;
|
||||||
if(this.ShipcallModel.AssignedParticipants.ContainsKey(ParticipantType.AGENCY))
|
if(this.ShipcallModel.AssignedParticipants.ContainsKey(ParticipantType.AGENCY))
|
||||||
|
|||||||
@ -46,6 +46,8 @@ namespace BreCalClient
|
|||||||
this.comboBoxDepartureBerth.ItemsSource = BreCalLists.Berths;
|
this.comboBoxDepartureBerth.ItemsSource = BreCalLists.Berths;
|
||||||
this.CopyToControls();
|
this.CopyToControls();
|
||||||
|
|
||||||
|
this.Title = this.ShipcallModel.Title;
|
||||||
|
|
||||||
Participant? p = null;
|
Participant? p = null;
|
||||||
if (this.ShipcallModel.AssignedParticipants.ContainsKey(ParticipantType.AGENCY))
|
if (this.ShipcallModel.AssignedParticipants.ContainsKey(ParticipantType.AGENCY))
|
||||||
p = BreCalLists.Participants.Find(x => x.Id == this.ShipcallModel.AssignedParticipants[ParticipantType.AGENCY].ParticipantId);
|
p = BreCalLists.Participants.Find(x => x.Id == this.ShipcallModel.AssignedParticipants[ParticipantType.AGENCY].ParticipantId);
|
||||||
|
|||||||
@ -47,6 +47,8 @@ namespace BreCalClient
|
|||||||
this.comboBoxArrivalBerth.ItemsSource = BreCalLists.Berths;
|
this.comboBoxArrivalBerth.ItemsSource = BreCalLists.Berths;
|
||||||
this.CopyToControls();
|
this.CopyToControls();
|
||||||
|
|
||||||
|
this.Title = this.ShipcallModel.Title;
|
||||||
|
|
||||||
Participant? p = null;
|
Participant? p = null;
|
||||||
if (this.ShipcallModel.AssignedParticipants.ContainsKey(ParticipantType.AGENCY))
|
if (this.ShipcallModel.AssignedParticipants.ContainsKey(ParticipantType.AGENCY))
|
||||||
p = BreCalLists.Participants.Find(x => x.Id == this.ShipcallModel.AssignedParticipants[ParticipantType.AGENCY].ParticipantId);
|
p = BreCalLists.Participants.Find(x => x.Id == this.ShipcallModel.AssignedParticipants[ParticipantType.AGENCY].ParticipantId);
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width=".25*" />
|
<ColumnDefinition Width=".25*" />
|
||||||
<ColumnDefinition Width=".75*" />
|
<ColumnDefinition Width=".75*" />
|
||||||
<ColumnDefinition Width="40" />
|
<!--ColumnDefinition Width="40" /-->
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="28" />
|
<RowDefinition Height="28" />
|
||||||
@ -24,7 +24,7 @@
|
|||||||
<RowDefinition Height="56" />
|
<RowDefinition Height="56" />
|
||||||
<RowDefinition Height="28" />
|
<RowDefinition Height="28" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Label Grid.Row="0" Grid.Column="2" Content="{x:Static p:Resources.textFixed}" />
|
<!-- Label Grid.Row="0" Grid.Column="2" Content="{x:Static p:Resources.textFixed}" /-->
|
||||||
<Label Grid.Row="1" Grid.Column="0" Content="{x:Static p:Resources.textETABerth}" HorizontalContentAlignment="Right" />
|
<Label Grid.Row="1" Grid.Column="0" Content="{x:Static p:Resources.textETABerth}" HorizontalContentAlignment="Right" />
|
||||||
<Label Grid.Row="2" Grid.Column="0" Content="{x:Static p:Resources.textETDBerth}" HorizontalContentAlignment="Right" />
|
<Label Grid.Row="2" Grid.Column="0" Content="{x:Static p:Resources.textETDBerth}" HorizontalContentAlignment="Right" />
|
||||||
<Label Grid.Row="3" Grid.Column="0" Content="{x:Static p:Resources.textLockTime}" HorizontalContentAlignment="Right" />
|
<Label Grid.Row="3" Grid.Column="0" Content="{x:Static p:Resources.textLockTime}" HorizontalContentAlignment="Right" />
|
||||||
@ -43,7 +43,7 @@
|
|||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
</xctk:DateTimePicker.ContextMenu>
|
</xctk:DateTimePicker.ContextMenu>
|
||||||
</xctk:DateTimePicker>
|
</xctk:DateTimePicker>
|
||||||
<CheckBox IsEnabled="False" Grid.Row="1" Grid.Column="2" Margin="4,0,0,0" Name="checkBoxEtaBerthFixed" VerticalAlignment="Center" />
|
<!--CheckBox IsEnabled="False" Grid.Row="1" Grid.Column="2" Margin="4,0,0,0" Name="checkBoxEtaBerthFixed" VerticalAlignment="Center" /-->
|
||||||
<xctk:DateTimePicker IsEnabled="False" Grid.Row="2" Grid.Column="1" Margin="2" Name="datePickerETDBerth" Format="Custom" FormatString="dd.MM. yyyy HH:mm">
|
<xctk:DateTimePicker IsEnabled="False" Grid.Row="2" Grid.Column="1" Margin="2" Name="datePickerETDBerth" Format="Custom" FormatString="dd.MM. yyyy HH:mm">
|
||||||
<xctk:DateTimePicker.ContextMenu>
|
<xctk:DateTimePicker.ContextMenu>
|
||||||
<ContextMenu>
|
<ContextMenu>
|
||||||
@ -55,7 +55,7 @@
|
|||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
</xctk:DateTimePicker.ContextMenu>
|
</xctk:DateTimePicker.ContextMenu>
|
||||||
</xctk:DateTimePicker>
|
</xctk:DateTimePicker>
|
||||||
<CheckBox IsEnabled="False" Grid.Row="2" Grid.Column="2" Margin="4,0,0,0" Name="checkBoxEtDBerthFixed" VerticalAlignment="Center" />
|
<!--CheckBox IsEnabled="False" Grid.Row="2" Grid.Column="2" Margin="4,0,0,0" Name="checkBoxEtDBerthFixed" VerticalAlignment="Center" /-->
|
||||||
<xctk:DateTimePicker IsEnabled="False" Grid.Row="3" Grid.Column="1" Margin="2" Name="datePickerLockTime" Format="Custom" FormatString="dd.MM. yyyy HH:mm">
|
<xctk:DateTimePicker IsEnabled="False" Grid.Row="3" Grid.Column="1" Margin="2" Name="datePickerLockTime" Format="Custom" FormatString="dd.MM. yyyy HH:mm">
|
||||||
<xctk:DateTimePicker.ContextMenu>
|
<xctk:DateTimePicker.ContextMenu>
|
||||||
<ContextMenu>
|
<ContextMenu>
|
||||||
@ -67,7 +67,7 @@
|
|||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
</xctk:DateTimePicker.ContextMenu>
|
</xctk:DateTimePicker.ContextMenu>
|
||||||
</xctk:DateTimePicker>
|
</xctk:DateTimePicker>
|
||||||
<CheckBox IsEnabled="False" Grid.Row="3" Grid.Column="2" Margin="4,0,0,0" Name="checkBoxLockTimeFixed" VerticalAlignment="Center" />
|
<!--CheckBox IsEnabled="False" Grid.Row="3" Grid.Column="2" Margin="4,0,0,0" Name="checkBoxLockTimeFixed" VerticalAlignment="Center" /-->
|
||||||
<xctk:DateTimePicker IsEnabled="False" Grid.Row="4" Grid.Column="1" Margin="2" Name="datePickerZoneEntry" Format="Custom" FormatString="dd.MM. yyyy HH:mm">
|
<xctk:DateTimePicker IsEnabled="False" Grid.Row="4" Grid.Column="1" Margin="2" Name="datePickerZoneEntry" Format="Custom" FormatString="dd.MM. yyyy HH:mm">
|
||||||
<xctk:DateTimePicker.ContextMenu>
|
<xctk:DateTimePicker.ContextMenu>
|
||||||
<ContextMenu>
|
<ContextMenu>
|
||||||
@ -79,7 +79,7 @@
|
|||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
</xctk:DateTimePicker.ContextMenu>
|
</xctk:DateTimePicker.ContextMenu>
|
||||||
</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" IsEnabled="False"/>
|
<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">
|
||||||
|
|||||||
@ -64,10 +64,10 @@ namespace BreCalClient
|
|||||||
this.Times.LockTime = this.datePickerLockTime.Value;
|
this.Times.LockTime = this.datePickerLockTime.Value;
|
||||||
this.Times.ZoneEntry = this.datePickerZoneEntry.Value;
|
this.Times.ZoneEntry = this.datePickerZoneEntry.Value;
|
||||||
|
|
||||||
this.Times.EtaBerthFixed = this.checkBoxEtaBerthFixed.IsChecked;
|
//this.Times.EtaBerthFixed = this.checkBoxEtaBerthFixed.IsChecked;
|
||||||
this.Times.EtdBerthFixed = this.checkBoxEtDBerthFixed.IsChecked;
|
//this.Times.EtdBerthFixed = this.checkBoxEtDBerthFixed.IsChecked;
|
||||||
this.Times.LockTimeFixed = this.checkBoxLockTimeFixed.IsChecked;
|
//this.Times.LockTimeFixed = this.checkBoxLockTimeFixed.IsChecked;
|
||||||
this.Times.ZoneEntryFixed = this.checkBoxZoneEntryFixed.IsChecked;
|
//this.Times.ZoneEntryFixed = this.checkBoxZoneEntryFixed.IsChecked;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CopyToControls()
|
private void CopyToControls()
|
||||||
@ -78,10 +78,10 @@ namespace BreCalClient
|
|||||||
this.datePickerLockTime.Value = this.Times.LockTime;
|
this.datePickerLockTime.Value = this.Times.LockTime;
|
||||||
this.datePickerZoneEntry.Value = this.Times.ZoneEntry;
|
this.datePickerZoneEntry.Value = this.Times.ZoneEntry;
|
||||||
|
|
||||||
this.checkBoxEtaBerthFixed.IsChecked = this.Times.EtaBerthFixed;
|
//this.checkBoxEtaBerthFixed.IsChecked = this.Times.EtaBerthFixed;
|
||||||
this.checkBoxEtDBerthFixed.IsChecked = this.Times.EtdBerthFixed;
|
//this.checkBoxEtDBerthFixed.IsChecked = this.Times.EtdBerthFixed;
|
||||||
this.checkBoxLockTimeFixed.IsChecked = this.Times.LockTimeFixed;
|
//this.checkBoxLockTimeFixed.IsChecked = this.Times.LockTimeFixed;
|
||||||
this.checkBoxZoneEntryFixed.IsChecked = this.Times.ZoneEntryFixed;
|
//this.checkBoxZoneEntryFixed.IsChecked = this.Times.ZoneEntryFixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EnableControls()
|
private void EnableControls()
|
||||||
@ -94,25 +94,25 @@ namespace BreCalClient
|
|||||||
case Extensions.ParticipantType.MOORING:
|
case Extensions.ParticipantType.MOORING:
|
||||||
case Extensions.ParticipantType.PORT_ADMINISTRATION:
|
case Extensions.ParticipantType.PORT_ADMINISTRATION:
|
||||||
case Extensions.ParticipantType.TUG:
|
case Extensions.ParticipantType.TUG:
|
||||||
this.datePickerETABerth.IsEnabled = (CallType == Extensions.TypeEnum.Incoming || CallType == Extensions.TypeEnum.Shifting);
|
this.datePickerETABerth.IsEnabled = (CallType == Extensions.TypeEnum.Incoming);
|
||||||
this.checkBoxEtaBerthFixed.IsEnabled = (CallType == Extensions.TypeEnum.Incoming || CallType == Extensions.TypeEnum.Shifting);
|
//this.checkBoxEtaBerthFixed.IsEnabled = (CallType == Extensions.TypeEnum.Incoming || CallType == Extensions.TypeEnum.Shifting);
|
||||||
this.datePickerETDBerth.IsEnabled = (CallType == Extensions.TypeEnum.Outgoing || CallType == Extensions.TypeEnum.Shifting);
|
this.datePickerETDBerth.IsEnabled = (CallType == Extensions.TypeEnum.Outgoing || CallType == Extensions.TypeEnum.Shifting);
|
||||||
this.checkBoxEtDBerthFixed.IsEnabled = (CallType == Extensions.TypeEnum.Outgoing || CallType == Extensions.TypeEnum.Shifting);
|
//this.checkBoxEtDBerthFixed.IsEnabled = (CallType == Extensions.TypeEnum.Outgoing || CallType == Extensions.TypeEnum.Shifting);
|
||||||
this.datePickerLockTime.IsEnabled = (CallType == Extensions.TypeEnum.Incoming || CallType == Extensions.TypeEnum.Shifting);
|
this.datePickerLockTime.IsEnabled = (CallType == Extensions.TypeEnum.Incoming || CallType == Extensions.TypeEnum.Shifting);
|
||||||
this.checkBoxLockTimeFixed.IsEnabled = (CallType == Extensions.TypeEnum.Incoming || CallType == Extensions.TypeEnum.Shifting);
|
//this.checkBoxLockTimeFixed.IsEnabled = (CallType == Extensions.TypeEnum.Incoming || CallType == Extensions.TypeEnum.Shifting);
|
||||||
this.datePickerZoneEntry.IsEnabled = false;
|
this.datePickerZoneEntry.IsEnabled = false;
|
||||||
this.checkBoxZoneEntryFixed.IsEnabled = false;
|
//this.checkBoxZoneEntryFixed.IsEnabled = false;
|
||||||
this.textBoxRemarks.IsEnabled = true;
|
this.textBoxRemarks.IsEnabled = true;
|
||||||
break;
|
break;
|
||||||
case Extensions.ParticipantType.PILOT:
|
case Extensions.ParticipantType.PILOT:
|
||||||
this.datePickerETABerth.IsEnabled = (CallType == Extensions.TypeEnum.Incoming || CallType == Extensions.TypeEnum.Shifting);
|
this.datePickerETABerth.IsEnabled = (CallType == Extensions.TypeEnum.Incoming);
|
||||||
this.checkBoxEtaBerthFixed.IsEnabled = (CallType == Extensions.TypeEnum.Incoming || CallType == Extensions.TypeEnum.Shifting);
|
//this.checkBoxEtaBerthFixed.IsEnabled = (CallType == Extensions.TypeEnum.Incoming || CallType == Extensions.TypeEnum.Shifting);
|
||||||
this.datePickerETDBerth.IsEnabled = (CallType == Extensions.TypeEnum.Outgoing || CallType == Extensions.TypeEnum.Shifting);
|
this.datePickerETDBerth.IsEnabled = (CallType == Extensions.TypeEnum.Outgoing || CallType == Extensions.TypeEnum.Shifting);
|
||||||
this.checkBoxEtDBerthFixed.IsEnabled = (CallType == Extensions.TypeEnum.Outgoing || CallType == Extensions.TypeEnum.Shifting);
|
//this.checkBoxEtDBerthFixed.IsEnabled = (CallType == Extensions.TypeEnum.Outgoing || CallType == Extensions.TypeEnum.Shifting);
|
||||||
this.datePickerLockTime.IsEnabled = (CallType == Extensions.TypeEnum.Incoming || CallType == Extensions.TypeEnum.Shifting);
|
this.datePickerLockTime.IsEnabled = (CallType == Extensions.TypeEnum.Incoming || CallType == Extensions.TypeEnum.Shifting);
|
||||||
this.checkBoxLockTimeFixed.IsEnabled = (CallType == Extensions.TypeEnum.Incoming || CallType == Extensions.TypeEnum.Shifting);
|
//this.checkBoxLockTimeFixed.IsEnabled = (CallType == Extensions.TypeEnum.Incoming || CallType == Extensions.TypeEnum.Shifting);
|
||||||
this.datePickerZoneEntry.IsEnabled = (CallType == Extensions.TypeEnum.Incoming);
|
this.datePickerZoneEntry.IsEnabled = (CallType == Extensions.TypeEnum.Incoming);
|
||||||
this.checkBoxZoneEntryFixed.IsEnabled = (CallType == Extensions.TypeEnum.Incoming);
|
//this.checkBoxZoneEntryFixed.IsEnabled = (CallType == Extensions.TypeEnum.Incoming);
|
||||||
this.textBoxRemarks.IsEnabled = true;
|
this.textBoxRemarks.IsEnabled = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -96,11 +96,11 @@ namespace BreCalClient
|
|||||||
{
|
{
|
||||||
if (this.Times.ParticipantId != App.Participant.Id) return;
|
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);
|
||||||
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);
|
||||||
this.comboBoxPierside.IsEnabled = (CallType == Extensions.TypeEnum.Incoming) || (CallType == Extensions.TypeEnum.Shifting);
|
this.comboBoxPierside.IsEnabled = (CallType == Extensions.TypeEnum.Incoming);
|
||||||
this.textBoxBerthRemarks.IsEnabled = (CallType == Extensions.TypeEnum.Incoming) || (CallType == Extensions.TypeEnum.Shifting);
|
this.textBoxBerthRemarks.IsEnabled = (CallType == Extensions.TypeEnum.Incoming);
|
||||||
this.textBoxRemarks.IsEnabled = true;
|
this.textBoxRemarks.IsEnabled = true;
|
||||||
this.buttonOK.IsEnabled = true;
|
this.buttonOK.IsEnabled = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,8 @@ namespace BreCalClient
|
|||||||
{
|
{
|
||||||
Times Times { get; set; }
|
Times Times { get; set; }
|
||||||
|
|
||||||
|
string Title { get; set; }
|
||||||
|
|
||||||
Extensions.TypeEnum CallType { get; set; }
|
Extensions.TypeEnum CallType { get; set; }
|
||||||
|
|
||||||
bool? ShowDialog();
|
bool? ShowDialog();
|
||||||
|
|||||||
@ -46,7 +46,7 @@ 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 int searchPastDays = 0;
|
||||||
|
|
||||||
// private bool _filterChanged = false;
|
// private bool _filterChanged = false;
|
||||||
@ -90,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)
|
||||||
@ -415,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();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -512,29 +521,26 @@ 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.Eta ?? DateTime.Now : x.Etd ?? DateTime.Now;
|
||||||
if (y.Shipcall == null) return 0;
|
DateTime yDate = (y.Shipcall.Type == (int) Extensions.TypeEnum.Incoming) ? y.Eta ?? DateTime.Now : y.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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -617,6 +623,7 @@ namespace BreCalClient
|
|||||||
|
|
||||||
// show a dialog that lets the user create / update times for the given shipcall
|
// show a dialog that lets the user create / update times for the given shipcall
|
||||||
IEditTimesControl etc = (participantType == ParticipantType.TERMINAL) ? new EditTimesTerminalControl() : new EditTimesControl();
|
IEditTimesControl etc = (participantType == ParticipantType.TERMINAL) ? new EditTimesTerminalControl() : new EditTimesControl();
|
||||||
|
etc.Title = obj.ShipcallControlModel.Title;
|
||||||
|
|
||||||
if(obj.ShipcallControlModel.Shipcall != null)
|
if(obj.ShipcallControlModel.Shipcall != null)
|
||||||
etc.CallType = (TypeEnum) obj.ShipcallControlModel.Shipcall.Type;
|
etc.CallType = (TypeEnum) obj.ShipcallControlModel.Shipcall.Type;
|
||||||
|
|||||||
@ -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.6.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>
|
||||||
@ -5,7 +5,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ApplicationRevision>0</ApplicationRevision>
|
<ApplicationRevision>0</ApplicationRevision>
|
||||||
<ApplicationVersion>0.9.4.0</ApplicationVersion>
|
<ApplicationVersion>0.9.6.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,17 @@ 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>
|
||||||
</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>
|
||||||
@ -5,11 +5,12 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ApplicationRevision>0</ApplicationRevision>
|
<ApplicationRevision>0</ApplicationRevision>
|
||||||
<ApplicationVersion>0.9.4.0</ApplicationVersion>
|
<ApplicationVersion>0.9.6.*</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>
|
||||||
|
|||||||
4
src/BreCalClient/Properties/Settings.Designer.cs
generated
4
src/BreCalClient/Properties/Settings.Designer.cs
generated
@ -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("#203864")]
|
||||||
public string BG_COLOR {
|
public string BG_COLOR {
|
||||||
get {
|
get {
|
||||||
return ((string)(this["BG_COLOR"]));
|
return ((string)(this["BG_COLOR"]));
|
||||||
@ -43,7 +43,7 @@ namespace BreCalClient.Properties {
|
|||||||
|
|
||||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
[global::System.Configuration.DefaultSettingValueAttribute("!!Bremen calling Testversion!!")]
|
[global::System.Configuration.DefaultSettingValueAttribute("Bremen calling")]
|
||||||
public string APP_TITLE {
|
public string APP_TITLE {
|
||||||
get {
|
get {
|
||||||
return ((string)(this["APP_TITLE"]));
|
return ((string)(this["APP_TITLE"]));
|
||||||
|
|||||||
@ -6,10 +6,10 @@
|
|||||||
<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)">#203864</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</Value>
|
||||||
</Setting>
|
</Setting>
|
||||||
<Setting Name="LOGO_IMAGE_URL" Type="System.String" Scope="Application">
|
<Setting Name="LOGO_IMAGE_URL" Type="System.String" Scope="Application">
|
||||||
<Value Profile="(Default)">https://www.textbausteine.net/</Value>
|
<Value Profile="(Default)">https://www.textbausteine.net/</Value>
|
||||||
|
|||||||
@ -71,26 +71,61 @@ namespace BreCalClient
|
|||||||
name = _agency?.Name;
|
name = _agency?.Name;
|
||||||
if (name != null) agentName = name;
|
if (name != null) agentName = name;
|
||||||
this.labelAgent.Content = name ?? "- / -";
|
this.labelAgent.Content = name ?? "- / -";
|
||||||
|
if(_agency == null)
|
||||||
|
{
|
||||||
|
// clear agency display controls
|
||||||
|
this.labelAgencyBerth.Content = "";
|
||||||
|
this.labelAgencyETAETDValue.Content = "";
|
||||||
|
this.textBlockAgencyRemarks.Text = "";
|
||||||
|
this.textBlockAgencyBerthRemarks.Text = "";
|
||||||
|
}
|
||||||
|
|
||||||
_mooring = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.MOORING);
|
_mooring = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.MOORING);
|
||||||
name = _mooring?.Name;
|
name = _mooring?.Name;
|
||||||
this.labelMooring.Content = name ?? "- / -";
|
this.labelMooring.Content = name ?? "- / -";
|
||||||
|
if(_mooring == null)
|
||||||
|
{
|
||||||
|
this.labelMooringETAETDValue.Content = "";
|
||||||
|
this.textBlockMooringRemarks.Text = "";
|
||||||
|
}
|
||||||
|
|
||||||
_pilot = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.PILOT);
|
_pilot = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.PILOT);
|
||||||
name = _pilot?.Name;
|
name = _pilot?.Name;
|
||||||
this.labelPilot.Content = name ?? "- / - ";
|
this.labelPilot.Content = name ?? "- / - ";
|
||||||
|
if(_pilot == null)
|
||||||
|
{
|
||||||
|
this.labelPilotETAETDValue.Content = "";
|
||||||
|
this.textBlockPilotRemarks.Text = "";
|
||||||
|
}
|
||||||
|
|
||||||
_tug = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.TUG);
|
_tug = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.TUG);
|
||||||
name = _tug?.Name;
|
name = _tug?.Name;
|
||||||
this.labelTug.Content = name ?? "- / - ";
|
this.labelTug.Content = name ?? "- / - ";
|
||||||
|
if(_tug == null)
|
||||||
|
{
|
||||||
|
this.labelTugETAETDValue.Content = "";
|
||||||
|
this.textBlockTugRemarks.Text = "";
|
||||||
|
}
|
||||||
|
|
||||||
_port_administration = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.PORT_ADMINISTRATION);
|
_port_administration = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.PORT_ADMINISTRATION);
|
||||||
name = _port_administration?.Name;
|
name = _port_administration?.Name;
|
||||||
this.labelPortAuthority.Content = name ?? "- / - ";
|
this.labelPortAuthority.Content = name ?? "- / - ";
|
||||||
|
if(_port_administration == null)
|
||||||
|
{
|
||||||
|
this.labelPortAuthorityETAETDValue.Content = "";
|
||||||
|
this.textBlockPortAuthorityRemarks.Text = "";
|
||||||
|
}
|
||||||
|
|
||||||
_terminal = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.TERMINAL);
|
_terminal = this.ShipcallControlModel.GetParticipantForType(Extensions.ParticipantType.TERMINAL);
|
||||||
name = _terminal?.Name;
|
name = _terminal?.Name;
|
||||||
this.labelTerminal.Content = name ?? "- / - ";
|
this.labelTerminal.Content = name ?? "- / - ";
|
||||||
|
if(_terminal == null)
|
||||||
|
{
|
||||||
|
this.textBlockTerminalRemarks.Text = "";
|
||||||
|
this.textBlockTerminalBerthRemarks.Text = "";
|
||||||
|
this.labelTerminalBerth.Content = "";
|
||||||
|
this.labelOperationsStart.Content = "";
|
||||||
|
}
|
||||||
|
|
||||||
if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.TERMINAL) && (App.Participant.Id == _terminal?.Id))
|
if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.TERMINAL) && (App.Participant.Id == _terminal?.Id))
|
||||||
{
|
{
|
||||||
@ -171,9 +206,9 @@ namespace BreCalClient
|
|||||||
ShipcallControlModel.TrafficLightMode resultColor = (ShipcallControlModel.TrafficLightMode) (this.ShipcallControlModel?.Shipcall?.Evaluation ?? 0); // der nullable Operator hier ist so doof, die VS validation blickts einfach nicht
|
ShipcallControlModel.TrafficLightMode resultColor = (ShipcallControlModel.TrafficLightMode) (this.ShipcallControlModel?.Shipcall?.Evaluation ?? 0); // der nullable Operator hier ist so doof, die VS validation blickts einfach nicht
|
||||||
switch (resultColor)
|
switch (resultColor)
|
||||||
{
|
{
|
||||||
case ShipcallControlModel.TrafficLightMode.GREEN:
|
//case ShipcallControlModel.TrafficLightMode.GREEN:
|
||||||
this.Background = Brushes.LightGreen;
|
// this.Background = Brushes.LightGreen;
|
||||||
break;
|
// break;
|
||||||
case ShipcallControlModel.TrafficLightMode.YELLOW:
|
case ShipcallControlModel.TrafficLightMode.YELLOW:
|
||||||
this.Background= Brushes.LightYellow;
|
this.Background= Brushes.LightYellow;
|
||||||
break;
|
break;
|
||||||
@ -222,12 +257,13 @@ 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) && (times.ParticipantType != (int) Extensions.ParticipantType.TERMINAL))
|
||||||
{
|
{
|
||||||
if (this.ShipcallControlModel?.Shipcall?.Type == (int)Extensions.TypeEnum.Incoming)
|
if (this.ShipcallControlModel?.Shipcall?.Type == (int)Extensions.TypeEnum.Incoming)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -52,6 +52,28 @@ namespace BreCalClient
|
|||||||
|
|
||||||
public List<Times> Times { get; set; } = new();
|
public List<Times> Times { get; set; } = new();
|
||||||
|
|
||||||
|
public DateTime? Eta
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
Times? agencyTimes = this.GetTimesForParticipantType(Extensions.ParticipantType.AGENCY);
|
||||||
|
if((agencyTimes != null) && (agencyTimes.EtaBerth != null))
|
||||||
|
return agencyTimes.EtaBerth;
|
||||||
|
return Shipcall?.Eta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime? Etd
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
Times? agencyTimes = this.GetTimesForParticipantType(Extensions.ParticipantType.AGENCY);
|
||||||
|
if ((agencyTimes != null) && (agencyTimes.EtdBerth != null))
|
||||||
|
return agencyTimes.EtdBerth;
|
||||||
|
return Shipcall?.Etd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public TrafficLightMode LightMode
|
public TrafficLightMode LightMode
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -69,6 +91,16 @@ namespace BreCalClient
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string Title
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (this.Shipcall == null) return "";
|
||||||
|
Extensions.TypeEnum callType = (Extensions.TypeEnum) this.Shipcall.Type;
|
||||||
|
return string.Format("{0} {1}", callType, this.Ship?.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region public methods
|
#region public methods
|
||||||
@ -142,6 +174,33 @@ namespace BreCalClient
|
|||||||
await _api.TimesPutAsync(times);
|
await _api.TimesPutAsync(times);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if somebody just removed an assignment it is gone fom AssignedParticipants, but there is still a
|
||||||
|
// times record left which must be removed
|
||||||
|
|
||||||
|
List<Times> deleteTimes = new();
|
||||||
|
foreach (Times times in this.Times)
|
||||||
|
{
|
||||||
|
bool foundTimes = false;
|
||||||
|
foreach (ParticipantAssignment pa in this.AssignedParticipants.Values)
|
||||||
|
{
|
||||||
|
if((pa.ParticipantId == times.ParticipantId) && (pa.Type == times.ParticipantType))
|
||||||
|
{
|
||||||
|
foundTimes = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!foundTimes)
|
||||||
|
{
|
||||||
|
deleteTimes.Add(times);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(Times times in deleteTimes)
|
||||||
|
{
|
||||||
|
_api.TimesDelete(times.Id);
|
||||||
|
this.Times.Remove(times);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -13,6 +13,25 @@ from .api import ships
|
|||||||
from .api import login
|
from .api import login
|
||||||
from .api import user
|
from .api import user
|
||||||
|
|
||||||
|
from BreCal.brecal_utils.file_handling import get_project_root, ensure_path
|
||||||
|
from BreCal.brecal_utils.test_handling import execute_test_with_pytest, execute_coverage_test
|
||||||
|
from BreCal.brecal_utils.time_handling import difference_to_then
|
||||||
|
|
||||||
|
from BreCal.validators.time_logic import TimeLogic
|
||||||
|
from BreCal.validators.validation_rules import ValidationRules
|
||||||
|
from BreCal.validators.schema_validation import validation_state_and_validation_name
|
||||||
|
|
||||||
|
from BreCal.stubs.times_agency import get_times_agency
|
||||||
|
from BreCal.stubs.times_bsmd import get_times_bsmd
|
||||||
|
from BreCal.stubs.times_mooring import get_times_mooring
|
||||||
|
from BreCal.stubs.times_pilot import get_times_pilot
|
||||||
|
from BreCal.stubs.times_portauthority import get_times_port_authority
|
||||||
|
from BreCal.stubs.times_terminal import get_times_terminal
|
||||||
|
from BreCal.stubs.times_tug import get_times_tug
|
||||||
|
from BreCal.stubs.times_full import get_times_full_simple
|
||||||
|
from BreCal.stubs.df_times import get_df_times
|
||||||
|
|
||||||
|
|
||||||
def create_app(test_config=None):
|
def create_app(test_config=None):
|
||||||
|
|
||||||
app = Flask(__name__, instance_relative_config=True)
|
app = Flask(__name__, instance_relative_config=True)
|
||||||
@ -47,22 +66,24 @@ def create_app(test_config=None):
|
|||||||
|
|
||||||
return app
|
return app
|
||||||
|
|
||||||
from BreCal.brecal_utils.file_handling import get_project_root, ensure_path
|
|
||||||
from BreCal.brecal_utils.test_handling import execute_test_with_pytest, execute_coverage_test
|
|
||||||
from BreCal.brecal_utils.time_handling import difference_to_then
|
|
||||||
|
|
||||||
from BreCal.validators.time_logic import TimeLogic
|
|
||||||
from BreCal.validators.validation_rules import ValidationRules
|
|
||||||
from BreCal.validators.schema_validation import validation_state_and_validation_name
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"get_project_root",
|
"get_project_root",
|
||||||
"ensure_path",
|
"ensure_path",
|
||||||
"execute_test_with_pytest",
|
"execute_test_with_pytest",
|
||||||
"execute_coverage_test",
|
"execute_coverage_test",
|
||||||
"difference_to_then",
|
"difference_to_then",
|
||||||
"TimeLogic",
|
"TimeLogic",
|
||||||
"ValidationRules",
|
"ValidationRules",
|
||||||
"validation_state_and_validation_name",
|
"validation_state_and_validation_name",
|
||||||
|
|
||||||
|
"get_times_agency",
|
||||||
|
"get_times_bsmd",
|
||||||
|
"get_times_mooring",
|
||||||
|
"get_times_pilot",
|
||||||
|
"get_times_port_authority",
|
||||||
|
"get_times_terminal",
|
||||||
|
"get_times_tug",
|
||||||
|
"get_times_full_simple",
|
||||||
|
"get_df_times",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,7 @@ class SQLHandler():
|
|||||||
with self.sql_connection.cursor(buffered=True) as cursor:
|
with self.sql_connection.cursor(buffered=True) as cursor:
|
||||||
cursor.execute("SHOW TABLES")
|
cursor.execute("SHOW TABLES")
|
||||||
schema = cursor.fetchall()
|
schema = cursor.fetchall()
|
||||||
all_schemas = [schem[0] for schem in schema]
|
all_schemas = [schem[0] for schem in schema]
|
||||||
return all_schemas
|
return all_schemas
|
||||||
|
|
||||||
def build_str_to_model_dict(self):
|
def build_str_to_model_dict(self):
|
||||||
@ -42,13 +42,51 @@ class SQLHandler():
|
|||||||
|
|
||||||
def read_mysql_table_to_df(self, table_name:str):
|
def read_mysql_table_to_df(self, table_name:str):
|
||||||
"""determine a {table_name}, which will be read from a mysql server. returns a pandas DataFrame with the respective data"""
|
"""determine a {table_name}, which will be read from a mysql server. returns a pandas DataFrame with the respective data"""
|
||||||
df = pd.read_sql(sql=f"SELECT * FROM {table_name}", con=self.sql_connection)
|
with self.sql_connection.cursor(buffered=True) as cursor: #df = pd.read_sql(sql=f"SELECT * FROM {table_name}", con=self.sql_connection)
|
||||||
|
# 1.) get the column names
|
||||||
|
cursor.execute(f"DESCRIBE {table_name}")
|
||||||
|
cols = cursor.fetchall()
|
||||||
|
column_names = [col_name[0] for col_name in cols]
|
||||||
|
|
||||||
|
# 2.) get the data tuples
|
||||||
|
cursor.execute(f"SELECT * FROM {table_name}")
|
||||||
|
data = cursor.fetchall()
|
||||||
|
|
||||||
|
# 3.) map the data tuples to the correct column names
|
||||||
|
data = [{k:v for k,v in zip(column_names, dat)} for dat in data]
|
||||||
|
|
||||||
|
# 4.) build a dataframe from the respective data models (which ensures the correct data type)
|
||||||
|
data_model = self.str_to_model_dict.get(table_name)
|
||||||
|
if data_model is not None:
|
||||||
|
df = pd.DataFrame([data_model(**dat) for dat in data])
|
||||||
|
else:
|
||||||
|
df = pd.DataFrame([dat for dat in data])
|
||||||
return df
|
return df
|
||||||
|
|
||||||
def mysql_to_df(self, query):
|
def mysql_to_df(self, query, table_name):
|
||||||
"""provide an arbitrary sql query that should be read from a mysql server {sql_connection}. returns a pandas DataFrame with the obtained data"""
|
"""provide an arbitrary sql query that should be read from a mysql server {sql_connection}. returns a pandas DataFrame with the obtained data"""
|
||||||
df = pd.read_sql(query, self.sql_connection).convert_dtypes()
|
with self.sql_connection.cursor(buffered=True) as cursor: # df = pd.read_sql(query, self.sql_connection).convert_dtypes()
|
||||||
df = df.set_index('id', inplace=False) # avoid inplace updates, so the raw sql remains unchanged
|
# 1.) get the column names
|
||||||
|
cursor.execute(f"DESCRIBE {table_name}")
|
||||||
|
cols = cursor.fetchall()
|
||||||
|
column_names = [col_name[0] for col_name in cols]
|
||||||
|
|
||||||
|
# 2.) get the data tuples
|
||||||
|
cursor.execute(query)
|
||||||
|
data = cursor.fetchall()
|
||||||
|
|
||||||
|
# 3.) map the data tuples to the correct column names
|
||||||
|
data = [{k:v for k,v in zip(column_names, dat)} for dat in data]
|
||||||
|
|
||||||
|
# 4.) build a dataframe from the respective data models (which ensures the correct data type)
|
||||||
|
data_model = self.str_to_model_dict.get(table_name)
|
||||||
|
if data_model is not None:
|
||||||
|
df = pd.DataFrame([data_model(**dat) for dat in data])
|
||||||
|
else:
|
||||||
|
df = pd.DataFrame([dat for dat in data])
|
||||||
|
|
||||||
|
if 'id' in df.columns:
|
||||||
|
df = df.set_index('id', inplace=False) # avoid inplace updates, so the raw sql remains unchanged
|
||||||
return df
|
return df
|
||||||
|
|
||||||
def read_all(self, all_schemas):
|
def read_all(self, all_schemas):
|
||||||
@ -64,7 +102,7 @@ class SQLHandler():
|
|||||||
mysql_df_dict = {}
|
mysql_df_dict = {}
|
||||||
for schem in all_schemas:
|
for schem in all_schemas:
|
||||||
query = f"SELECT * FROM {schem}"
|
query = f"SELECT * FROM {schem}"
|
||||||
mysql_df_dict[schem] = self.mysql_to_df(query)
|
mysql_df_dict[schem] = self.mysql_to_df(query, table_name=schem)
|
||||||
return mysql_df_dict
|
return mysql_df_dict
|
||||||
|
|
||||||
def initialize_shipcall_participant_list(self):
|
def initialize_shipcall_participant_list(self):
|
||||||
@ -183,6 +221,9 @@ class SQLHandler():
|
|||||||
|
|
||||||
# filter out all NaN and NaT entries
|
# filter out all NaN and NaT entries
|
||||||
if non_null_column is not None:
|
if non_null_column is not None:
|
||||||
|
# in the Pandas documentation, it says for .isnull():
|
||||||
|
# "This function takes a scalar or array-like object and indicates whether values are missing
|
||||||
|
# (NaN in numeric arrays, None or NaN in object arrays, NaT in datetimelike)."
|
||||||
df_times = df_times.loc[~df_times[non_null_column].isnull()] # NOT null filter
|
df_times = df_times.loc[~df_times[non_null_column].isnull()] # NOT null filter
|
||||||
|
|
||||||
# filter by the agency participant_type
|
# filter by the agency participant_type
|
||||||
@ -192,13 +233,20 @@ class SQLHandler():
|
|||||||
def filter_df_by_key_value(self, df, key, value)->pd.DataFrame:
|
def filter_df_by_key_value(self, df, key, value)->pd.DataFrame:
|
||||||
return df.loc[df[key]==value]
|
return df.loc[df[key]==value]
|
||||||
|
|
||||||
def get_unique_ship_counts(self, all_df_times:pd.DataFrame, query:str, rounding:str="min", maximum_threshold=3):
|
def get_unique_ship_counts(self, all_df_times:pd.DataFrame, times_agency:pd.DataFrame, query:str, rounding:str="min", maximum_threshold=3):
|
||||||
"""given a dataframe of all agency times, get all unique ship counts, their values (datetime) and the string tags. returns a tuple (values,unique,counts)"""
|
"""given a dataframe of all agency times, get all unique ship counts, their values (datetime) and the string tags. returns a tuple (values,unique,counts)"""
|
||||||
# get values and optional: rounding
|
# optional: rounding
|
||||||
values = all_df_times.loc[:, query]
|
|
||||||
if rounding is not None:
|
if rounding is not None:
|
||||||
values = values.dt.round(rounding) # e.g., 'min'
|
all_df_times.loc[:, query] = all_df_times.loc[:, query].dt.round(rounding) # e.g., 'min'
|
||||||
|
query_time_agency = times_agency[query].iloc[0].round(rounding)# e.g., 'min'
|
||||||
|
|
||||||
unique, counts = np.unique(values, return_counts=True)
|
# after rounding, filter {all_df_times}, so only those, which match the current query are of interest
|
||||||
violation_state = np.any(np.greater(counts, maximum_threshold))
|
# takes 'times_agency' to sample, which value should match
|
||||||
return (values, unique, counts)
|
all_df_times = all_df_times.loc[all_df_times[query]==query_time_agency]
|
||||||
|
|
||||||
|
# finally, count all remaining entries
|
||||||
|
values = all_df_times.loc[:, query]
|
||||||
|
|
||||||
|
# get unique entries and counts
|
||||||
|
counts = len(values) # unique, counts = np.unique(values, return_counts=True)
|
||||||
|
return counts # (values, unique, counts)
|
||||||
|
|||||||
@ -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:
|
||||||
|
|||||||
@ -21,8 +21,8 @@ def GetShipcalls(options):
|
|||||||
commands = pydapper.using(pooledConnection)
|
commands = pydapper.using(pooledConnection)
|
||||||
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 ((type = 1 OR type = 2) AND eta >= DATE(NOW() - INTERVAL %d 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)"
|
||||||
"OR (type = 3 AND etd >= DATE(NOW() - INTERVAL %d DAY))) "
|
"OR (type = 2 AND etd >= DATE(NOW() - INTERVAL %d DAY))) "
|
||||||
"ORDER BY eta") % (options["past_days"], options["past_days"])
|
"ORDER BY eta") % (options["past_days"], options["past_days"])
|
||||||
|
|
||||||
data = commands.query(query, model=model.Shipcall)
|
data = commands.query(query, model=model.Shipcall)
|
||||||
|
|||||||
@ -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_prod.json');
|
||||||
|
|
||||||
print (config_path)
|
print (config_path)
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,6 @@ def obj_dict(obj):
|
|||||||
class Berth(Schema):
|
class Berth(Schema):
|
||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
participant_id: int
|
|
||||||
lock: bool
|
lock: bool
|
||||||
owner_id: int
|
owner_id: int
|
||||||
authority_id: int
|
authority_id: int
|
||||||
|
|||||||
@ -3,3 +3,4 @@ def generate_uuid1_int():
|
|||||||
"""# TODO: clarify, what kind of integer ID is used in mysql. Generates a proxy ID, which is used in the stubs"""
|
"""# TODO: clarify, what kind of integer ID is used in mysql. Generates a proxy ID, which is used in the stubs"""
|
||||||
from uuid import uuid1
|
from uuid import uuid1
|
||||||
return uuid1().int>>64
|
return uuid1().int>>64
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,6 @@ def get_berth_simple():
|
|||||||
|
|
||||||
# Note: #TODO: name, participant_id & lock state are arbitrary
|
# Note: #TODO: name, participant_id & lock state are arbitrary
|
||||||
name = "Avangard Dalben"
|
name = "Avangard Dalben"
|
||||||
participant_id = 1# e.g., Avangard
|
|
||||||
lock = False
|
lock = False
|
||||||
owner_id = 1 # e.g., Avangard
|
owner_id = 1 # e.g., Avangard
|
||||||
authority_id = 1 # e.g., Avangard
|
authority_id = 1 # e.g., Avangard
|
||||||
@ -19,7 +18,6 @@ def get_berth_simple():
|
|||||||
berth = Berth(
|
berth = Berth(
|
||||||
berth_id,
|
berth_id,
|
||||||
name,
|
name,
|
||||||
participant_id,
|
|
||||||
lock,
|
lock,
|
||||||
owner_id,
|
owner_id,
|
||||||
authority_id,
|
authority_id,
|
||||||
|
|||||||
78
src/server/BreCal/stubs/df_times.py
Normal file
78
src/server/BreCal/stubs/df_times.py
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import pandas as pd
|
||||||
|
import random
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
from BreCal.stubs.times_agency import get_times_agency
|
||||||
|
from BreCal.stubs.times_bsmd import get_times_bsmd
|
||||||
|
from BreCal.stubs.times_mooring import get_times_mooring
|
||||||
|
from BreCal.stubs.times_pilot import get_times_pilot
|
||||||
|
from BreCal.stubs.times_portauthority import get_times_port_authority
|
||||||
|
from BreCal.stubs.times_terminal import get_times_terminal
|
||||||
|
from BreCal.stubs.times_tug import get_times_tug
|
||||||
|
from BreCal.database.enums import ParticipantType
|
||||||
|
|
||||||
|
def get_df_times(shipcall=None):
|
||||||
|
"""in case of providing a shipcall, one can read the id to set each times entry in the dataframe towards that shipcall id"""
|
||||||
|
df_times = pd.DataFrame([
|
||||||
|
fct()
|
||||||
|
|
||||||
|
for fct in [
|
||||||
|
get_times_agency,
|
||||||
|
get_times_bsmd,
|
||||||
|
get_times_mooring,
|
||||||
|
get_times_pilot,
|
||||||
|
get_times_port_authority,
|
||||||
|
get_times_terminal,
|
||||||
|
get_times_tug
|
||||||
|
]
|
||||||
|
])
|
||||||
|
if shipcall is not None:
|
||||||
|
df_times.loc[:,"shipcall_id"] = shipcall.id
|
||||||
|
return df_times
|
||||||
|
|
||||||
|
def random_time_perturbation(df_times, query):
|
||||||
|
# random perturbations
|
||||||
|
population = [datetime.datetime.now(), None, pd.NaT]
|
||||||
|
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, query] = random.sample(population,k=1)[0]
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.MOORING.value, query] = random.sample(population,k=1)[0]
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.PORT_ADMINISTRATION.value, query] = random.sample(population,k=1)[0]
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.PILOT.value, query] = random.sample(population,k=1)[0]
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.TUG.value, query] = random.sample(population,k=1)[0]
|
||||||
|
return df_times
|
||||||
|
|
||||||
|
def get_df_times_participants_disagree(query, shipcall=None, df_times = None):
|
||||||
|
if df_times is None:
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
df_times = random_time_perturbation(df_times=df_times, query=query)
|
||||||
|
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, query] = datetime.datetime.now()+datetime.timedelta(hours=2, minutes=14)
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.PILOT.value, query] = datetime.datetime.now()+datetime.timedelta(hours=1, minutes=7)
|
||||||
|
|
||||||
|
return df_times
|
||||||
|
|
||||||
|
def build_stub_df_times(shipcall, query, reference_time):
|
||||||
|
"""creates an artificial dataset, which simulates having too many shipcalls with too many identical times"""
|
||||||
|
df_times_a = get_df_times(shipcall)
|
||||||
|
df_times_a = df_times_a.loc[df_times_a["participant_type"]==ParticipantType.AGENCY.value]
|
||||||
|
df_times_a.loc[:,query] = reference_time + datetime.timedelta(seconds=17)
|
||||||
|
|
||||||
|
df_times_b = get_df_times(shipcall)
|
||||||
|
df_times_b = df_times_b.loc[df_times_b["participant_type"]==ParticipantType.AGENCY.value]
|
||||||
|
df_times_b.loc[:,query] = reference_time + datetime.timedelta(seconds=21)
|
||||||
|
|
||||||
|
df_times_c = get_df_times(shipcall)
|
||||||
|
df_times_c = df_times_c.loc[df_times_c["participant_type"]==ParticipantType.AGENCY.value]
|
||||||
|
df_times_c.loc[:,query] = reference_time + datetime.timedelta(seconds=26)
|
||||||
|
|
||||||
|
df_times_d = get_df_times(shipcall)
|
||||||
|
df_times_d = df_times_d.loc[df_times_d["participant_type"]==ParticipantType.AGENCY.value]
|
||||||
|
df_times_d.loc[:,query] = reference_time + datetime.timedelta(seconds=28)
|
||||||
|
|
||||||
|
df_times_e = get_df_times(shipcall)
|
||||||
|
df_times_e = df_times_e.loc[df_times_e["participant_type"]==ParticipantType.AGENCY.value]
|
||||||
|
df_times_e.loc[:,query] = reference_time + datetime.timedelta(seconds=29)
|
||||||
|
|
||||||
|
return pd.concat([df_times_a, df_times_b, df_times_c, df_times_d, df_times_e],axis=0)
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
from BreCal.stubs.times_full import get_times_full_simple
|
||||||
|
from BreCal.database.enums import ParticipantType
|
||||||
|
|
||||||
|
def get_times_agency():
|
||||||
|
times_agency = get_times_full_simple()
|
||||||
|
times_agency.participant_type = ParticipantType.AGENCY.value
|
||||||
|
return times_agency
|
||||||
|
|
||||||
8
src/server/BreCal/stubs/times_bsmd.py
Normal file
8
src/server/BreCal/stubs/times_bsmd.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
from BreCal.stubs.times_full import get_times_full_simple
|
||||||
|
from BreCal.database.enums import ParticipantType
|
||||||
|
|
||||||
|
def get_times_bsmd():
|
||||||
|
times_bsmd = get_times_full_simple()
|
||||||
|
times_bsmd.participant_type = ParticipantType.BSMD.value
|
||||||
|
return times_bsmd
|
||||||
|
|
||||||
@ -3,9 +3,11 @@ this stub creates an example time object, where the times of every role are pres
|
|||||||
users will thereby be able to modify these values
|
users will thereby be able to modify these values
|
||||||
"""
|
"""
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from BreCal.stubs import generate_uuid1_int
|
from BreCal.stubs import generate_uuid1_int
|
||||||
from BreCal.schemas.model import Times
|
from BreCal.schemas.model import Times
|
||||||
|
|
||||||
|
|
||||||
def get_times_full_simple():
|
def get_times_full_simple():
|
||||||
# only used for the stub
|
# only used for the stub
|
||||||
base_time = datetime.datetime.now()
|
base_time = datetime.datetime.now()
|
||||||
@ -65,3 +67,5 @@ def get_times_full_simple():
|
|||||||
modified=modified,
|
modified=modified,
|
||||||
)
|
)
|
||||||
return times
|
return times
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,8 @@
|
|||||||
|
from BreCal.stubs.times_full import get_times_full_simple
|
||||||
|
from BreCal.database.enums import ParticipantType
|
||||||
|
|
||||||
|
def get_times_mooring():
|
||||||
|
times_mooring = get_times_full_simple()
|
||||||
|
times_mooring.participant_type = ParticipantType.MOORING.value
|
||||||
|
return times_mooring
|
||||||
|
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
from BreCal.stubs.times_full import get_times_full_simple
|
||||||
|
from BreCal.database.enums import ParticipantType
|
||||||
|
|
||||||
|
def get_times_pilot():
|
||||||
|
times_pilot = get_times_full_simple()
|
||||||
|
times_pilot.participant_type = ParticipantType.PILOT.value
|
||||||
|
return times_pilot
|
||||||
|
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
from BreCal.stubs.times_full import get_times_full_simple
|
||||||
|
from BreCal.database.enums import ParticipantType
|
||||||
|
|
||||||
|
def get_times_port_authority():
|
||||||
|
times_port_authority = get_times_full_simple()
|
||||||
|
times_port_authority.participant_type = ParticipantType.PORT_ADMINISTRATION.value
|
||||||
|
return times_port_authority
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
from BreCal.stubs.times_full import get_times_full_simple
|
||||||
|
from BreCal.database.enums import ParticipantType
|
||||||
|
|
||||||
|
def get_times_terminal():
|
||||||
|
times_terminal = get_times_full_simple()
|
||||||
|
times_terminal.participant_type = ParticipantType.TERMINAL.value
|
||||||
|
return times_terminal
|
||||||
|
|
||||||
8
src/server/BreCal/stubs/times_tug.py
Normal file
8
src/server/BreCal/stubs/times_tug.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
from BreCal.stubs.times_full import get_times_full_simple
|
||||||
|
from BreCal.database.enums import ParticipantType
|
||||||
|
|
||||||
|
def get_times_tug():
|
||||||
|
times_tug = get_times_full_simple()
|
||||||
|
times_tug.participant_type = ParticipantType.TUG.value
|
||||||
|
return times_tug
|
||||||
|
|
||||||
@ -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:
|
||||||
"""
|
"""
|
||||||
@ -26,17 +73,22 @@ class ValidationRuleBaseFunctions():
|
|||||||
when the query_time lays in the future, the delta is positive
|
when the query_time lays in the future, the delta is positive
|
||||||
|
|
||||||
returns a violation state depending on whether the delta is
|
returns a violation state depending on whether the delta is
|
||||||
Violation, if: 0 >= delta > threshold
|
Violation, if: 0 >= delta <= threshold
|
||||||
|
|
||||||
When the key time is defined (not None), there is no violation. Returns False
|
When the key time is defined (not None), there is no violation. Returns False
|
||||||
|
|
||||||
options:
|
options:
|
||||||
query_time: will be used to measure the time difference of 'now' until the query time
|
query_time: will be used to measure the time difference of 'now' until the query time
|
||||||
key_time: will be used to check, whether the respective key already has a value
|
key_time: will be used to check, whether the respective key already has a value
|
||||||
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 (minutes)
|
||||||
"""
|
"""
|
||||||
# rule is not applicable -> return 'GREEN'
|
# rule is not applicable -> return 'GREEN'
|
||||||
if key_time is not None:
|
# rule is only applicable, when 'key_time' is not defined (neither None, nor pd.NaT)
|
||||||
|
if (key_time is not None) and (key_time is not pd.NaT):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# when query_time is not valid, the rule cannot be applied
|
||||||
|
if 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
|
||||||
@ -44,7 +96,7 @@ class ValidationRuleBaseFunctions():
|
|||||||
|
|
||||||
# a violation occurs, when the delta (in minutes) exceeds the specified threshold of a participant
|
# a violation occurs, when the delta (in minutes) exceeds the specified threshold of a participant
|
||||||
# to prevent past-events from triggering violations, negative values are ignored
|
# to prevent past-events from triggering violations, negative values are ignored
|
||||||
# Violation, if 0 >= delta >= threshold
|
# Violation, if 0 <= delta <= threshold
|
||||||
violation_state = (delta >= 0) and (delta<=threshold)
|
violation_state = (delta >= 0) and (delta<=threshold)
|
||||||
return violation_state
|
return violation_state
|
||||||
|
|
||||||
@ -76,7 +128,7 @@ class ValidationRuleBaseFunctions():
|
|||||||
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 and consider only pd.Timestamp entries (which ignores pd.NaT/null entries)
|
# exclude missing entries and consider only pd.Timestamp entries (which ignores pd.NaT/null entries)
|
||||||
estimated_times = [type(time_) for time_ in df_times.loc[:,query].tolist() if isinstance(time_, pd.Timestamp)] # df_times = 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
|
# 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'
|
# '15min' rounds to 'every 15 minutes'. E.g., '2023-09-22 08:18:49' becomes '2023-09-22 08:15:00'
|
||||||
@ -94,7 +146,7 @@ class ValidationRuleBaseFunctions():
|
|||||||
violation_state = n_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, times_agency:pd.DataFrame, rounding="min", maximum_threshold=3, all_times_agency=None)->bool:
|
||||||
"""
|
"""
|
||||||
# base function for all validation rules in the group {0005} A&B
|
# base function for all validation rules in the group {0005} A&B
|
||||||
|
|
||||||
@ -103,15 +155,21 @@ class ValidationRuleBaseFunctions():
|
|||||||
"""
|
"""
|
||||||
# filter the df: keep only times_agents
|
# filter the df: keep only times_agents
|
||||||
# filter out all NaN and NaT entries
|
# filter out all NaN and NaT entries
|
||||||
times_agency = self.sql_handler.get_times_for_agency(non_null_column=query)
|
if all_times_agency is None:
|
||||||
|
all_times_agency = self.sql_handler.get_times_for_agency(non_null_column=query)
|
||||||
|
|
||||||
# get values and optionally round the values
|
# get values and optionally round the values (internally)
|
||||||
(values, unique, counts) = self.sql_handler.get_unique_ship_counts(all_df_times=times_agency, query=query, rounding=rounding, maximum_threshold=maximum_threshold)
|
counts = self.sql_handler.get_unique_ship_counts(all_df_times=all_times_agency, times_agency=times_agency, query=query, rounding=rounding, maximum_threshold=maximum_threshold)
|
||||||
|
|
||||||
# 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
|
||||||
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):
|
||||||
"""
|
"""
|
||||||
@ -466,12 +524,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'.
|
||||||
"""
|
"""
|
||||||
@ -595,11 +653,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)
|
||||||
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
|
||||||
violation_state = times_terminal.operations_start<times_agency.eta_berth
|
violation_state = times_terminal.operations_start < times_agency.eta_berth
|
||||||
|
|
||||||
if violation_state:
|
if violation_state:
|
||||||
validation_name = inspect.currentframe().f_code.co_name
|
validation_name = inspect.currentframe().f_code.co_name
|
||||||
@ -607,7 +665,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
|
||||||
@ -624,7 +682,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
|
||||||
@ -651,11 +709,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:
|
||||||
@ -679,11 +737,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.etd_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,15 +750,20 @@ class ValidationRuleFunctions(ValidationRuleBaseFunctions):
|
|||||||
else:
|
else:
|
||||||
return (StatusFlags.GREEN, None)
|
return (StatusFlags.GREEN, None)
|
||||||
|
|
||||||
def validation_rule_fct_too_many_identical_eta_times(self, shipcall, df_times, rounding = "min", maximum_threshold = 3, *args, **kwargs):
|
def validation_rule_fct_too_many_identical_eta_times(self, shipcall, df_times, rounding = "min", maximum_threshold = 3, all_times_agency=None, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Code: #0005-A
|
Code: #0005-A
|
||||||
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.
|
||||||
"""
|
"""
|
||||||
|
times_agency = df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value]
|
||||||
|
# check, if the header is filled in (agency)
|
||||||
|
if len(times_agency) != 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, times_agency=times_agency, rounding=rounding, maximum_threshold=maximum_threshold, all_times_agency=all_times_agency)
|
||||||
|
|
||||||
if violation_state:
|
if violation_state:
|
||||||
validation_name = inspect.currentframe().f_code.co_name
|
validation_name = inspect.currentframe().f_code.co_name
|
||||||
@ -708,15 +771,20 @@ class ValidationRuleFunctions(ValidationRuleBaseFunctions):
|
|||||||
else:
|
else:
|
||||||
return (StatusFlags.GREEN, None)
|
return (StatusFlags.GREEN, None)
|
||||||
|
|
||||||
def validation_rule_fct_too_many_identical_etd_times(self, shipcall, df_times, rounding = "min", maximum_threshold = 3, *args, **kwargs):
|
def validation_rule_fct_too_many_identical_etd_times(self, shipcall, df_times, rounding = "min", maximum_threshold = 3, all_times_agency=None, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Code: #0005-B
|
Code: #0005-B
|
||||||
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.
|
||||||
"""
|
"""
|
||||||
|
times_agency = df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value]
|
||||||
|
# check, if the header is filled in (agency)
|
||||||
|
if len(times_agency) != 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, times_agency=times_agency, rounding=rounding, maximum_threshold=maximum_threshold, all_times_agency=all_times_agency)
|
||||||
|
|
||||||
if violation_state:
|
if violation_state:
|
||||||
validation_name = inspect.currentframe().f_code.co_name
|
validation_name = inspect.currentframe().f_code.co_name
|
||||||
@ -737,6 +805,18 @@ 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)
|
||||||
|
|
||||||
|
# when one of the two values is null, the state is GREEN
|
||||||
|
if (pd.isnull(times_agency.berth_id)) or (pd.isnull(times_terminal.berth_id)):
|
||||||
|
return (StatusFlags.GREEN, None)
|
||||||
|
|
||||||
|
if shipcall.type in [ShipcallType.OUTGOING.value, ShipcallType.SHIFTING.value]:
|
||||||
|
return (StatusFlags.GREEN, None)
|
||||||
|
|
||||||
|
# only incoming shipcalls matter. The other ones are not relevant for the berth selection
|
||||||
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:
|
||||||
@ -758,6 +838,18 @@ 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)
|
||||||
|
|
||||||
|
# when one of the two values is null, the state is GREEN
|
||||||
|
if (pd.isnull(times_agency.pier_side)) or (pd.isnull(times_terminal.pier_side)):
|
||||||
|
return (StatusFlags.GREEN, None)
|
||||||
|
|
||||||
|
# only incoming shipcalls matter. The other ones are not relevant for the pier_side selection
|
||||||
|
if shipcall.type in [ShipcallType.OUTGOING.value, ShipcallType.SHIFTING.value]:
|
||||||
|
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:
|
||||||
|
|||||||
@ -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.
|
||||||
|
|||||||
@ -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/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
|
||||||
|
|||||||
@ -44,7 +44,7 @@ def test_import_webargs():
|
|||||||
from webargs.flaskparser import parser
|
from webargs.flaskparser import parser
|
||||||
return
|
return
|
||||||
|
|
||||||
def test_import_mashmallow():
|
def test_import_marshmallow():
|
||||||
"""currently used in ~/brecal/src/server/BreCal/api/shipcalls.py"""
|
"""currently used in ~/brecal/src/server/BreCal/api/shipcalls.py"""
|
||||||
import marshmallow
|
import marshmallow
|
||||||
from marshmallow import Schema, fields
|
from marshmallow import Schema, fields
|
||||||
|
|||||||
@ -1,7 +1,13 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
import datetime
|
||||||
|
import pandas as pd
|
||||||
from BreCal.validators.validation_rule_functions import ValidationRuleFunctions
|
from BreCal.validators.validation_rule_functions import ValidationRuleFunctions
|
||||||
from BreCal.validators.validation_rules import ValidationRules
|
from BreCal.validators.validation_rules import ValidationRules
|
||||||
from BreCal.database.sql_handler import SQLHandler
|
from BreCal.database.sql_handler import SQLHandler
|
||||||
|
from BreCal.database.enums import ParticipantwiseTimeDelta, ParticipantType, StatusFlags, ShipcallType
|
||||||
|
|
||||||
|
from BreCal.stubs.shipcall import get_shipcall_simple
|
||||||
|
from BreCal.stubs.df_times import get_df_times, random_time_perturbation, get_df_times_participants_disagree, build_stub_df_times
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
def build_sql_proxy_connection():
|
def build_sql_proxy_connection():
|
||||||
@ -25,38 +31,796 @@ def test_build_validation_rule_functions(build_sql_proxy_connection):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_check_time_delta_violation_query_time_to_now_key_time_is_defined(build_sql_proxy_connection):
|
||||||
def test_validation_rule_fct_agency_and_terminal_pier_side_disagreement(build_sql_proxy_connection):
|
|
||||||
"""#0006-A validation_rule_fct_agency_and_terminal_pier_side_disagreement"""
|
|
||||||
import pandas as pd
|
|
||||||
|
|
||||||
from BreCal.stubs.times_full import get_times_full_simple
|
|
||||||
from BreCal.stubs.shipcall import get_shipcall_simple
|
|
||||||
from BreCal.database.enums import ParticipantType
|
|
||||||
from BreCal.database.enums import StatusFlags
|
|
||||||
|
|
||||||
vr = build_sql_proxy_connection["vr"]
|
vr = build_sql_proxy_connection["vr"]
|
||||||
shipcall = get_shipcall_simple()
|
|
||||||
t1 = get_times_full_simple()
|
|
||||||
t2 = get_times_full_simple()
|
|
||||||
|
|
||||||
# roles: agency & terminal
|
# ship arrives in three hours, while the threshold for an alert is (e.g.) 5 hours
|
||||||
t1.participant_type = ParticipantType.AGENCY.value
|
# key time is given, so the function should always return False (no violation)
|
||||||
t2.participant_type = ParticipantType.TERMINAL.value
|
query_time = datetime.datetime.now() + datetime.timedelta(hours=3)
|
||||||
|
key_time = datetime.datetime.now() + datetime.timedelta(hours=7, minutes=30)
|
||||||
|
|
||||||
# disagreement
|
threshold = 60*5
|
||||||
t1.pier_side = True
|
violation_state = vr.check_time_delta_violation_query_time_to_now(query_time=query_time, key_time=key_time, threshold=threshold)
|
||||||
t2.pier_side = False
|
assert not violation_state, f"the key time is filled in, so there should not be a violation"
|
||||||
|
|
||||||
time_objects = [t1, t2]
|
|
||||||
df_times = pd.DataFrame.from_records([to_.__dict__ for to_ in time_objects])
|
|
||||||
df_times.set_index('id',inplace=True)
|
|
||||||
|
|
||||||
(state, description) = vr.validation_rule_fct_agency_and_terminal_pier_side_disagreement(shipcall, df_times)
|
|
||||||
assert state.value > StatusFlags.GREEN.value, f"a violation must be identified"
|
|
||||||
assert description is not None, f"a violation description must be identified"
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def test_check_time_delta_violation_query_time_to_now_no_key_time_but_event_in_distant_future(build_sql_proxy_connection):
|
||||||
|
vr = build_sql_proxy_connection["vr"]
|
||||||
|
|
||||||
|
# ship arrives in three hours, while the threshold for an alert is (e.g.) 5 hours
|
||||||
|
# key time is given, so the function should always return False (no violation)
|
||||||
|
# query time (-> delta) & threshold have the same time -> no violation
|
||||||
|
query_time = datetime.datetime.now() + datetime.timedelta(hours=5, seconds=10) # when the delta & threshold are identical, microseconds between checking the time and defining it here, raise the violation
|
||||||
|
key_time = None
|
||||||
|
|
||||||
|
threshold = 60*5
|
||||||
|
violation_state = vr.check_time_delta_violation_query_time_to_now(query_time=query_time, key_time=key_time, threshold=threshold)
|
||||||
|
assert not violation_state, f"the event is still far enough away, so there should not be a violation."
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_check_time_delta_violation_query_time_to_now_key_time_is_none(build_sql_proxy_connection):
|
||||||
|
vr = build_sql_proxy_connection["vr"]
|
||||||
|
|
||||||
|
# ship arrives in three hours, while the threshold for an alert is (e.g.) 5 hours
|
||||||
|
# key time is given, so the function should always return False (no violation)
|
||||||
|
query_time = datetime.datetime.now() + datetime.timedelta(hours=3)
|
||||||
|
key_time = None
|
||||||
|
|
||||||
|
threshold = 60*5 # minutes
|
||||||
|
violation_state = vr.check_time_delta_violation_query_time_to_now(query_time=query_time, key_time=key_time, threshold=threshold)
|
||||||
|
assert violation_state, f"when the key time is not filled in and the query time is 'dangerously close', there should be a violation to indicate the traffic state"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_check_time_delta_violation_query_time_to_now_key_time_is_pd_nat(build_sql_proxy_connection):
|
||||||
|
vr = build_sql_proxy_connection["vr"]
|
||||||
|
|
||||||
|
# ship arrives in three hours, while the threshold for an alert is (e.g.) 5 hours
|
||||||
|
# key time is given, so the function should always return False (no violation)
|
||||||
|
query_time = datetime.datetime.now() + datetime.timedelta(hours=3)
|
||||||
|
key_time = pd.NaT
|
||||||
|
|
||||||
|
threshold = 60*5 # minutes
|
||||||
|
violation_state = vr.check_time_delta_violation_query_time_to_now(query_time=query_time, key_time=key_time, threshold=threshold)
|
||||||
|
assert violation_state, f"when the key time is not filled in and the query time is 'dangerously close', there should be a violation to indicate the traffic state"
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_validation_rule_fct_missing_time_agency_berth_eta__missing_time_agency_no_violation(build_sql_proxy_connection):
|
||||||
|
"""0001-A validation_rule_fct_missing_time_agency_berth_eta"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
# artificially remove the agency, so the function is properly checked
|
||||||
|
df_times = df_times.loc[df_times["participant_type"]!=ParticipantType.AGENCY.value]
|
||||||
|
|
||||||
|
# apply the validation rule
|
||||||
|
(state, msg) = vr.validation_rule_fct_missing_time_agency_berth_eta(shipcall=shipcall, df_times=df_times)
|
||||||
|
|
||||||
|
# expectation: green state, no msg
|
||||||
|
assert state==StatusFlags.GREEN, f"function should return 'green', because the agency's entry is not present"
|
||||||
|
assert msg is None, f"with a 'green' state, there should be no message returned"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_missing_time_agency_berth_eta__shipcall_eta_dangerously_close_no_times_agency(build_sql_proxy_connection):
|
||||||
|
"""0001-A validation_rule_fct_missing_time_agency_berth_eta"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
# the shipcall happens 'soon'
|
||||||
|
shipcall.eta = datetime.datetime.now() + datetime.timedelta(minutes=ParticipantwiseTimeDelta.AGENCY-10)
|
||||||
|
|
||||||
|
# set times agency to be undetermined
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "eta_berth"] = None
|
||||||
|
|
||||||
|
# apply the validation rule
|
||||||
|
(state, msg) = vr.validation_rule_fct_missing_time_agency_berth_eta(shipcall=shipcall, df_times=df_times)
|
||||||
|
|
||||||
|
# expectation: green state, no msg
|
||||||
|
assert state==StatusFlags.YELLOW, f"function should return 'yellow', because the agency's entry is not present and the shipcall takes place soon"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_missing_time_agency_berth_eta__shipcall_eta_distant_enough_no_times_agency(build_sql_proxy_connection):
|
||||||
|
"""0001-A validation_rule_fct_missing_time_agency_berth_eta"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
# the shipcall happens 'soon'
|
||||||
|
shipcall.eta = datetime.datetime.now() + datetime.timedelta(minutes=ParticipantwiseTimeDelta.AGENCY+10)
|
||||||
|
|
||||||
|
# set times agency to be undetermined
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "eta_berth"] = None
|
||||||
|
|
||||||
|
# apply the validation rule
|
||||||
|
(state, msg) = vr.validation_rule_fct_missing_time_agency_berth_eta(shipcall=shipcall, df_times=df_times)
|
||||||
|
|
||||||
|
# expectation: green state, no msg
|
||||||
|
assert state==StatusFlags.GREEN, f"function should return 'yellow', because the agency's entry is not present and the shipcall takes place soon"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_missing_time_agency_berth_eta__shipcall_eta_is_undefined_agency_eta_is_defined(build_sql_proxy_connection):
|
||||||
|
"""0001-A validation_rule_fct_missing_time_agency_berth_eta"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
# the shipcall is undefined
|
||||||
|
shipcall.eta = None
|
||||||
|
|
||||||
|
# set times agency to be undetermined
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "eta_berth"] = None
|
||||||
|
|
||||||
|
# apply the validation rule
|
||||||
|
(state, msg) = vr.validation_rule_fct_missing_time_agency_berth_eta(shipcall=shipcall, df_times=df_times)
|
||||||
|
|
||||||
|
# expectation: green state, no msg
|
||||||
|
assert state==StatusFlags.GREEN, f"function should return 'yellow', because the agency's entry is not present and the shipcall takes place soon"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_missing_time_agency_berth_etd__shipcall_etd_is_undefined_agency_etd_is_defined(build_sql_proxy_connection):
|
||||||
|
"""0001-B validation_rule_fct_missing_time_agency_berth_etd"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
# the shipcall etd is 'soon'
|
||||||
|
shipcall.etd = datetime.datetime.now() + datetime.timedelta(minutes=ParticipantwiseTimeDelta.AGENCY-10)
|
||||||
|
|
||||||
|
# set times agency to be undetermined
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "etd_berth"] = None
|
||||||
|
|
||||||
|
# apply the validation rule
|
||||||
|
(state, msg) = vr.validation_rule_fct_missing_time_agency_berth_etd(shipcall=shipcall, df_times=df_times)
|
||||||
|
|
||||||
|
# expectation: green state, no msg
|
||||||
|
assert state==StatusFlags.YELLOW, f"function should return 'yellow', because the agency's entry is not present and the shipcall takes place soon"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_missing_time_mooring_berth_eta__shipcall_soon_but_participant_estimated_time_undefined(build_sql_proxy_connection):
|
||||||
|
"""0001-C validation_rule_fct_missing_time_mooring_berth_eta"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
# according to the agency, a shipcall takes place soon (ETA/ETD)
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "eta_berth"] = datetime.datetime.now() + datetime.timedelta(minutes=ParticipantwiseTimeDelta.MOORING-10)
|
||||||
|
|
||||||
|
# set times agency to be undetermined
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.MOORING.value, "eta_berth"] = None
|
||||||
|
|
||||||
|
# apply the validation rule
|
||||||
|
(state, msg) = vr.validation_rule_fct_missing_time_mooring_berth_eta(shipcall=shipcall, df_times=df_times)
|
||||||
|
|
||||||
|
# expectation: green state, no msg
|
||||||
|
assert state==StatusFlags.YELLOW, f"function should return 'yellow', because the participant did not provide a time and the shipcall takes place soon (according to the agency)"
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_validation_rule_fct_missing_time_mooring_berth_etd__shipcall_soon_but_participant_estimated_time_undefined(build_sql_proxy_connection):
|
||||||
|
"""0001-D validation_rule_fct_missing_time_mooring_berth_etd"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
# according to the agency, a shipcall takes place soon (ETA/ETD)
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "etd_berth"] = datetime.datetime.now() + datetime.timedelta(minutes=ParticipantwiseTimeDelta.MOORING-10)
|
||||||
|
|
||||||
|
# set times agency to be undetermined
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.MOORING.value, "etd_berth"] = None
|
||||||
|
|
||||||
|
# apply the validation rule
|
||||||
|
(state, msg) = vr.validation_rule_fct_missing_time_mooring_berth_etd(shipcall=shipcall, df_times=df_times)
|
||||||
|
|
||||||
|
# expectation: green state, no msg
|
||||||
|
assert state==StatusFlags.YELLOW, f"function should return 'yellow', because the participant did not provide a time and the shipcall takes place soon (according to the agency)"
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_validation_rule_fct_missing_time_portadministration_berth_eta__shipcall_soon_but_participant_estimated_time_undefined(build_sql_proxy_connection):
|
||||||
|
"""0001-F validation_rule_fct_missing_time_portadministration_berth_eta"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
# according to the agency, a shipcall takes place soon (ETA/ETD)
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "eta_berth"] = datetime.datetime.now() + datetime.timedelta(minutes=ParticipantwiseTimeDelta.PORT_ADMINISTRATION-10)
|
||||||
|
|
||||||
|
# set times agency to be undetermined
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.PORT_ADMINISTRATION.value, "eta_berth"] = None
|
||||||
|
|
||||||
|
# apply the validation rule
|
||||||
|
(state, msg) = vr.validation_rule_fct_missing_time_portadministration_berth_eta(shipcall=shipcall, df_times=df_times)
|
||||||
|
|
||||||
|
# expectation: green state, no msg
|
||||||
|
assert state==StatusFlags.YELLOW, f"function should return 'yellow', because the participant did not provide a time and the shipcall takes place soon (according to the agency)"
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_validation_rule_fct_missing_time_portadministration_berth_etd__shipcall_soon_but_participant_estimated_time_undefined(build_sql_proxy_connection):
|
||||||
|
"""0001-G validation_rule_fct_missing_time_portadministration_berth_etd"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
# according to the agency, a shipcall takes place soon (ETA/ETD)
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "etd_berth"] = datetime.datetime.now() + datetime.timedelta(minutes=ParticipantwiseTimeDelta.PORT_ADMINISTRATION-10)
|
||||||
|
|
||||||
|
# set times agency to be undetermined
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.PORT_ADMINISTRATION.value, "etd_berth"] = None
|
||||||
|
|
||||||
|
# apply the validation rule
|
||||||
|
(state, msg) = vr.validation_rule_fct_missing_time_portadministration_berth_etd(shipcall=shipcall, df_times=df_times)
|
||||||
|
|
||||||
|
# expectation: green state, no msg
|
||||||
|
assert state==StatusFlags.YELLOW, f"function should return 'yellow', because the participant did not provide a time and the shipcall takes place soon (according to the agency)"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_missing_time_pilot_berth_eta__shipcall_soon_but_participant_estimated_time_undefined(build_sql_proxy_connection):
|
||||||
|
"""0001-H validation_rule_fct_missing_time_pilot_berth_eta"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
# according to the agency, a shipcall takes place soon (ETA/ETD)
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "eta_berth"] = datetime.datetime.now() + datetime.timedelta(minutes=ParticipantwiseTimeDelta.PILOT-10)
|
||||||
|
|
||||||
|
# set times agency to be undetermined
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.PILOT.value, "eta_berth"] = None
|
||||||
|
|
||||||
|
# apply the validation rule
|
||||||
|
(state, msg) = vr.validation_rule_fct_missing_time_pilot_berth_eta(shipcall=shipcall, df_times=df_times)
|
||||||
|
|
||||||
|
# expectation: green state, no msg
|
||||||
|
assert state==StatusFlags.YELLOW, f"function should return 'yellow', because the participant did not provide a time and the shipcall takes place soon (according to the agency)"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_missing_time_pilot_berth_etd__shipcall_soon_but_participant_estimated_time_undefined(build_sql_proxy_connection):
|
||||||
|
"""0001-I validation_rule_fct_missing_time_pilot_berth_etd"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
# according to the agency, a shipcall takes place soon (ETA/ETD)
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "etd_berth"] = datetime.datetime.now() + datetime.timedelta(minutes=ParticipantwiseTimeDelta.PILOT-10)
|
||||||
|
|
||||||
|
# set times agency to be undetermined
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.PILOT.value, "etd_berth"] = None
|
||||||
|
|
||||||
|
# apply the validation rule
|
||||||
|
(state, msg) = vr.validation_rule_fct_missing_time_pilot_berth_etd(shipcall=shipcall, df_times=df_times)
|
||||||
|
|
||||||
|
# expectation: green state, no msg
|
||||||
|
assert state==StatusFlags.YELLOW, f"function should return 'yellow', because the participant did not provide a time and the shipcall takes place soon (according to the agency)"
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_validation_rule_fct_missing_time_tug_berth_eta__shipcall_soon_but_participant_estimated_time_undefined(build_sql_proxy_connection):
|
||||||
|
"""0001-J validation_rule_fct_missing_time_tug_berth_eta"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
# according to the agency, a shipcall takes place soon (ETA/ETD)
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "eta_berth"] = datetime.datetime.now() + datetime.timedelta(minutes=ParticipantwiseTimeDelta.TUG-10)
|
||||||
|
|
||||||
|
# set times agency to be undetermined
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.TUG.value, "eta_berth"] = None
|
||||||
|
|
||||||
|
# apply the validation rule
|
||||||
|
(state, msg) = vr.validation_rule_fct_missing_time_tug_berth_eta(shipcall=shipcall, df_times=df_times)
|
||||||
|
|
||||||
|
# expectation: green state, no msg
|
||||||
|
assert state==StatusFlags.YELLOW, f"function should return 'yellow', because the participant did not provide a time and the shipcall takes place soon (according to the agency)"
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_validation_rule_fct_missing_time_tug_berth_etd__shipcall_soon_but_participant_estimated_time_undefined(build_sql_proxy_connection):
|
||||||
|
"""0001-K validation_rule_fct_missing_time_tug_berth_etd"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
# according to the agency, a shipcall takes place soon (ETA/ETD)
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "etd_berth"] = datetime.datetime.now() + datetime.timedelta(minutes=ParticipantwiseTimeDelta.TUG-10)
|
||||||
|
|
||||||
|
# set times agency to be undetermined
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.TUG.value, "etd_berth"] = None
|
||||||
|
|
||||||
|
# apply the validation rule
|
||||||
|
(state, msg) = vr.validation_rule_fct_missing_time_tug_berth_etd(shipcall=shipcall, df_times=df_times)
|
||||||
|
|
||||||
|
# expectation: green state, no msg
|
||||||
|
assert state==StatusFlags.YELLOW, f"function should return 'yellow', because the participant did not provide a time and the shipcall takes place soon (according to the agency)"
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_validation_rule_fct_missing_time_terminal_berth_eta__shipcall_soon_but_participant_estimated_time_undefined(build_sql_proxy_connection):
|
||||||
|
"""0001-L validation_rule_fct_missing_time_terminal_berth_eta"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
# according to the agency, a shipcall takes place soon (ETA/ETD)
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "eta_berth"] = datetime.datetime.now() + datetime.timedelta(minutes=ParticipantwiseTimeDelta.TERMINAL-10)
|
||||||
|
|
||||||
|
# set times agency to be undetermined
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.TERMINAL.value, "eta_berth"] = None
|
||||||
|
|
||||||
|
# apply the validation rule
|
||||||
|
(state, msg) = vr.validation_rule_fct_missing_time_terminal_berth_eta(shipcall=shipcall, df_times=df_times)
|
||||||
|
|
||||||
|
# expectation: green state, no msg
|
||||||
|
assert state==StatusFlags.YELLOW, f"function should return 'yellow', because the participant did not provide a time and the shipcall takes place soon (according to the agency)"
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_validation_rule_fct_missing_time_terminal_berth_etd__shipcall_soon_but_participant_estimated_time_undefined(build_sql_proxy_connection):
|
||||||
|
"""0001-M validation_rule_fct_missing_time_terminal_berth_etd"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
# according to the agency, a shipcall takes place soon (ETA/ETD)
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "etd_berth"] = datetime.datetime.now() + datetime.timedelta(minutes=ParticipantwiseTimeDelta.TERMINAL-10)
|
||||||
|
|
||||||
|
# set times agency to be undetermined
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.TERMINAL.value, "etd_berth"] = None
|
||||||
|
|
||||||
|
# apply the validation rule
|
||||||
|
(state, msg) = vr.validation_rule_fct_missing_time_terminal_berth_etd(shipcall=shipcall, df_times=df_times)
|
||||||
|
|
||||||
|
# expectation: green state, no msg
|
||||||
|
assert state==StatusFlags.YELLOW, f"function should return 'yellow', because the participant did not provide a time and the shipcall takes place soon (according to the agency)"
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def test_validation_rule_fct_shipcall_incoming_participants_disagree_on_eta__participants_disagree_on_time_but_different_shipcall_type(build_sql_proxy_connection):
|
||||||
|
"""0002-A validation_rule_fct_shipcall_incoming_participants_disagree_on_eta"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
|
||||||
|
# set shipcall type to NOT match the function -> returns 'green'
|
||||||
|
query = "eta_berth"
|
||||||
|
shipcall.type = ShipcallType.SHIFTING.value
|
||||||
|
df_times = get_df_times_participants_disagree(query=query, shipcall=shipcall)
|
||||||
|
|
||||||
|
# apply the validation rule
|
||||||
|
(state, msg) = vr.validation_rule_fct_shipcall_incoming_participants_disagree_on_eta(shipcall=shipcall, df_times=df_times)
|
||||||
|
|
||||||
|
# expectation: green state, no msg
|
||||||
|
assert state==StatusFlags.GREEN, f"function should return 'green', because the shipcall type does not match the function"
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def test_validation_rule_fct_shipcall_incoming_participants_disagree_on_eta__participants_disagree_on_time(build_sql_proxy_connection):
|
||||||
|
"""0002-A validation_rule_fct_shipcall_incoming_participants_disagree_on_eta"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
|
||||||
|
# set shipcall type to match the function
|
||||||
|
query = "eta_berth"
|
||||||
|
shipcall.type = ShipcallType.INCOMING.value
|
||||||
|
df_times = get_df_times_participants_disagree(query=query, shipcall=shipcall) # makes sure that there is disagreement among participants
|
||||||
|
|
||||||
|
# apply the validation rule
|
||||||
|
(state, msg) = vr.validation_rule_fct_shipcall_incoming_participants_disagree_on_eta(shipcall=shipcall, df_times=df_times)
|
||||||
|
|
||||||
|
# expectation: green state, no msg
|
||||||
|
assert state==StatusFlags.RED, f"function should return 'red', because agency and pilot disagree on the query"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_shipcall_incoming_participants_disagree_on_eta__participants_agree_on_time(build_sql_proxy_connection):
|
||||||
|
"""0002-A validation_rule_fct_shipcall_incoming_participants_disagree_on_eta"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
|
||||||
|
# set shipcall type to NOT match the function -> returns 'green'
|
||||||
|
query = "eta_berth"
|
||||||
|
shipcall.type = ShipcallType.INCOMING.value
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
df_times.loc[:,query] = datetime.datetime.now()
|
||||||
|
|
||||||
|
# apply the validation rule
|
||||||
|
(state, msg) = vr.validation_rule_fct_shipcall_incoming_participants_disagree_on_eta(shipcall=shipcall, df_times=df_times)
|
||||||
|
|
||||||
|
# expectation: green state, no msg
|
||||||
|
assert state==StatusFlags.GREEN, f"function should return 'green', because the participants fully agree on the time"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_shipcall_outgoing_participants_disagree_on_etd__participants_disagree_on_time_but_different_shipcall_type(build_sql_proxy_connection):
|
||||||
|
"""0002-B validation_rule_fct_shipcall_outgoing_participants_disagree_on_etd"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
|
||||||
|
# set shipcall type to NOT match the function -> returns 'green'
|
||||||
|
query = "etd_berth"
|
||||||
|
shipcall.type = ShipcallType.SHIFTING.value
|
||||||
|
df_times = get_df_times_participants_disagree(query=query, shipcall=shipcall)
|
||||||
|
|
||||||
|
# apply the validation rule
|
||||||
|
(state, msg) = vr.validation_rule_fct_shipcall_outgoing_participants_disagree_on_etd(shipcall=shipcall, df_times=df_times)
|
||||||
|
|
||||||
|
# expectation: green state, no msg
|
||||||
|
assert state==StatusFlags.GREEN, f"function should return 'green', because the shipcall type does not match the function"
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def test_validation_rule_fct_shipcall_outgoing_participants_disagree_on_etd__participants_disagree_on_time(build_sql_proxy_connection):
|
||||||
|
"""0002-B validation_rule_fct_shipcall_outgoing_participants_disagree_on_etd"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
|
||||||
|
# set shipcall type to match the function
|
||||||
|
query = "etd_berth"
|
||||||
|
shipcall.type = ShipcallType.OUTGOING.value
|
||||||
|
df_times = get_df_times_participants_disagree(query=query, shipcall=shipcall) # makes sure that there is disagreement among participants
|
||||||
|
|
||||||
|
# apply the validation rule
|
||||||
|
(state, msg) = vr.validation_rule_fct_shipcall_outgoing_participants_disagree_on_etd(shipcall=shipcall, df_times=df_times)
|
||||||
|
|
||||||
|
# expectation: green state, no msg
|
||||||
|
assert state==StatusFlags.RED, f"function should return 'red', because agency and pilot disagree on the query"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_shipcall_outgoing_participants_disagree_on_etd__participants_agree_on_time(build_sql_proxy_connection):
|
||||||
|
"""0002-B validation_rule_fct_shipcall_outgoing_participants_disagree_on_etd"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
|
||||||
|
# set shipcall type to NOT match the function -> returns 'green'
|
||||||
|
query = "etd_berth"
|
||||||
|
shipcall.type = ShipcallType.OUTGOING.value
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
df_times.loc[:,query] = datetime.datetime.now()
|
||||||
|
|
||||||
|
# apply the validation rule
|
||||||
|
(state, msg) = vr.validation_rule_fct_shipcall_outgoing_participants_disagree_on_etd(shipcall=shipcall, df_times=df_times)
|
||||||
|
|
||||||
|
# expectation: green state, no msg
|
||||||
|
assert state==StatusFlags.GREEN, f"function should return 'green', because the participants fully agree on the time"
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_validation_rule_fct_shipcall_shifting_participants_disagree_on_eta_or_etd__participants_disagree_on_time_but_different_shipcall_type(build_sql_proxy_connection):
|
||||||
|
"""0002-C validation_rule_fct_shipcall_shifting_participants_disagree_on_eta_or_etd"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
shipcall.type = ShipcallType.INCOMING.value
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
# set shipcall type to match the function
|
||||||
|
query = "eta_berth"
|
||||||
|
df_times = get_df_times_participants_disagree(query=query, shipcall=shipcall, df_times=df_times) # makes sure that there is disagreement among participants
|
||||||
|
|
||||||
|
# set shipcall type to match the function
|
||||||
|
query = "etd_berth"
|
||||||
|
df_times = get_df_times_participants_disagree(query=query, shipcall=shipcall, df_times=df_times) # makes sure that there is disagreement among participants
|
||||||
|
|
||||||
|
# apply the validation rule
|
||||||
|
(state, msg) = vr.validation_rule_fct_shipcall_shifting_participants_disagree_on_eta_or_etd(shipcall=shipcall, df_times=df_times)
|
||||||
|
|
||||||
|
# expectation: green state, no msg
|
||||||
|
assert state==StatusFlags.GREEN, f"function should return 'green', because the shipcall type does not match the function"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_shipcall_shifting_participants_disagree_on_eta_or_etd__participants_disagree_on_time(build_sql_proxy_connection):
|
||||||
|
"""0002-C validation_rule_fct_shipcall_shifting_participants_disagree_on_eta_or_etd"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
shipcall.type = ShipcallType.SHIFTING.value
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
# set shipcall type to match the function
|
||||||
|
query = "eta_berth"
|
||||||
|
df_times = get_df_times_participants_disagree(query=query, shipcall=shipcall, df_times=df_times) # makes sure that there is disagreement among participants
|
||||||
|
|
||||||
|
# set shipcall type to match the function
|
||||||
|
query = "etd_berth"
|
||||||
|
df_times = get_df_times_participants_disagree(query=query, shipcall=shipcall, df_times=df_times) # makes sure that there is disagreement among participants
|
||||||
|
|
||||||
|
# apply the validation rule
|
||||||
|
(state, msg) = vr.validation_rule_fct_shipcall_shifting_participants_disagree_on_eta_or_etd(shipcall=shipcall, df_times=df_times)
|
||||||
|
|
||||||
|
# expectation: green state, no msg
|
||||||
|
assert state==StatusFlags.RED, f"function should return 'red', because agency and pilot disagree on the query"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_shipcall_shifting_participants_disagree_on_eta_or_etd__participants_agree_on_time(build_sql_proxy_connection):
|
||||||
|
"""0002-C validation_rule_fct_shipcall_shifting_participants_disagree_on_eta_or_etd"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
shipcall.type = ShipcallType.SHIFTING.value
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
# set shipcall type to match the function
|
||||||
|
query = "eta_berth"
|
||||||
|
df_times.loc[:,query] = datetime.datetime.now()
|
||||||
|
|
||||||
|
# set shipcall type to match the function
|
||||||
|
query = "etd_berth"
|
||||||
|
df_times.loc[:,query] = datetime.datetime.now()
|
||||||
|
|
||||||
|
# apply the validation rule
|
||||||
|
(state, msg) = vr.validation_rule_fct_shipcall_shifting_participants_disagree_on_eta_or_etd(shipcall=shipcall, df_times=df_times)
|
||||||
|
|
||||||
|
# expectation: green state, no msg
|
||||||
|
assert state==StatusFlags.GREEN, f"function should return 'green', because the participants fully agree on the time"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_eta_time_not_in_operation_window__times_dont_match(build_sql_proxy_connection):
|
||||||
|
"""0003-A validation_rule_fct_eta_time_not_in_operation_window"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
t0_time = datetime.datetime.now() # reference time for easier readability
|
||||||
|
|
||||||
|
# the planned operations_start is before eta_berth (by one minute in this case)
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "eta_berth"] = t0_time + datetime.timedelta(minutes=1)
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.TERMINAL.value, "operations_start"] = t0_time + datetime.timedelta(minutes=0)
|
||||||
|
|
||||||
|
(code, msg) = vr.validation_rule_fct_eta_time_not_in_operation_window(shipcall, df_times)
|
||||||
|
assert code==StatusFlags.RED, f"status flag should be 'red', because the planned operations start is BEFORE the estimated time of arrival for the shipcall"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_etd_time_not_in_operation_window__times_dont_match(build_sql_proxy_connection):
|
||||||
|
"""0003-B validation_rule_fct_etd_time_not_in_operation_window"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
t0_time = datetime.datetime.now() # reference time for easier readability
|
||||||
|
|
||||||
|
# the planned operations_end is after etd_berth (by one minute in this case)
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "etd_berth"] = t0_time + datetime.timedelta(hours=1)
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.TERMINAL.value, "operations_end"] = t0_time+datetime.timedelta(hours=1, minutes=1)
|
||||||
|
|
||||||
|
|
||||||
|
(code, msg) = vr.validation_rule_fct_etd_time_not_in_operation_window(shipcall, df_times)
|
||||||
|
assert code==StatusFlags.RED, f"status flag should be 'red', because the planned operations end is AFTER the estimated time of departure for the shipcall"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_eta_time_not_in_operation_window_and_validation_rule_fct_etd_time_not_in_operation_window__always_okay(build_sql_proxy_connection):
|
||||||
|
"""
|
||||||
|
0003-A validation_rule_fct_eta_time_not_in_operation_window
|
||||||
|
0003-B validation_rule_fct_etd_time_not_in_operation_window
|
||||||
|
"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
import random
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
t0_time = datetime.datetime.now()
|
||||||
|
|
||||||
|
# 10 random permutations of None/pd.NaT/suitable values
|
||||||
|
# each of these combinations is okay and should return a 'green' state
|
||||||
|
for _i in range(10):
|
||||||
|
# eta_berth & operations start
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "eta_berth"] = random.sample([None, pd.NaT, t0_time + datetime.timedelta(minutes=0)],k=1)[0]
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.TERMINAL.value, "operations_start"] = random.sample([None, pd.NaT, t0_time + datetime.timedelta(minutes=0)], k=1)[0]
|
||||||
|
|
||||||
|
# etd_berth & operations start
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "etd_berth"] = random.sample([None, pd.NaT, t0_time + datetime.timedelta(hours=1)],k=1)[0]
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.TERMINAL.value, "operations_end"] = random.sample([None, pd.NaT, t0_time+datetime.timedelta(hours=1)],k=1)[0]
|
||||||
|
|
||||||
|
(code, msg) = vr.validation_rule_fct_eta_time_not_in_operation_window(shipcall=shipcall, df_times=df_times)
|
||||||
|
assert code==StatusFlags.GREEN, f"status flag should be 'green', as any of these perturbations sets operation & estimated time to be on par ot one the values missed"
|
||||||
|
(code, msg) = vr.validation_rule_fct_etd_time_not_in_operation_window(shipcall=shipcall, df_times=df_times)
|
||||||
|
assert code==StatusFlags.GREEN, f"status flag should be 'green', as any of these perturbations sets operation & estimated time to be on par ot one the values missed"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_eta_time_not_in_tidal_window__is_okay(build_sql_proxy_connection):
|
||||||
|
"""0004-A validation_rule_fct_eta_time_not_in_tidal_window"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
t0_time = datetime.datetime.now()
|
||||||
|
|
||||||
|
# tidal window: [t0 +1min, t0 +1hr)
|
||||||
|
# eta berth:
|
||||||
|
shipcall.tidal_window_from = t0_time + datetime.timedelta(minutes=1)
|
||||||
|
shipcall.tidal_window_to = t0_time + datetime.timedelta(hours=1)
|
||||||
|
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "eta_berth"] = t0_time + datetime.timedelta(minutes=1)
|
||||||
|
(code, msg) = vr.validation_rule_fct_eta_time_not_in_tidal_window(shipcall, df_times)
|
||||||
|
assert code==StatusFlags.GREEN, f"state should be 'green', because eta_berth matches precisely the tidal_window_from"
|
||||||
|
|
||||||
|
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "eta_berth"] = t0_time + datetime.timedelta(hours=1)
|
||||||
|
(code, msg) = vr.validation_rule_fct_eta_time_not_in_tidal_window(shipcall, df_times)
|
||||||
|
assert code==StatusFlags.GREEN, f"state should be 'green', because eta_berth matches precisely the tidal_window_to (in this case, the etd_berth would likely cause an issue)"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_eta_time_not_in_tidal_window__eta_outside_tidal_window(build_sql_proxy_connection):
|
||||||
|
"""0004-A validation_rule_fct_eta_time_not_in_tidal_window"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
t0_time = datetime.datetime.now()
|
||||||
|
|
||||||
|
# tidal window: [t0 +1min, t0 +1hr)
|
||||||
|
# eta berth: t0+0min
|
||||||
|
shipcall.tidal_window_from = t0_time + datetime.timedelta(minutes=1)
|
||||||
|
shipcall.tidal_window_to = t0_time + datetime.timedelta(hours=1)
|
||||||
|
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "eta_berth"] = t0_time + datetime.timedelta(minutes=0)
|
||||||
|
(code, msg) = vr.validation_rule_fct_eta_time_not_in_tidal_window(shipcall, df_times)
|
||||||
|
assert code==StatusFlags.RED, f"state should be 'red', eta_berth takes place before the tidal window"
|
||||||
|
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "eta_berth"] = t0_time + datetime.timedelta(hours=1, minutes=1)
|
||||||
|
(code, msg) = vr.validation_rule_fct_eta_time_not_in_tidal_window(shipcall, df_times)
|
||||||
|
assert code==StatusFlags.RED, f"state should be 'red', eta_berth takes place after the tidal window"
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_validation_rule_fct_etd_time_not_in_tidal_window__is_okay(build_sql_proxy_connection):
|
||||||
|
"""0004-B validation_rule_fct_etd_time_not_in_tidal_window"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
t0_time = datetime.datetime.now()
|
||||||
|
|
||||||
|
# tidal window: [t0 +1min, t0 +1hr)
|
||||||
|
# etd berth:
|
||||||
|
shipcall.tidal_window_from = t0_time + datetime.timedelta(minutes=1)
|
||||||
|
shipcall.tidal_window_to = t0_time + datetime.timedelta(hours=1)
|
||||||
|
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "etd_berth"] = t0_time + datetime.timedelta(minutes=1)
|
||||||
|
(code, msg) = vr.validation_rule_fct_etd_time_not_in_tidal_window(shipcall, df_times)
|
||||||
|
assert code==StatusFlags.GREEN, f"state should be 'green', because etd_berth matches precisely the tidal_window_from"
|
||||||
|
|
||||||
|
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "etd_berth"] = t0_time + datetime.timedelta(hours=1)
|
||||||
|
(code, msg) = vr.validation_rule_fct_etd_time_not_in_tidal_window(shipcall, df_times)
|
||||||
|
assert code==StatusFlags.GREEN, f"state should be 'green', because etd_berth matches precisely the tidal_window_to (in this case, the etd_berth would likely cause an issue)"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_etd_time_not_in_tidal_window__etd_outside_tidal_window(build_sql_proxy_connection):
|
||||||
|
"""0004-B validation_rule_fct_etd_time_not_in_tidal_window"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
|
||||||
|
t0_time = datetime.datetime.now()
|
||||||
|
|
||||||
|
# tidal window: [t0 +1min, t0 +1hr)
|
||||||
|
# etd berth:
|
||||||
|
shipcall.tidal_window_from = t0_time + datetime.timedelta(minutes=1)
|
||||||
|
shipcall.tidal_window_to = t0_time + datetime.timedelta(hours=1)
|
||||||
|
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "etd_berth"] = t0_time + datetime.timedelta(minutes=0)
|
||||||
|
(code, msg) = vr.validation_rule_fct_etd_time_not_in_tidal_window(shipcall, df_times)
|
||||||
|
assert code==StatusFlags.RED, f"state should be 'red', etd_berth takes place before the tidal window"
|
||||||
|
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "etd_berth"] = t0_time + datetime.timedelta(hours=1, minutes=1)
|
||||||
|
(code, msg) = vr.validation_rule_fct_etd_time_not_in_tidal_window(shipcall, df_times)
|
||||||
|
assert code==StatusFlags.RED, f"state should be 'red', etd_berth takes place after the tidal window"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_too_many_identical_eta_times__is_violated_by_too_many_identical_times(build_sql_proxy_connection):
|
||||||
|
"""0005-A validation_rule_fct_too_many_identical_eta_times"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
query = "eta_berth"
|
||||||
|
|
||||||
|
reference_time = pd.Timestamp(datetime.datetime.now())
|
||||||
|
reference_time = reference_time.round("min")
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
df_times = df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value]
|
||||||
|
df_times.loc[:,query] = reference_time + datetime.timedelta(seconds=12)
|
||||||
|
|
||||||
|
all_times_df = build_stub_df_times(shipcall, query, reference_time)
|
||||||
|
(code, msg) = vr.validation_rule_fct_too_many_identical_eta_times(shipcall=shipcall, df_times=df_times, all_times_agency=all_times_df)
|
||||||
|
assert code == StatusFlags.YELLOW, f"status should be 'yellow', because the artificial 'all_times_df' contains five shipcalls with identical times, which exceeds the threshold"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_too_many_identical_etd_times__is_violated_by_too_many_identical_times(build_sql_proxy_connection):
|
||||||
|
"""0005-B validation_rule_fct_too_many_identical_etd_times"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
query = "etd_berth"
|
||||||
|
|
||||||
|
reference_time = pd.Timestamp(datetime.datetime.now())
|
||||||
|
reference_time = reference_time.round("min")
|
||||||
|
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
df_times = df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value]
|
||||||
|
df_times.loc[:,query] = reference_time + datetime.timedelta(seconds=12)
|
||||||
|
|
||||||
|
all_times_df = build_stub_df_times(shipcall, query, reference_time)
|
||||||
|
(code, msg) = vr.validation_rule_fct_too_many_identical_etd_times(shipcall=shipcall, df_times=df_times, all_times_agency=all_times_df)
|
||||||
|
assert code == StatusFlags.YELLOW, f"status should be 'yellow', because the artificial 'all_times_df' contains five shipcalls with identical times, which exceeds the threshold"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_agency_and_terminal_berth_id_disagreement__agency_and_terminal_agree(build_sql_proxy_connection):
|
||||||
|
"""0006-A validation_rule_fct_agency_and_terminal_berth_id_disagreement"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "berth_id"] = 143
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.TERMINAL.value, "berth_id"] = 143
|
||||||
|
|
||||||
|
(code, msg) = vr.validation_rule_fct_agency_and_terminal_berth_id_disagreement(shipcall=shipcall, df_times=df_times)
|
||||||
|
assert code==StatusFlags.GREEN, f"status should be 'green', because agency and terminal agree on the selected berth id"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_agency_and_terminal_berth_id_disagreement__agency_and_terminal_disagree(build_sql_proxy_connection):
|
||||||
|
"""0006-A validation_rule_fct_agency_and_terminal_berth_id_disagreement"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "berth_id"] = 143
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.TERMINAL.value, "berth_id"] = 145
|
||||||
|
|
||||||
|
(code, msg) = vr.validation_rule_fct_agency_and_terminal_berth_id_disagreement(shipcall=shipcall, df_times=df_times)
|
||||||
|
assert code==StatusFlags.YELLOW, f"status should be 'yellow', because agency and terminal do not agree on the selected berth id"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_agency_and_terminal_pier_side_disagreement__agency_and_terminal_agree(build_sql_proxy_connection):
|
||||||
|
"""0006-B validation_rule_fct_agency_and_terminal_pier_side_disagreement"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "pier_side"] = True
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.TERMINAL.value, "pier_side"] = True
|
||||||
|
|
||||||
|
(code, msg) = vr.validation_rule_fct_agency_and_terminal_pier_side_disagreement(shipcall=shipcall, df_times=df_times)
|
||||||
|
assert code==StatusFlags.GREEN, f"status should be 'green', because agency and terminal agree on the selected pier side"
|
||||||
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_agency_and_terminal_pier_side_disagreement__agency_and_terminal_disagree(build_sql_proxy_connection):
|
||||||
|
"""0006-B validation_rule_fct_agency_and_terminal_pier_side_disagreement"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value, "pier_side"] = True
|
||||||
|
df_times.loc[df_times["participant_type"]==ParticipantType.TERMINAL.value, "pier_side"] = False
|
||||||
|
|
||||||
|
(code, msg) = vr.validation_rule_fct_agency_and_terminal_pier_side_disagreement(shipcall=shipcall, df_times=df_times)
|
||||||
|
assert code==StatusFlags.YELLOW, f"status should be 'yellow', because agency and terminal do not agree on the selected pier side"
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_validation_rule_fct_agency_and_terminal_pier_side_agreement(build_sql_proxy_connection):
|
def test_validation_rule_fct_agency_and_terminal_pier_side_agreement(build_sql_proxy_connection):
|
||||||
"""#0006-A validation_rule_fct_agency_and_terminal_pier_side_disagreement"""
|
"""#0006-A validation_rule_fct_agency_and_terminal_pier_side_disagreement"""
|
||||||
@ -89,8 +853,36 @@ def test_validation_rule_fct_agency_and_terminal_pier_side_agreement(build_sql_p
|
|||||||
assert description is None, f"no violation should be observed"
|
assert description is None, f"no violation should be observed"
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_agency_and_terminal_pier_side_disagreement(build_sql_proxy_connection):
|
||||||
|
"""#0006-A validation_rule_fct_agency_and_terminal_pier_side_disagreement"""
|
||||||
|
import pandas as pd
|
||||||
|
|
||||||
|
from BreCal.stubs.times_full import get_times_full_simple
|
||||||
|
from BreCal.stubs.shipcall import get_shipcall_simple
|
||||||
|
from BreCal.database.enums import ParticipantType
|
||||||
|
from BreCal.database.enums import StatusFlags
|
||||||
|
|
||||||
|
vr = build_sql_proxy_connection["vr"]
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
t1 = get_times_full_simple()
|
||||||
|
t2 = get_times_full_simple()
|
||||||
|
|
||||||
|
# roles: agency & terminal
|
||||||
|
t1.participant_type = ParticipantType.AGENCY.value
|
||||||
|
t2.participant_type = ParticipantType.TERMINAL.value
|
||||||
|
|
||||||
|
# disagreement
|
||||||
|
t1.pier_side = True
|
||||||
|
t2.pier_side = False
|
||||||
|
|
||||||
|
time_objects = [t1, t2]
|
||||||
|
df_times = pd.DataFrame.from_records([to_.__dict__ for to_ in time_objects])
|
||||||
|
df_times.set_index('id',inplace=True)
|
||||||
|
|
||||||
|
(state, description) = vr.validation_rule_fct_agency_and_terminal_pier_side_disagreement(shipcall, df_times)
|
||||||
|
assert state.value > StatusFlags.GREEN.value, f"a violation must be identified"
|
||||||
|
assert description is not None, f"a violation description must be identified"
|
||||||
|
return
|
||||||
|
|
||||||
def test_validation_rule_fct_agency_and_terminal_berth_id_disagreement(build_sql_proxy_connection):
|
def test_validation_rule_fct_agency_and_terminal_berth_id_disagreement(build_sql_proxy_connection):
|
||||||
"""#0006-B validation_rule_fct_agency_and_terminal_pier_side_disagreement"""
|
"""#0006-B validation_rule_fct_agency_and_terminal_pier_side_disagreement"""
|
||||||
@ -156,4 +948,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
|
||||||
|
|||||||
Reference in New Issue
Block a user