Compare commits
8 Commits
feature/in
...
master
Author | SHA1 | Date | |
---|---|---|---|
d7caf3b0f8 | |||
35db9aad43 | |||
c98a5acb38 | |||
8f410198e9 | |||
e97b177a92 | |||
6191bf16e0 | |||
63af33d003 | |||
3b94f117fb |
3
.aliases
3
.aliases
@ -95,3 +95,6 @@ if [ ! -f .environment ]; then
|
|||||||
cp .tc-environment .environment
|
cp .tc-environment .environment
|
||||||
fi
|
fi
|
||||||
source .environment
|
source .environment
|
||||||
|
|
||||||
|
alias scenario-reports-upload='./gradlew scenarioTests convertMarkdownToHtml && ssh hsh03-hsngdev@h50.hostsharing.net "rm -f doms/hsngdev.hs-example.de/htdocs-ssl/scenarios/office/*.html" && scp build/doc/scenarios/*.html hsh03-hsngdev@h50.hostsharing.net:doms/hsngdev.hs-example.de/htdocs-ssl/scenarios/office'
|
||||||
|
alias scenario-reports-open='open https://hsngdev.hs-example.de/scenarios/office'
|
||||||
|
36
Jenkinsfile
vendored
36
Jenkinsfile
vendored
@ -26,9 +26,35 @@ pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stage ('Compile & Test') {
|
stage ('Compile') {
|
||||||
steps {
|
steps {
|
||||||
sh './gradlew clean check --no-daemon -x pitest -x dependencyCheckAnalyze'
|
sh './gradlew clean processSpring compileJava compileTestJava --no-daemon'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage ('Tests') {
|
||||||
|
parallel {
|
||||||
|
stage('Unit-/Integration/Acceptance-Tests') {
|
||||||
|
steps {
|
||||||
|
sh './gradlew check --no-daemon -x pitest -x dependencyCheckAnalyze -x importOfficeData -x importHostingAssets'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Import-Tests') {
|
||||||
|
steps {
|
||||||
|
sh './gradlew importOfficeData importHostingAssets --no-daemon'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage ('Scenario-Tests') {
|
||||||
|
steps {
|
||||||
|
sh './gradlew scenarioTests --no-daemon'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage ('Check') {
|
||||||
|
steps {
|
||||||
|
sh './gradlew check -x pitest -x dependencyCheckAnalyze --no-daemon'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,6 +71,12 @@ pipeline {
|
|||||||
sourcePattern: 'src/main/java'
|
sourcePattern: 'src/main/java'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// archive scenario-test reports in HTML format
|
||||||
|
sh '''
|
||||||
|
./gradlew convertMarkdownToHtml
|
||||||
|
'''
|
||||||
|
archiveArtifacts artifacts: 'doc/scenarios/*.html', allowEmptyArchive: true
|
||||||
|
|
||||||
// cleanup workspace
|
// cleanup workspace
|
||||||
cleanWs()
|
cleanWs()
|
||||||
}
|
}
|
||||||
|
60
build.gradle
60
build.gradle
@ -118,8 +118,8 @@ openapiProcessor {
|
|||||||
springRoot {
|
springRoot {
|
||||||
processorName 'spring'
|
processorName 'spring'
|
||||||
processor 'io.openapiprocessor:openapi-processor-spring:2022.5'
|
processor 'io.openapiprocessor:openapi-processor-spring:2022.5'
|
||||||
apiPath "$projectDir/src/main/resources/api-definition.yaml"
|
apiPath "$projectDir/src/main/resources/api-definition/api-definition.yaml"
|
||||||
mapping "$projectDir/src/main/resources/api-mappings.yaml"
|
mapping "$projectDir/src/main/resources/api-definition/api-mappings.yaml"
|
||||||
targetDir "$buildDir/generated/sources/openapi-javax"
|
targetDir "$buildDir/generated/sources/openapi-javax"
|
||||||
showWarnings true
|
showWarnings true
|
||||||
openApiNullable true
|
openApiNullable true
|
||||||
@ -255,7 +255,7 @@ test {
|
|||||||
'net.hostsharing.hsadminng.**.generated.**',
|
'net.hostsharing.hsadminng.**.generated.**',
|
||||||
]
|
]
|
||||||
useJUnitPlatform {
|
useJUnitPlatform {
|
||||||
excludeTags 'import'
|
excludeTags 'importOfficeData', 'importHostingData', 'scenarioTest'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
jacocoTestReport {
|
jacocoTestReport {
|
||||||
@ -344,6 +344,17 @@ tasks.register('importHostingAssets', Test) {
|
|||||||
mustRunAfter spotlessJava
|
mustRunAfter spotlessJava
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.register('scenarioTests', Test) {
|
||||||
|
useJUnitPlatform {
|
||||||
|
includeTags 'scenarioTest'
|
||||||
|
}
|
||||||
|
|
||||||
|
group 'verification'
|
||||||
|
description 'run the import jobs as tests'
|
||||||
|
|
||||||
|
mustRunAfter spotlessJava
|
||||||
|
}
|
||||||
|
|
||||||
// pitest mutation testing
|
// pitest mutation testing
|
||||||
pitest {
|
pitest {
|
||||||
targetClasses = ['net.hostsharing.hsadminng.**']
|
targetClasses = ['net.hostsharing.hsadminng.**']
|
||||||
@ -391,3 +402,46 @@ tasks.named("dependencyUpdates").configure {
|
|||||||
isNonStable(it.candidate.version)
|
isNonStable(it.candidate.version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Generate HTML from Markdown scenario-test-reports using Pandoc:
|
||||||
|
tasks.register('convertMarkdownToHtml') {
|
||||||
|
description = 'Generates HTML from Markdown scenario-test-reports using Pandoc.'
|
||||||
|
group = 'Conversion'
|
||||||
|
|
||||||
|
// Define the template file and input directory
|
||||||
|
def templateFile = file('doc/scenarios/.template.html')
|
||||||
|
|
||||||
|
// Task configuration and execution
|
||||||
|
doFirst {
|
||||||
|
// Check if pandoc is installed
|
||||||
|
try {
|
||||||
|
exec {
|
||||||
|
commandLine 'pandoc', '--version'
|
||||||
|
}
|
||||||
|
} catch (Exception) {
|
||||||
|
throw new GradleException("Pandoc is not installed or not found in the system path.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the template file exists
|
||||||
|
if (!templateFile.exists()) {
|
||||||
|
throw new GradleException("Template file 'doc/scenarios/.template.html' not found.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
doLast {
|
||||||
|
// Gather all Markdown files in the current directory
|
||||||
|
fileTree(dir: '.', include: 'build/doc/scenarios/*.md').each { file ->
|
||||||
|
// Corrected way to create the output file path
|
||||||
|
def outputFile = new File(file.parent, file.name.replaceAll(/\.md$/, '.html'))
|
||||||
|
|
||||||
|
// Execute pandoc for each markdown file
|
||||||
|
exec {
|
||||||
|
commandLine 'pandoc', file.absolutePath, '--template', templateFile.absolutePath, '-o', outputFile.absolutePath
|
||||||
|
}
|
||||||
|
|
||||||
|
println "Converted ${file.name} to ${outputFile.name}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
convertMarkdownToHtml.dependsOn scenarioTests
|
||||||
|
124
doc/business-glossary-de.md
Normal file
124
doc/business-glossary-de.md
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
### hsadminNg fachliches Glossar
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Currently, this business glossary is only available in German because in many cases,
|
||||||
|
the German terms are important for comprehensibility for those using this software.
|
||||||
|
-->
|
||||||
|
|
||||||
|
Dieses ist eine Sammlung von Fachbegriffen, die in diesem Projekt benutzt werden.
|
||||||
|
Ebenfalls aufgenommen sind technische Begriffe, die für Benutzer für das Verständnis der Schnittstellen nötig sind.
|
||||||
|
|
||||||
|
Falls etwas fehlt, bitte Bescheid geben.
|
||||||
|
|
||||||
|
|
||||||
|
#### Partner
|
||||||
|
|
||||||
|
In diesem System ist ein _Partner_ grundsätzlich jeglicher Geschäftspartner der _Hostsharing eG_.
|
||||||
|
Dies können grundsätzlich Kunden, siehe [Debitor](#Debitor), wie Lieferanten sein.
|
||||||
|
Derzeit sind aber nur Debitoren implementiert.
|
||||||
|
|
||||||
|
Des Weiteren gibt es für jeden _Partner_ eine fünfstellige Partnernummer mit dem Prefix 'P-' (z.B. `P-123454`)
|
||||||
|
sowie Zusatzinformationen (z.B. Registergerichtnummer oder Geburtsdatum), die zur genauen Identifikation benötigt werden.
|
||||||
|
|
||||||
|
Für einen _Partner_ kann es gleichzeitig mehrere [Debitoren](#Debitor)
|
||||||
|
und zeitlich nacheinander mehrere [Mitgliedschaften](#Mitgliedschaft) geben.
|
||||||
|
|
||||||
|
Partner sind grundsätzlich als ist [Relation](#Relation) der Vertragsperson mit der Person _Hostsharing eG_ implementiert.
|
||||||
|
|
||||||
|
|
||||||
|
### Debitor
|
||||||
|
|
||||||
|
Ein `Debitor` ist quasi ein Rechnungsempfänger für einen [Partner](#Partner).
|
||||||
|
|
||||||
|
Für einen _Partner_ kann es gleichzeitig mehrere [Debitoren](#Debitor) geben,
|
||||||
|
z.B. für spezielle Projekte des Kunden oder verbundene Organisationen.
|
||||||
|
|
||||||
|
Des Weiteren gibt es für jeden _Partner_ eine fünfstellige Partnernummer mit dem Prefix 'P-' (z.B. `P-123454`)
|
||||||
|
sowie Zusatzinformationen (z.B. Registergerichtsnummer oder Geburtsdatum), die zur genauen Identifikation benötigt werden.
|
||||||
|
|
||||||
|
Debitoren sind grundsätzlich als ist [Relation](#Relation) der Vertragsperson mit der Person des Vertragspartners implementiert.
|
||||||
|
|
||||||
|
|
||||||
|
#### Relation
|
||||||
|
|
||||||
|
Eine _Relation_ ist eine typisierte und mit Kontaktdaten versehene Beziehung einer (_Holder_)-Person zu einer _Anchor_-Person.
|
||||||
|
|
||||||
|
Eine Relation ist eine Art Geschäftsrolle, wir haben hier aber keinen Begriff mit 'Rolle' verwendet,
|
||||||
|
weil 'Role' (engl.) zu leicht mit der [RBAC-Rolle](#RBAC-Role) verwechselt werden könnte.
|
||||||
|
|
||||||
|
Die _Relation_ ist auch ein technisches Konzept und gehört nicht zur Domänensprache.
|
||||||
|
Dieses Konzept ist jedoch für das Verständnis der ([API](#API)) notwendig.
|
||||||
|
|
||||||
|
|
||||||
|
#### Ex-Partner
|
||||||
|
|
||||||
|
Ex-Partner bilden [Personen](#Person) ab, die vormals [Partner](#Partner) waren.
|
||||||
|
Diese bleiben dadurch informationshalber im System verfügbar.
|
||||||
|
|
||||||
|
Implementiert ist der _Ex-Partner_ als eine besondere Form der [Relation](#Relation)
|
||||||
|
der Person des Ex-Partner (_Holder_) zum neuen Partner (_Anchor_) dargestellt.
|
||||||
|
Dieses kann zu einer Kettenbildung führen.
|
||||||
|
|
||||||
|
|
||||||
|
#### Representative-Contact (ehemals _contractual_)
|
||||||
|
|
||||||
|
Ein _Representative_ ist eine natürliche Person, die für eine nicht-natürliche Person vertretungsberechtigt ist.
|
||||||
|
|
||||||
|
Implementiert ist der _Representative_ als eine besondere Form der [Relation](#Relation)
|
||||||
|
der Person des Repräsentanten (_Holder_) zur repräsentierten Person (_Anchor_) dargestellt.
|
||||||
|
|
||||||
|
|
||||||
|
### VIP-Contact
|
||||||
|
|
||||||
|
Ein _VIP-Contact_ ist eine natürliche Person, die für einen Geschäftspartner eine wichtige Funktion übernimmt,
|
||||||
|
nicht aber deren offizieller Repräsentant ist.
|
||||||
|
|
||||||
|
Implementiert ist der _VIP-Contact_ als eine besondere Form der [Relation](#Relation)
|
||||||
|
der Person des VIP-Contact (_Holder_) zur repräsentierten Person (_Anchor_) dargestellt.
|
||||||
|
|
||||||
|
|
||||||
|
### Operations-Contact
|
||||||
|
|
||||||
|
Ein _Operations-_Contact_ ist_ eine natürliche Person, die für einen Geschäftspartner technischer Ansprechpartner ist.
|
||||||
|
|
||||||
|
Ein Seiteneffekt ist, dass diese Person im Ticketsystem Znuny direkt dem Geschäftspartner zugeordnet werden kann.
|
||||||
|
|
||||||
|
Im Legacy System waren das die Kontakte mit der Rolle `operation` und `silent`.
|
||||||
|
|
||||||
|
Implementiert ist der _Operations-Contact_ als eine besondere Form der [Relation](#Relation)
|
||||||
|
der Person des _Operations-Contact_ (_Holder_) zur repräsentierten Person (_Anchor_) dargestellt.
|
||||||
|
|
||||||
|
|
||||||
|
### OperationsAlert-Contact
|
||||||
|
|
||||||
|
Ein _OperationsAlert-_Contact_ ist_ eine natürliche Person, die für einen Geschäftspartner bei technischen Probleme kontaktiert werden soll.
|
||||||
|
|
||||||
|
Im Legacy System waren das die Kontakte mit der Rolle `operation`.
|
||||||
|
|
||||||
|
Implementiert ist der _OperationsAlert-Contact_ als eine besondere Form der [Relation](#Relation)
|
||||||
|
der Person des _OperationsAlert-Contact_ (_Holder_) zur repräsentierten Person (_Anchor_) dargestellt.
|
||||||
|
|
||||||
|
|
||||||
|
### Subscriber-Contact
|
||||||
|
|
||||||
|
Ein _Subscriber-_Contact_ ist_ eine natürliche Person, die für einen Geschäftspartner eine bestimmte Mailingliste abonniert.
|
||||||
|
|
||||||
|
Implementiert ist der _Subscriber-Contact_ als eine besondere Form der [Relation](#Relation)
|
||||||
|
der Person des _Subscriber-Contact_ (_Holder_) zur repräsentierten Person (_Anchor_) dargestellt.
|
||||||
|
Zusätzlich wird diese Relation mit dem Kurznamen der abonnierten Mailingliste markiert.
|
||||||
|
|
||||||
|
|
||||||
|
#### Anchor / Relation-Anchor
|
||||||
|
|
||||||
|
siehe [Relation](#Relation)
|
||||||
|
|
||||||
|
|
||||||
|
#### Holder / Relation-Holder
|
||||||
|
|
||||||
|
siehe [Relation](#Relation)
|
||||||
|
|
||||||
|
|
||||||
|
#### API
|
||||||
|
|
||||||
|
Und API (Application-Programming-Interface) verstehen wir eine über HTTPS angesprochene programmatisch bedienbare Schnittstell
|
||||||
|
zur Funktionalität des hsAdmin-NG-Systems.
|
@ -64,7 +64,7 @@ classDiagram
|
|||||||
}
|
}
|
||||||
|
|
||||||
class partner-MeierGmbH {
|
class partner-MeierGmbH {
|
||||||
+Numeric partnerNumber: 12345
|
+Numeric partnerNumber: P-12345
|
||||||
+Relation partnerRel
|
+Relation partnerRel
|
||||||
}
|
}
|
||||||
partner-MeierGmbH *-- rel-MeierGmbH
|
partner-MeierGmbH *-- rel-MeierGmbH
|
||||||
|
124
doc/scenarios/.template.html
Normal file
124
doc/scenarios/.template.html
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html $if(lang)$ lang="$lang$" $endif$>
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<!--[if lt IE 9]>
|
||||||
|
<script src="http://css3-mediaqueries-js.googlecode.com/svn/trunk/css3-mediaqueries.js"></script>
|
||||||
|
<![endif]-->
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
<meta http-equiv="Content-Style-Type" content="text/css" />
|
||||||
|
|
||||||
|
<!-- <link rel="stylesheet" type="text/css" href="template.css" /> -->
|
||||||
|
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/diversen/pandoc-bootstrap-adaptive-template@959c3622/template.css" />
|
||||||
|
|
||||||
|
<link href="https://vjs.zencdn.net/5.4.4/video-js.css" rel="stylesheet" />
|
||||||
|
|
||||||
|
<script src="https://code.jquery.com/jquery-2.2.1.min.js"></script>
|
||||||
|
<!-- <script type='text/javascript' src='menu/js/jquery.cookie.js'></script> -->
|
||||||
|
<!-- <script type='text/javascript' src='menu/js/jquery.hoverIntent.minified.js'></script> -->
|
||||||
|
<!-- <script type='text/javascript' src='menu/js/jquery.dcjqaccordion.2.7.min.js'></script> -->
|
||||||
|
|
||||||
|
<!-- <link href="menu/css/skins/blue.css" rel="stylesheet" type="text/css" /> -->
|
||||||
|
<!-- <link href="menu/css/skins/graphite.css" rel="stylesheet" type="text/css" /> -->
|
||||||
|
<!-- <link href="menu/css/skins/grey.css" rel="stylesheet" type="text/css" /> -->
|
||||||
|
|
||||||
|
<!-- <script src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script> -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <script src="script.js"></script> -->
|
||||||
|
|
||||||
|
<!-- <script src="jquery.sticky-kit.js "></script> -->
|
||||||
|
<script type='text/javascript' src='https://cdn.jsdelivr.net/gh/diversen/pandoc-bootstrap-adaptive-template@959c3622/menu/js/jquery.cookie.js'></script>
|
||||||
|
<script type='text/javascript' src='https://cdn.jsdelivr.net/gh/diversen/pandoc-bootstrap-adaptive-template@959c3622/menu/js/jquery.hoverIntent.minified.js'></script>
|
||||||
|
<script type='text/javascript' src='https://cdn.jsdelivr.net/gh/diversen/pandoc-bootstrap-adaptive-template@959c3622/menu/js/jquery.dcjqaccordion.2.7.min.js'></script>
|
||||||
|
|
||||||
|
<link href="https://cdn.jsdelivr.net/gh/diversen/pandoc-bootstrap-adaptive-template@959c3622/menu/css/skins/blue.css" rel="stylesheet" type="text/css" />
|
||||||
|
<link href="https://cdn.jsdelivr.net/gh/diversen/pandoc-bootstrap-adaptive-template@959c3622/menu/css/skins/graphite.css" rel="stylesheet" type="text/css" />
|
||||||
|
<link href="https://cdn.jsdelivr.net/gh/diversen/pandoc-bootstrap-adaptive-template@959c3622/menu/css/skins/grey.css" rel="stylesheet" type="text/css" />
|
||||||
|
<link href="https://cdn.jsdelivr.net/gh/ryangrose/easy-pandoc-templates@948e28e5/css/elegant_bootstrap.css" rel="stylesheet" type="text/css" />
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.4/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/gh/diversen/pandoc-bootstrap-adaptive-template@959c3622/script.js"></script>
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/gh/diversen/pandoc-bootstrap-adaptive-template@959c3622/jquery.sticky-kit.js"></script>
|
||||||
|
<meta name="generator" content="pandoc" />
|
||||||
|
$for(author-meta)$
|
||||||
|
<meta name="author" content="$author-meta$" />
|
||||||
|
$endfor$
|
||||||
|
$if(date-meta)$
|
||||||
|
<meta name="date" content="$date-meta$" />
|
||||||
|
$endif$
|
||||||
|
<title>$if(title-prefix)$$title-prefix$ - $endif$$pagetitle$</title>
|
||||||
|
<style type="text/css">code{white-space: pre;}</style>
|
||||||
|
$if(quotes)$
|
||||||
|
<style type="text/css">q { quotes: "“" "”" "‘" "’"; }</style>
|
||||||
|
$endif$
|
||||||
|
$if(highlighting-css)$
|
||||||
|
<style type="text/css">
|
||||||
|
$highlighting-css$
|
||||||
|
</style>
|
||||||
|
$endif$
|
||||||
|
$for(css)$
|
||||||
|
<link rel="stylesheet" href="$css$" $if(html5)$$else$type="text/css" $endif$/>
|
||||||
|
$endfor$
|
||||||
|
$if(math)$
|
||||||
|
$math$
|
||||||
|
$endif$
|
||||||
|
$for(header-includes)$
|
||||||
|
$header-includes$
|
||||||
|
$endfor$
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
$if(title)$
|
||||||
|
<div class="navbar navbar-static-top">
|
||||||
|
<div class="navbar-inner">
|
||||||
|
<div class="container">
|
||||||
|
<span class="doc-title">$title$</span>
|
||||||
|
<ul class="nav pull-right doc-info">
|
||||||
|
$for(author)$
|
||||||
|
<li><p class="navbar-text">$author$</p></li>
|
||||||
|
$endfor$
|
||||||
|
$if(date)$
|
||||||
|
<li><p class="navbar-text">$date$</p></li>
|
||||||
|
$endif$
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
$endif$
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
$if(toc)$
|
||||||
|
<div id="$idprefix$TOC" class="span3">
|
||||||
|
<div class="well toc">
|
||||||
|
|
||||||
|
$toc$
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
$endif$
|
||||||
|
<div class="span$if(toc)$9$else$12$endif$">
|
||||||
|
|
||||||
|
$if(abstract)$
|
||||||
|
<H1>$abstract-title$</H1>
|
||||||
|
$abstract$
|
||||||
|
$endif$
|
||||||
|
|
||||||
|
$for(include-before)$
|
||||||
|
$include-before$
|
||||||
|
$endfor$
|
||||||
|
$body$
|
||||||
|
$for(include-after)$
|
||||||
|
$include-after$
|
||||||
|
$endfor$
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="https://vjs.zencdn.net/5.4.4/video.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
1
doc/scenarios/README.txt
Normal file
1
doc/scenarios/README.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
find the generated ScenarioReports in build/doc/scenarios
|
@ -90,6 +90,20 @@ Acceptance-tests, are blackbox-tests and do <u>not</u> count into test-code-cove
|
|||||||
TODO.test: Complete the Acceptance-Tests test concept.
|
TODO.test: Complete the Acceptance-Tests test concept.
|
||||||
|
|
||||||
|
|
||||||
|
#### Scenario-Tests
|
||||||
|
|
||||||
|
Our Scenario-tests are induced by business use-cases.
|
||||||
|
They test from the REST API all the way down to the database.
|
||||||
|
|
||||||
|
Most scenario-tests are positive tests, they test if business scenarios do work.
|
||||||
|
But few might be negative tests, which test if specific forbidden data gets rejected.
|
||||||
|
|
||||||
|
Our scenario tests also generate test-reports which contain the REST-API calls needed for each scenario.
|
||||||
|
These reports can be used as examples for the API usage from a business perspective.
|
||||||
|
|
||||||
|
There is an extra document regarding scenario-test, see [Scenario-Tests README](../src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/README.md).
|
||||||
|
|
||||||
|
|
||||||
#### Performance-Tests
|
#### Performance-Tests
|
||||||
|
|
||||||
Performance-critical scenarios have to be identified and a special performance-test has to be implemented.
|
Performance-critical scenarios have to be identified and a special performance-test has to be implemented.
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
FROM eclipse-temurin:21-jdk
|
FROM eclipse-temurin:21-jdk
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y bind9-utils && \
|
apt-get install -y bind9-utils pandoc && \
|
||||||
apt-get clean && \
|
apt-get clean && \
|
||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
|
||||||
# RUN mkdir /opt/app
|
|
||||||
# COPY japp.jar /opt
|
|
||||||
# CMD ["java", "-jar", "/opt/app/japp.jar"]
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.hostsharing.hsadminng.config;
|
package net.hostsharing.hsadminng.config;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonParser;
|
import com.fasterxml.jackson.core.JsonParser;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
import org.openapitools.jackson.nullable.JsonNullableModule;
|
import org.openapitools.jackson.nullable.JsonNullableModule;
|
||||||
@ -9,15 +10,20 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import org.springframework.context.annotation.Primary;
|
import org.springframework.context.annotation.Primary;
|
||||||
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
||||||
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public class JsonObjectMapperConfiguration {
|
public class JsonObjectMapperConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Primary
|
@Primary
|
||||||
public Jackson2ObjectMapperBuilder customObjectMapper() {
|
public Jackson2ObjectMapperBuilder customObjectMapper() {
|
||||||
|
// HOWTO: add JSON converters and specify other JSON mapping configurations
|
||||||
return new Jackson2ObjectMapperBuilder()
|
return new Jackson2ObjectMapperBuilder()
|
||||||
.modules(new JsonNullableModule(), new JavaTimeModule())
|
.modules(new JsonNullableModule(), new JavaTimeModule())
|
||||||
.featuresToEnable(JsonParser.Feature.ALLOW_COMMENTS, JsonParser.Feature.ALLOW_COMMENTS)
|
.featuresToEnable(
|
||||||
|
JsonParser.Feature.ALLOW_COMMENTS,
|
||||||
|
DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS
|
||||||
|
)
|
||||||
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ public class CustomErrorResponse {
|
|||||||
this.path = path;
|
this.path = path;
|
||||||
this.statusCode = status.value();
|
this.statusCode = status.value();
|
||||||
this.statusPhrase = status.getReasonPhrase();
|
this.statusPhrase = status.getReasonPhrase();
|
||||||
|
// HOWTO: debug serverside error response - set a breakpoint here
|
||||||
this.message = message.startsWith("ERROR: [") ? message : "ERROR: [" + statusCode + "] " + message;
|
this.message = message.startsWith("ERROR: [") ? message : "ERROR: [" + statusCode + "] " + message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,8 @@ import lombok.Builder;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.repr.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||||
|
|
||||||
import jakarta.persistence.Column;
|
import jakarta.persistence.Column;
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
@ -14,7 +14,7 @@ import jakarta.persistence.Id;
|
|||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
||||||
|
|
||||||
// a partial HsOfficeDebitorEntity to reduce the number of SQL queries to load the entity
|
// a partial HsOfficeDebitorEntity to reduce the number of SQL queries to load the entity
|
||||||
@Entity
|
@Entity
|
||||||
|
@ -15,8 +15,8 @@ import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealEntity;
|
|||||||
import net.hostsharing.hsadminng.hs.validation.PropertiesProvider;
|
import net.hostsharing.hsadminng.hs.validation.PropertiesProvider;
|
||||||
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
|
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
|
||||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.repr.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||||
import org.hibernate.annotations.Type;
|
import org.hibernate.annotations.Type;
|
||||||
|
|
||||||
import jakarta.persistence.CascadeType;
|
import jakarta.persistence.CascadeType;
|
||||||
@ -45,7 +45,7 @@ import static java.util.Optional.ofNullable;
|
|||||||
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.lowerInclusiveFromPostgresDateRange;
|
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.lowerInclusiveFromPostgresDateRange;
|
||||||
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange;
|
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange;
|
||||||
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.upperInclusiveFromPostgresDateRange;
|
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.upperInclusiveFromPostgresDateRange;
|
||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
||||||
|
|
||||||
@MappedSuperclass
|
@MappedSuperclass
|
||||||
@Getter
|
@Getter
|
||||||
|
@ -4,14 +4,14 @@ import lombok.*;
|
|||||||
import lombok.experimental.SuperBuilder;
|
import lombok.experimental.SuperBuilder;
|
||||||
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
|
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
|
||||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.repr.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static java.util.Optional.ofNullable;
|
import static java.util.Optional.ofNullable;
|
||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
||||||
|
|
||||||
@MappedSuperclass
|
@MappedSuperclass
|
||||||
@Getter
|
@Getter
|
||||||
|
@ -15,8 +15,8 @@ import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
|||||||
import net.hostsharing.hsadminng.hs.validation.PropertiesProvider;
|
import net.hostsharing.hsadminng.hs.validation.PropertiesProvider;
|
||||||
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
|
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
|
||||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.repr.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||||
import org.hibernate.annotations.Type;
|
import org.hibernate.annotations.Type;
|
||||||
|
|
||||||
import jakarta.persistence.CascadeType;
|
import jakarta.persistence.CascadeType;
|
||||||
@ -42,7 +42,7 @@ import java.util.Optional;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static java.util.Collections.emptyMap;
|
import static java.util.Collections.emptyMap;
|
||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
||||||
|
|
||||||
@MappedSuperclass
|
@MappedSuperclass
|
||||||
@Getter
|
@Getter
|
||||||
|
@ -5,8 +5,8 @@ import lombok.experimental.FieldNameConstants;
|
|||||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.repr.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -16,7 +16,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.*;
|
|||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacSubjectReference.UserRole.CREATOR;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacSubjectReference.UserRole.CREATOR;
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(schema = "hs_office", name = "bankaccount_rv")
|
@Table(schema = "hs_office", name = "bankaccount_rv")
|
||||||
|
@ -12,8 +12,8 @@ import lombok.experimental.SuperBuilder;
|
|||||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||||
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
|
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
|
||||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.repr.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
import org.hibernate.annotations.GenericGenerator;
|
||||||
import org.hibernate.annotations.Type;
|
import org.hibernate.annotations.Type;
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
||||||
|
|
||||||
@MappedSuperclass
|
@MappedSuperclass
|
||||||
@Getter
|
@Getter
|
||||||
@ -54,8 +54,14 @@ public class HsOfficeContact implements Stringifyable, BaseEntity<HsOfficeContac
|
|||||||
@Column(name = "caption")
|
@Column(name = "caption")
|
||||||
private String caption;
|
private String caption;
|
||||||
|
|
||||||
|
@Builder.Default
|
||||||
|
@Setter(AccessLevel.NONE)
|
||||||
|
@Type(JsonType.class)
|
||||||
@Column(name = "postaladdress")
|
@Column(name = "postaladdress")
|
||||||
private String postalAddress; // multiline free-format text
|
private Map<String, String> postalAddress = new HashMap<>();
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
private PatchableMapWrapper<String> postalAddressWrapper;
|
||||||
|
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
@Setter(AccessLevel.NONE)
|
@Setter(AccessLevel.NONE)
|
||||||
@ -75,6 +81,17 @@ public class HsOfficeContact implements Stringifyable, BaseEntity<HsOfficeContac
|
|||||||
@Transient
|
@Transient
|
||||||
private PatchableMapWrapper<String> phoneNumbersWrapper;
|
private PatchableMapWrapper<String> phoneNumbersWrapper;
|
||||||
|
|
||||||
|
public PatchableMapWrapper<String> getPostalAddress() {
|
||||||
|
return PatchableMapWrapper.of(
|
||||||
|
postalAddressWrapper,
|
||||||
|
(newWrapper) -> {postalAddressWrapper = newWrapper;},
|
||||||
|
postalAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putPostalAddress(Map<String, String> newPostalAddress) {
|
||||||
|
getPostalAddress().assign(newPostalAddress);
|
||||||
|
}
|
||||||
|
|
||||||
public PatchableMapWrapper<String> getEmailAddresses() {
|
public PatchableMapWrapper<String> getEmailAddresses() {
|
||||||
return PatchableMapWrapper.of(
|
return PatchableMapWrapper.of(
|
||||||
emailAddressesWrapper,
|
emailAddressesWrapper,
|
||||||
|
@ -18,7 +18,8 @@ class HsOfficeContactEntityPatcher implements EntityPatcher<HsOfficeContactPatch
|
|||||||
@Override
|
@Override
|
||||||
public void apply(final HsOfficeContactPatchResource resource) {
|
public void apply(final HsOfficeContactPatchResource resource) {
|
||||||
OptionalFromJson.of(resource.getCaption()).ifPresent(entity::setCaption);
|
OptionalFromJson.of(resource.getCaption()).ifPresent(entity::setCaption);
|
||||||
OptionalFromJson.of(resource.getPostalAddress()).ifPresent(entity::setPostalAddress);
|
Optional.ofNullable(resource.getPostalAddress())
|
||||||
|
.ifPresent(r -> entity.getPostalAddress().patch(KeyValueMap.from(resource.getPostalAddress())));
|
||||||
Optional.ofNullable(resource.getEmailAddresses())
|
Optional.ofNullable(resource.getEmailAddresses())
|
||||||
.ifPresent(r -> entity.getEmailAddresses().patch(KeyValueMap.from(resource.getEmailAddresses())));
|
.ifPresent(r -> entity.getEmailAddresses().patch(KeyValueMap.from(resource.getEmailAddresses())));
|
||||||
Optional.ofNullable(resource.getPhoneNumbers())
|
Optional.ofNullable(resource.getPhoneNumbers())
|
||||||
|
@ -36,7 +36,7 @@ public class HsOfficeCoopAssetsTransactionController implements HsOfficeCoopAsse
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public ResponseEntity<List<HsOfficeCoopAssetsTransactionResource>> listCoopAssets(
|
public ResponseEntity<List<HsOfficeCoopAssetsTransactionResource>> getListOfCoopAssets(
|
||||||
final String currentSubject,
|
final String currentSubject,
|
||||||
final String assumedRoles,
|
final String assumedRoles,
|
||||||
final UUID membershipUuid,
|
final UUID membershipUuid,
|
||||||
@ -55,7 +55,7 @@ public class HsOfficeCoopAssetsTransactionController implements HsOfficeCoopAsse
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public ResponseEntity<HsOfficeCoopAssetsTransactionResource> addCoopAssetsTransaction(
|
public ResponseEntity<HsOfficeCoopAssetsTransactionResource> postNewCoopAssetTransaction(
|
||||||
final String currentSubject,
|
final String currentSubject,
|
||||||
final String assumedRoles,
|
final String assumedRoles,
|
||||||
final HsOfficeCoopAssetsTransactionInsertResource requestBody) {
|
final HsOfficeCoopAssetsTransactionInsertResource requestBody) {
|
||||||
@ -77,8 +77,7 @@ public class HsOfficeCoopAssetsTransactionController implements HsOfficeCoopAsse
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
|
public ResponseEntity<HsOfficeCoopAssetsTransactionResource> getSingleCoopAssetTransactionByUuid(
|
||||||
public ResponseEntity<HsOfficeCoopAssetsTransactionResource> getCoopAssetTransactionByUuid(
|
|
||||||
final String currentSubject, final String assumedRoles, final UUID assetTransactionUuid) {
|
final String currentSubject, final String assumedRoles, final UUID assetTransactionUuid) {
|
||||||
|
|
||||||
context.define(currentSubject, assumedRoles);
|
context.define(currentSubject, assumedRoles);
|
||||||
@ -129,9 +128,9 @@ public class HsOfficeCoopAssetsTransactionController implements HsOfficeCoopAsse
|
|||||||
}
|
}
|
||||||
|
|
||||||
final BiConsumer<HsOfficeCoopAssetsTransactionInsertResource, HsOfficeCoopAssetsTransactionEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
|
final BiConsumer<HsOfficeCoopAssetsTransactionInsertResource, HsOfficeCoopAssetsTransactionEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
|
||||||
if ( resource.getReverseEntryUuid() != null ) {
|
if ( resource.getRevertedAssetTxUuid() != null ) {
|
||||||
entity.setAdjustedAssetTx(coopAssetsTransactionRepo.findByUuid(resource.getReverseEntryUuid())
|
entity.setRevertedAssetTx(coopAssetsTransactionRepo.findByUuid(resource.getRevertedAssetTxUuid())
|
||||||
.orElseThrow(() -> new EntityNotFoundException("ERROR: [400] reverseEntityUuid %s not found".formatted(resource.getReverseEntryUuid()))));
|
.orElseThrow(() -> new EntityNotFoundException("ERROR: [400] reverseEntityUuid %s not found".formatted(resource.getRevertedAssetTxUuid()))));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -10,8 +10,8 @@ import net.hostsharing.hsadminng.errors.DisplayAs;
|
|||||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.repr.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
import org.hibernate.annotations.GenericGenerator;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
@ -31,7 +31,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.ADMIN;
|
|||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.AGENT;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.AGENT;
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(schema = "hs_office", name = "coopassettx_rv")
|
@Table(schema = "hs_office", name = "coopassettx_rv")
|
||||||
@ -50,8 +50,8 @@ public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, BaseE
|
|||||||
.withProp(HsOfficeCoopAssetsTransactionEntity::getAssetValue)
|
.withProp(HsOfficeCoopAssetsTransactionEntity::getAssetValue)
|
||||||
.withProp(HsOfficeCoopAssetsTransactionEntity::getReference)
|
.withProp(HsOfficeCoopAssetsTransactionEntity::getReference)
|
||||||
.withProp(HsOfficeCoopAssetsTransactionEntity::getComment)
|
.withProp(HsOfficeCoopAssetsTransactionEntity::getComment)
|
||||||
.withProp(at -> ofNullable(at.getAdjustedAssetTx()).map(HsOfficeCoopAssetsTransactionEntity::toShortString).orElse(null))
|
.withProp(at -> ofNullable(at.getRevertedAssetTx()).map(HsOfficeCoopAssetsTransactionEntity::toShortString).orElse(null))
|
||||||
.withProp(at -> ofNullable(at.getAdjustmentAssetTx()).map(HsOfficeCoopAssetsTransactionEntity::toShortString).orElse(null))
|
.withProp(at -> ofNullable(at.getReversalAssetTx()).map(HsOfficeCoopAssetsTransactionEntity::toShortString).orElse(null))
|
||||||
.quotedValues(false);
|
.quotedValues(false);
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@ -77,7 +77,7 @@ public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, BaseE
|
|||||||
* The signed value which directly affects the booking balance.
|
* The signed value which directly affects the booking balance.
|
||||||
*
|
*
|
||||||
* <p>This means, that a DEPOSIT is always positive, a DISBURSAL is always negative,
|
* <p>This means, that a DEPOSIT is always positive, a DISBURSAL is always negative,
|
||||||
* but an ADJUSTMENT can bei either positive or negative.
|
* but an REVERSAL can bei either positive or negative.
|
||||||
* See {@link HsOfficeCoopAssetsTransactionType} for</p> more information.
|
* See {@link HsOfficeCoopAssetsTransactionType} for</p> more information.
|
||||||
*/
|
*/
|
||||||
@Column(name = "assetvalue")
|
@Column(name = "assetvalue")
|
||||||
@ -96,14 +96,14 @@ public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, BaseE
|
|||||||
private String comment;
|
private String comment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optionally, the UUID of the corresponding transaction for an adjustment transaction.
|
* Optionally, the UUID of the corresponding transaction for an reversal transaction.
|
||||||
*/
|
*/
|
||||||
@OneToOne
|
@OneToOne
|
||||||
@JoinColumn(name = "adjustedassettxuuid")
|
@JoinColumn(name = "revertedassettxuuid")
|
||||||
private HsOfficeCoopAssetsTransactionEntity adjustedAssetTx;
|
private HsOfficeCoopAssetsTransactionEntity revertedAssetTx;
|
||||||
|
|
||||||
@OneToOne(mappedBy = "adjustedAssetTx")
|
@OneToOne(mappedBy = "revertedAssetTx")
|
||||||
private HsOfficeCoopAssetsTransactionEntity adjustmentAssetTx;
|
private HsOfficeCoopAssetsTransactionEntity reversalAssetTx;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HsOfficeCoopAssetsTransactionEntity load() {
|
public HsOfficeCoopAssetsTransactionEntity load() {
|
||||||
|
@ -4,7 +4,7 @@ public enum HsOfficeCoopAssetsTransactionType {
|
|||||||
/**
|
/**
|
||||||
* correction of wrong bookings, value can be positive or negative
|
* correction of wrong bookings, value can be positive or negative
|
||||||
*/
|
*/
|
||||||
ADJUSTMENT,
|
REVERSAL,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* payment received from member after signing shares, value >0
|
* payment received from member after signing shares, value >0
|
||||||
|
@ -38,7 +38,7 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public ResponseEntity<List<HsOfficeCoopSharesTransactionResource>> listCoopShares(
|
public ResponseEntity<List<HsOfficeCoopSharesTransactionResource>> getListOfCoopShares(
|
||||||
final String currentSubject,
|
final String currentSubject,
|
||||||
final String assumedRoles,
|
final String assumedRoles,
|
||||||
final UUID membershipUuid,
|
final UUID membershipUuid,
|
||||||
@ -57,7 +57,7 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public ResponseEntity<HsOfficeCoopSharesTransactionResource> addCoopSharesTransaction(
|
public ResponseEntity<HsOfficeCoopSharesTransactionResource> postNewCoopSharesTransaction(
|
||||||
final String currentSubject,
|
final String currentSubject,
|
||||||
final String assumedRoles,
|
final String assumedRoles,
|
||||||
final HsOfficeCoopSharesTransactionInsertResource requestBody) {
|
final HsOfficeCoopSharesTransactionInsertResource requestBody) {
|
||||||
@ -80,7 +80,7 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public ResponseEntity<HsOfficeCoopSharesTransactionResource> getCoopShareTransactionByUuid(
|
public ResponseEntity<HsOfficeCoopSharesTransactionResource> getSingleCoopShareTransactionByUuid(
|
||||||
final String currentSubject, final String assumedRoles, final UUID shareTransactionUuid) {
|
final String currentSubject, final String assumedRoles, final UUID shareTransactionUuid) {
|
||||||
|
|
||||||
context.define(currentSubject, assumedRoles);
|
context.define(currentSubject, assumedRoles);
|
||||||
@ -131,9 +131,9 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
|
|||||||
}
|
}
|
||||||
|
|
||||||
final BiConsumer<HsOfficeCoopSharesTransactionInsertResource, HsOfficeCoopSharesTransactionEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
|
final BiConsumer<HsOfficeCoopSharesTransactionInsertResource, HsOfficeCoopSharesTransactionEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
|
||||||
if ( resource.getAdjustedShareTxUuid() != null ) {
|
if ( resource.getRevertedShareTxUuid() != null ) {
|
||||||
entity.setAdjustedShareTx(coopSharesTransactionRepo.findByUuid(resource.getAdjustedShareTxUuid())
|
entity.setRevertedShareTx(coopSharesTransactionRepo.findByUuid(resource.getRevertedShareTxUuid())
|
||||||
.orElseThrow(() -> new EntityNotFoundException("ERROR: [400] adjustedShareTxUuid %s not found".formatted(resource.getAdjustedShareTxUuid()))));
|
.orElseThrow(() -> new EntityNotFoundException("ERROR: [400] revertedShareTxUuid %s not found".formatted(resource.getRevertedShareTxUuid()))));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,8 @@ import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
|||||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.repr.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -29,7 +29,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.ADMIN;
|
|||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.AGENT;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.AGENT;
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(schema = "hs_office", name = "coopsharetx_rv")
|
@Table(schema = "hs_office", name = "coopsharetx_rv")
|
||||||
@ -48,8 +48,8 @@ public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, BaseE
|
|||||||
.withProp(HsOfficeCoopSharesTransactionEntity::getShareCount)
|
.withProp(HsOfficeCoopSharesTransactionEntity::getShareCount)
|
||||||
.withProp(HsOfficeCoopSharesTransactionEntity::getReference)
|
.withProp(HsOfficeCoopSharesTransactionEntity::getReference)
|
||||||
.withProp(HsOfficeCoopSharesTransactionEntity::getComment)
|
.withProp(HsOfficeCoopSharesTransactionEntity::getComment)
|
||||||
.withProp(at -> ofNullable(at.getAdjustedShareTx()).map(HsOfficeCoopSharesTransactionEntity::toShortString).orElse(null))
|
.withProp(at -> ofNullable(at.getRevertedShareTx()).map(HsOfficeCoopSharesTransactionEntity::toShortString).orElse(null))
|
||||||
.withProp(at -> ofNullable(at.getAdjustmentShareTx()).map(HsOfficeCoopSharesTransactionEntity::toShortString).orElse(null))
|
.withProp(at -> ofNullable(at.getReversalShareTx()).map(HsOfficeCoopSharesTransactionEntity::toShortString).orElse(null))
|
||||||
.quotedValues(false);
|
.quotedValues(false);
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@ -71,7 +71,7 @@ public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, BaseE
|
|||||||
* The signed value which directly affects the booking balance.
|
* The signed value which directly affects the booking balance.
|
||||||
*
|
*
|
||||||
* <p>This means, that a SUBSCRIPTION is always positive, a CANCELLATION is always negative,
|
* <p>This means, that a SUBSCRIPTION is always positive, a CANCELLATION is always negative,
|
||||||
* but an ADJUSTMENT can bei either positive or negative.
|
* but an REVERSAL can bei either positive or negative.
|
||||||
* See {@link HsOfficeCoopSharesTransactionType} for</p> more information.
|
* See {@link HsOfficeCoopSharesTransactionType} for</p> more information.
|
||||||
*/
|
*/
|
||||||
@Column(name = "valuedate")
|
@Column(name = "valuedate")
|
||||||
@ -93,14 +93,14 @@ public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, BaseE
|
|||||||
private String comment;
|
private String comment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optionally, the UUID of the corresponding transaction for an adjustment transaction.
|
* Optionally, the UUID of the corresponding transaction for a REVERSAL transaction.
|
||||||
*/
|
*/
|
||||||
@OneToOne
|
@OneToOne
|
||||||
@JoinColumn(name = "adjustedsharetxuuid")
|
@JoinColumn(name = "revertedsharetxuuid")
|
||||||
private HsOfficeCoopSharesTransactionEntity adjustedShareTx;
|
private HsOfficeCoopSharesTransactionEntity revertedShareTx;
|
||||||
|
|
||||||
@OneToOne(mappedBy = "adjustedShareTx")
|
@OneToOne(mappedBy = "revertedShareTx")
|
||||||
private HsOfficeCoopSharesTransactionEntity adjustmentShareTx;
|
private HsOfficeCoopSharesTransactionEntity reversalShareTx;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HsOfficeCoopSharesTransactionEntity load() {
|
public HsOfficeCoopSharesTransactionEntity load() {
|
||||||
|
@ -2,9 +2,9 @@ package net.hostsharing.hsadminng.hs.office.coopshares;
|
|||||||
|
|
||||||
public enum HsOfficeCoopSharesTransactionType {
|
public enum HsOfficeCoopSharesTransactionType {
|
||||||
/**
|
/**
|
||||||
* correction of wrong bookings, with either positive or negative value
|
* reversal of wrong bookings, with either positive or negative value identical to reversed transaction
|
||||||
*/
|
*/
|
||||||
ADJUSTMENT,
|
REVERSAL,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* shares signed, e.g. with the declaration of accession, value >0
|
* shares signed, e.g. with the declaration of accession, value >0
|
||||||
|
@ -22,8 +22,10 @@ import jakarta.persistence.PersistenceContext;
|
|||||||
import jakarta.validation.ValidationException;
|
import jakarta.validation.ValidationException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.DEBITOR;
|
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.DEBITOR;
|
||||||
|
import static net.hostsharing.hsadminng.repr.TaggedNumber.cropTag;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
|
|
||||||
@ -49,24 +51,24 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public ResponseEntity<List<HsOfficeDebitorResource>> listDebitors(
|
public ResponseEntity<List<HsOfficeDebitorResource>> getListOfDebitors(
|
||||||
final String currentSubject,
|
final String currentSubject,
|
||||||
final String assumedRoles,
|
final String assumedRoles,
|
||||||
final String name,
|
final String name,
|
||||||
final Integer debitorNumber) {
|
final String debitorNumber) {
|
||||||
context.define(currentSubject, assumedRoles);
|
context.define(currentSubject, assumedRoles);
|
||||||
|
|
||||||
final var entities = debitorNumber != null
|
final var entities = debitorNumber != null
|
||||||
? debitorRepo.findDebitorByDebitorNumber(debitorNumber)
|
? debitorRepo.findDebitorByDebitorNumber(cropTag("D-", debitorNumber))
|
||||||
: debitorRepo.findDebitorByOptionalNameLike(name);
|
: debitorRepo.findDebitorByOptionalNameLike(name);
|
||||||
|
|
||||||
final var resources = mapper.mapList(entities, HsOfficeDebitorResource.class);
|
final var resources = mapper.mapList(entities, HsOfficeDebitorResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||||
return ResponseEntity.ok(resources);
|
return ResponseEntity.ok(resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public ResponseEntity<HsOfficeDebitorResource> addDebitor(
|
public ResponseEntity<HsOfficeDebitorResource> postNewDebitor(
|
||||||
String currentSubject,
|
String currentSubject,
|
||||||
String assumedRoles,
|
String assumedRoles,
|
||||||
HsOfficeDebitorInsertResource body) {
|
HsOfficeDebitorInsertResource body) {
|
||||||
@ -77,16 +79,13 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
|||||||
"ERROR: [400] exactly one of debitorRel and debitorRelUuid must be supplied, but found both");
|
"ERROR: [400] exactly one of debitorRel and debitorRelUuid must be supplied, but found both");
|
||||||
Validate.isTrue(body.getDebitorRel() != null || body.getDebitorRelUuid() != null,
|
Validate.isTrue(body.getDebitorRel() != null || body.getDebitorRelUuid() != null,
|
||||||
"ERROR: [400] exactly one of debitorRel and debitorRelUuid must be supplied, but found none");
|
"ERROR: [400] exactly one of debitorRel and debitorRelUuid must be supplied, but found none");
|
||||||
Validate.isTrue(body.getDebitorRel() == null ||
|
|
||||||
body.getDebitorRel().getType() == null || DEBITOR.name().equals(body.getDebitorRel().getType()),
|
|
||||||
"ERROR: [400] debitorRel.type must be '"+DEBITOR.name()+"' or null for default");
|
|
||||||
Validate.isTrue(body.getDebitorRel() == null || body.getDebitorRel().getMark() == null,
|
Validate.isTrue(body.getDebitorRel() == null || body.getDebitorRel().getMark() == null,
|
||||||
"ERROR: [400] debitorRel.mark must be null");
|
"ERROR: [400] debitorRel.mark must be null");
|
||||||
|
|
||||||
final var entityToSave = mapper.map(body, HsOfficeDebitorEntity.class);
|
final var entityToSave = mapper.map(body, HsOfficeDebitorEntity.class);
|
||||||
if ( body.getDebitorRel() != null ) {
|
if (body.getDebitorRel() != null) {
|
||||||
body.getDebitorRel().setType(DEBITOR.name());
|
|
||||||
final var debitorRel = mapper.map("debitorRel.", body.getDebitorRel(), HsOfficeRelationRealEntity.class);
|
final var debitorRel = mapper.map("debitorRel.", body.getDebitorRel(), HsOfficeRelationRealEntity.class);
|
||||||
|
debitorRel.setType(DEBITOR);
|
||||||
entityValidator.validateEntityExists("debitorRel.anchorUuid", debitorRel.getAnchor());
|
entityValidator.validateEntityExists("debitorRel.anchorUuid", debitorRel.getAnchor());
|
||||||
entityValidator.validateEntityExists("debitorRel.holderUuid", debitorRel.getHolder());
|
entityValidator.validateEntityExists("debitorRel.holderUuid", debitorRel.getHolder());
|
||||||
entityValidator.validateEntityExists("debitorRel.contactUuid", debitorRel.getContact());
|
entityValidator.validateEntityExists("debitorRel.contactUuid", debitorRel.getContact());
|
||||||
@ -95,7 +94,10 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
|||||||
final var debitorRelOptional = relrealRepo.findByUuid(body.getDebitorRelUuid());
|
final var debitorRelOptional = relrealRepo.findByUuid(body.getDebitorRelUuid());
|
||||||
debitorRelOptional.ifPresentOrElse(
|
debitorRelOptional.ifPresentOrElse(
|
||||||
debitorRel -> {entityToSave.setDebitorRel(relrealRepo.save(debitorRel));},
|
debitorRel -> {entityToSave.setDebitorRel(relrealRepo.save(debitorRel));},
|
||||||
() -> { throw new ValidationException("Unable to find RealRelation by debitorRelUuid: " + body.getDebitorRelUuid());});
|
() -> {
|
||||||
|
throw new ValidationException(
|
||||||
|
"Unable to find RealRelation by debitorRelUuid: " + body.getDebitorRelUuid());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
final var savedEntity = debitorRepo.save(entityToSave);
|
final var savedEntity = debitorRepo.save(entityToSave);
|
||||||
@ -107,13 +109,13 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
|||||||
.path("/api/hs/office/debitors/{id}")
|
.path("/api/hs/office/debitors/{id}")
|
||||||
.buildAndExpand(savedEntity.getUuid())
|
.buildAndExpand(savedEntity.getUuid())
|
||||||
.toUri();
|
.toUri();
|
||||||
final var mapped = mapper.map(savedEntity, HsOfficeDebitorResource.class);
|
final var mapped = mapper.map(savedEntity, HsOfficeDebitorResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||||
return ResponseEntity.created(uri).body(mapped);
|
return ResponseEntity.created(uri).body(mapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public ResponseEntity<HsOfficeDebitorResource> getDebitorByUuid(
|
public ResponseEntity<HsOfficeDebitorResource> getSingleDebitorByUuid(
|
||||||
final String currentSubject,
|
final String currentSubject,
|
||||||
final String assumedRoles,
|
final String assumedRoles,
|
||||||
final UUID debitorUuid) {
|
final UUID debitorUuid) {
|
||||||
@ -124,7 +126,7 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
|||||||
if (result.isEmpty()) {
|
if (result.isEmpty()) {
|
||||||
return ResponseEntity.notFound().build();
|
return ResponseEntity.notFound().build();
|
||||||
}
|
}
|
||||||
return ResponseEntity.ok(mapper.map(result.get(), HsOfficeDebitorResource.class));
|
return ResponseEntity.ok(mapper.map(result.get(), HsOfficeDebitorResource.class, ENTITY_TO_RESOURCE_POSTMAPPER));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -159,7 +161,11 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
|||||||
|
|
||||||
final var saved = debitorRepo.save(current);
|
final var saved = debitorRepo.save(current);
|
||||||
Hibernate.initialize(saved);
|
Hibernate.initialize(saved);
|
||||||
final var mapped = mapper.map(saved, HsOfficeDebitorResource.class);
|
final var mapped = mapper.map(saved, HsOfficeDebitorResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||||
return ResponseEntity.ok(mapped);
|
return ResponseEntity.ok(mapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final BiConsumer<HsOfficeDebitorEntity, HsOfficeDebitorResource> ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> {
|
||||||
|
resource.setDebitorNumber(entity.getTaggedDebitorNumber());
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,8 @@ import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
|
|||||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.repr.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
import org.hibernate.annotations.GenericGenerator;
|
||||||
import org.hibernate.annotations.JoinFormula;
|
import org.hibernate.annotations.JoinFormula;
|
||||||
import org.hibernate.annotations.NotFound;
|
import org.hibernate.annotations.NotFound;
|
||||||
@ -51,7 +51,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
|||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.fetchedBySql;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.fetchedBySql;
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(schema = "hs_office", name = "debitor_rv")
|
@Table(schema = "hs_office", name = "debitor_rv")
|
||||||
@ -142,19 +142,14 @@ public class HsOfficeDebitorEntity implements BaseEntity<HsOfficeDebitorEntity>,
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getDebitorNumberString() {
|
public String getTaggedDebitorNumber() {
|
||||||
return ofNullable(partner)
|
return ofNullable(partner)
|
||||||
.filter(partner -> debitorNumberSuffix != null)
|
.filter(partner -> debitorNumberSuffix != null)
|
||||||
.map(HsOfficePartnerEntity::getPartnerNumber)
|
.map(HsOfficePartnerEntity::getPartnerNumber)
|
||||||
.map(Object::toString)
|
.map(partnerNumber -> DEBITOR_NUMBER_TAG + partnerNumber + debitorNumberSuffix)
|
||||||
.map(partnerNumber -> partnerNumber + debitorNumberSuffix)
|
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getDebitorNumber() {
|
|
||||||
return ofNullable(getDebitorNumberString()).map(Integer::parseInt).orElse(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return stringify.apply(this);
|
return stringify.apply(this);
|
||||||
@ -162,7 +157,7 @@ public class HsOfficeDebitorEntity implements BaseEntity<HsOfficeDebitorEntity>,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toShortString() {
|
public String toShortString() {
|
||||||
return DEBITOR_NUMBER_TAG + getDebitorNumberString();
|
return getTaggedDebitorNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RbacView rbac() {
|
public static RbacView rbac() {
|
||||||
|
@ -16,13 +16,16 @@ public interface HsOfficeDebitorRepository extends Repository<HsOfficeDebitorEnt
|
|||||||
JOIN HsOfficePartnerEntity partner
|
JOIN HsOfficePartnerEntity partner
|
||||||
ON partner.partnerRel.holder = debitor.debitorRel.anchor
|
ON partner.partnerRel.holder = debitor.debitorRel.anchor
|
||||||
AND partner.partnerRel.type = 'PARTNER' AND debitor.debitorRel.type = 'DEBITOR'
|
AND partner.partnerRel.type = 'PARTNER' AND debitor.debitorRel.type = 'DEBITOR'
|
||||||
WHERE cast(partner.partnerNumber as integer) = :partnerNumber
|
WHERE partner.partnerNumber = :partnerNumber
|
||||||
AND cast(debitor.debitorNumberSuffix as integer) = :debitorNumberSuffix
|
AND debitor.debitorNumberSuffix = :debitorNumberSuffix
|
||||||
""")
|
""")
|
||||||
List<HsOfficeDebitorEntity> findDebitorByDebitorNumber(int partnerNumber, byte debitorNumberSuffix);
|
List<HsOfficeDebitorEntity> findDebitorByDebitorNumber(int partnerNumber, String debitorNumberSuffix);
|
||||||
|
|
||||||
default List<HsOfficeDebitorEntity> findDebitorByDebitorNumber(int debitorNumber) {
|
default List<HsOfficeDebitorEntity> findDebitorByDebitorNumber(int debitorNumber) {
|
||||||
return findDebitorByDebitorNumber( debitorNumber/100, (byte) (debitorNumber%100));
|
final var partnerNumber = debitorNumber / 100;
|
||||||
|
final String suffix = String.format("%02d", debitorNumber % 100);
|
||||||
|
final var result = findDebitorByDebitorNumber(partnerNumber, suffix);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
|
@ -16,8 +16,10 @@ import java.util.List;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
@RestController
|
import static java.util.Optional.ofNullable;
|
||||||
|
import static net.hostsharing.hsadminng.repr.TaggedNumber.cropTag;
|
||||||
|
|
||||||
|
@RestController
|
||||||
public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
|
public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@ -31,16 +33,18 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public ResponseEntity<List<HsOfficeMembershipResource>> listMemberships(
|
public ResponseEntity<List<HsOfficeMembershipResource>> getListOfMemberships(
|
||||||
final String currentSubject,
|
final String currentSubject,
|
||||||
final String assumedRoles,
|
final String assumedRoles,
|
||||||
UUID partnerUuid,
|
final UUID partnerUuid,
|
||||||
Integer memberNumber) {
|
final String memberNumber) {
|
||||||
context.define(currentSubject, assumedRoles);
|
context.define(currentSubject, assumedRoles);
|
||||||
|
|
||||||
final var entities = ( memberNumber != null)
|
final var entities = (memberNumber != null)
|
||||||
? List.of(membershipRepo.findMembershipByMemberNumber(memberNumber))
|
? ofNullable(membershipRepo.findMembershipByMemberNumber(
|
||||||
: membershipRepo.findMembershipsByOptionalPartnerUuid(partnerUuid);
|
cropTag(HsOfficeMembershipEntity.MEMBER_NUMBER_TAG, memberNumber))).stream()
|
||||||
|
.toList()
|
||||||
|
: membershipRepo.findMembershipsByOptionalPartnerUuid(partnerUuid);
|
||||||
|
|
||||||
final var resources = mapper.mapList(entities, HsOfficeMembershipResource.class,
|
final var resources = mapper.mapList(entities, HsOfficeMembershipResource.class,
|
||||||
SEPA_MANDATE_ENTITY_TO_RESOURCE_POSTMAPPER);
|
SEPA_MANDATE_ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||||
@ -49,7 +53,7 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public ResponseEntity<HsOfficeMembershipResource> addMembership(
|
public ResponseEntity<HsOfficeMembershipResource> postNewMembership(
|
||||||
final String currentSubject,
|
final String currentSubject,
|
||||||
final String assumedRoles,
|
final String assumedRoles,
|
||||||
final HsOfficeMembershipInsertResource body) {
|
final HsOfficeMembershipInsertResource body) {
|
||||||
@ -72,7 +76,7 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public ResponseEntity<HsOfficeMembershipResource> getMembershipByUuid(
|
public ResponseEntity<HsOfficeMembershipResource> getSingleMembershipByUuid(
|
||||||
final String currentSubject,
|
final String currentSubject,
|
||||||
final String assumedRoles,
|
final String assumedRoles,
|
||||||
final UUID membershipUuid) {
|
final UUID membershipUuid) {
|
||||||
@ -123,7 +127,7 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final BiConsumer<HsOfficeMembershipEntity, HsOfficeMembershipResource> SEPA_MANDATE_ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> {
|
final BiConsumer<HsOfficeMembershipEntity, HsOfficeMembershipResource> SEPA_MANDATE_ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> {
|
||||||
// TODO.refa: this should be possible via ModelMapper config
|
resource.setMemberNumber(entity.getTaggedMemberNumber());
|
||||||
resource.setValidFrom(entity.getValidity().lower());
|
resource.setValidFrom(entity.getValidity().lower());
|
||||||
if (entity.getValidity().hasUpperBound()) {
|
if (entity.getValidity().hasUpperBound()) {
|
||||||
resource.setValidTo(entity.getValidity().upper().minusDays(1));
|
resource.setValidTo(entity.getValidity().upper().minusDays(1));
|
||||||
|
@ -13,8 +13,8 @@ import net.hostsharing.hsadminng.persistence.BaseEntity;
|
|||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.repr.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||||
import org.hibernate.annotations.Type;
|
import org.hibernate.annotations.Type;
|
||||||
|
|
||||||
import jakarta.persistence.Column;
|
import jakarta.persistence.Column;
|
||||||
@ -53,7 +53,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.OWNER;
|
|||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.TENANT;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.TENANT;
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.fetchedBySql;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.fetchedBySql;
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(schema = "hs_office", name = "membership_rv")
|
@Table(schema = "hs_office", name = "membership_rv")
|
||||||
@ -130,6 +130,7 @@ public class HsOfficeMembershipEntity implements BaseEntity<HsOfficeMembershipEn
|
|||||||
}
|
}
|
||||||
return validity;
|
return validity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getMemberNumber() {
|
public Integer getMemberNumber() {
|
||||||
if (partner == null || partner.getPartnerNumber() == null || memberNumberSuffix == null ) {
|
if (partner == null || partner.getPartnerNumber() == null || memberNumberSuffix == null ) {
|
||||||
return null;
|
return null;
|
||||||
@ -138,6 +139,10 @@ public class HsOfficeMembershipEntity implements BaseEntity<HsOfficeMembershipEn
|
|||||||
return getPartner().getPartnerNumber() * 100 + Integer.parseInt(memberNumberSuffix, 10);
|
return getPartner().getPartnerNumber() * 100 + Integer.parseInt(memberNumberSuffix, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getTaggedMemberNumber() {
|
||||||
|
return MEMBER_NUMBER_TAG + getMemberNumber();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return stringify.apply(this);
|
return stringify.apply(this);
|
||||||
|
@ -14,14 +14,16 @@ public interface HsOfficeMembershipRepository extends Repository<HsOfficeMembers
|
|||||||
|
|
||||||
HsOfficeMembershipEntity save(final HsOfficeMembershipEntity entity);
|
HsOfficeMembershipEntity save(final HsOfficeMembershipEntity entity);
|
||||||
|
|
||||||
|
List<HsOfficeMembershipEntity> findAll();
|
||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
SELECT membership FROM HsOfficeMembershipEntity membership
|
SELECT membership FROM HsOfficeMembershipEntity membership
|
||||||
WHERE ( CAST(:partnerUuid as org.hibernate.type.UUIDCharType) IS NULL
|
WHERE ( CAST(:partnerUuid as org.hibernate.type.UUIDCharType) IS NULL
|
||||||
OR membership.partner.uuid = :partnerUuid )
|
OR membership.partner.uuid = :partnerUuid )
|
||||||
ORDER BY membership.partner.partnerNumber, membership.memberNumberSuffix
|
ORDER BY membership.partner.partnerNumber, membership.memberNumberSuffix
|
||||||
""")
|
""")
|
||||||
List<HsOfficeMembershipEntity> findMembershipsByOptionalPartnerUuid(UUID partnerUuid);
|
List<HsOfficeMembershipEntity> findMembershipsByOptionalPartnerUuid(UUID partnerUuid);
|
||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
SELECT membership FROM HsOfficeMembershipEntity membership
|
SELECT membership FROM HsOfficeMembershipEntity membership
|
||||||
WHERE (:partnerNumber = membership.partner.partnerNumber)
|
WHERE (:partnerNumber = membership.partner.partnerNumber)
|
||||||
@ -31,10 +33,12 @@ public interface HsOfficeMembershipRepository extends Repository<HsOfficeMembers
|
|||||||
HsOfficeMembershipEntity findMembershipByPartnerNumberAndSuffix(
|
HsOfficeMembershipEntity findMembershipByPartnerNumberAndSuffix(
|
||||||
@NotNull Integer partnerNumber,
|
@NotNull Integer partnerNumber,
|
||||||
@NotNull String suffix);
|
@NotNull String suffix);
|
||||||
|
|
||||||
default HsOfficeMembershipEntity findMembershipByMemberNumber(Integer memberNumber) {
|
default HsOfficeMembershipEntity findMembershipByMemberNumber(Integer memberNumber) {
|
||||||
final var partnerNumber = memberNumber / 100;
|
final var partnerNumber = memberNumber / 100;
|
||||||
final var suffix = memberNumber % 100;
|
final String suffix = String.format("%02d", memberNumber % 100);
|
||||||
return findMembershipByPartnerNumberAndSuffix(partnerNumber, String.format("%02d", suffix));
|
final var result = findMembershipByPartnerNumberAndSuffix(partnerNumber, suffix);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
long count();
|
long count();
|
||||||
|
@ -27,6 +27,7 @@ import java.util.List;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.EX_PARTNER;
|
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.EX_PARTNER;
|
||||||
|
import static net.hostsharing.hsadminng.repr.TaggedNumber.cropTag;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
|
|
||||||
@ -143,13 +144,14 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
|||||||
|
|
||||||
private void optionallyCreateExPartnerRelation(final HsOfficePartnerEntity saved, final HsOfficeRelationRealEntity previousPartnerRel) {
|
private void optionallyCreateExPartnerRelation(final HsOfficePartnerEntity saved, final HsOfficeRelationRealEntity previousPartnerRel) {
|
||||||
if (!saved.getPartnerRel().getUuid().equals(previousPartnerRel.getUuid())) {
|
if (!saved.getPartnerRel().getUuid().equals(previousPartnerRel.getUuid())) {
|
||||||
|
// TODO.impl: we also need to use the new partner-person as the anchor
|
||||||
relationRepo.save(previousPartnerRel.toBuilder().uuid(null).type(EX_PARTNER).build());
|
relationRepo.save(previousPartnerRel.toBuilder().uuid(null).type(EX_PARTNER).build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private HsOfficePartnerEntity createPartnerEntity(final HsOfficePartnerInsertResource body) {
|
private HsOfficePartnerEntity createPartnerEntity(final HsOfficePartnerInsertResource body) {
|
||||||
final var entityToSave = new HsOfficePartnerEntity();
|
final var entityToSave = new HsOfficePartnerEntity();
|
||||||
entityToSave.setPartnerNumber(body.getPartnerNumber());
|
entityToSave.setPartnerNumber(cropTag(HsOfficePartnerEntity.PARTNER_NUMBER_TAG, body.getPartnerNumber()));
|
||||||
entityToSave.setPartnerRel(persistPartnerRel(body.getPartnerRel()));
|
entityToSave.setPartnerRel(persistPartnerRel(body.getPartnerRel()));
|
||||||
entityToSave.setDetails(mapper.map(body.getDetails(), HsOfficePartnerDetailsEntity.class));
|
entityToSave.setDetails(mapper.map(body.getDetails(), HsOfficePartnerDetailsEntity.class));
|
||||||
return entityToSave;
|
return entityToSave;
|
||||||
|
@ -5,8 +5,8 @@ import net.hostsharing.hsadminng.errors.DisplayAs;
|
|||||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.repr.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -17,7 +17,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
|
|||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(schema = "hs_office", name = "partner_details_rv")
|
@Table(schema = "hs_office", name = "partner_details_rv")
|
||||||
|
@ -14,8 +14,8 @@ import net.hostsharing.hsadminng.persistence.BaseEntity;
|
|||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
||||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.repr.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||||
import org.hibernate.annotations.NotFound;
|
import org.hibernate.annotations.NotFound;
|
||||||
import org.hibernate.annotations.NotFoundAction;
|
import org.hibernate.annotations.NotFoundAction;
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
|||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||||
import static java.util.Optional.ofNullable;
|
import static java.util.Optional.ofNullable;
|
||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(schema = "hs_office", name = "partner_rv")
|
@Table(schema = "hs_office", name = "partner_rv")
|
||||||
|
@ -6,8 +6,8 @@ import net.hostsharing.hsadminng.errors.DisplayAs;
|
|||||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.repr.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
@ -19,7 +19,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
|
|||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacSubjectReference.UserRole.CREATOR;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacSubjectReference.UserRole.CREATOR;
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
||||||
|
|
||||||
// TODO.refa: split HsOfficePersonEntity into Real+Rbac-Entity
|
// TODO.refa: split HsOfficePersonEntity into Real+Rbac-Entity
|
||||||
@Entity
|
@Entity
|
||||||
|
@ -4,6 +4,7 @@ import jakarta.persistence.AttributeConverter;
|
|||||||
import jakarta.persistence.Converter;
|
import jakarta.persistence.Converter;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
// HOWTO: convert data types for exchange between PostgreSQL and Java/Hibernate/JPA-Entities
|
||||||
@Converter(autoApply = true)
|
@Converter(autoApply = true)
|
||||||
public class HsOfficePersonTypeConverter implements AttributeConverter<HsOfficePersonType, String> {
|
public class HsOfficePersonTypeConverter implements AttributeConverter<HsOfficePersonType, String> {
|
||||||
|
|
||||||
|
@ -6,14 +6,14 @@ import lombok.experimental.SuperBuilder;
|
|||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.repr.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import jakarta.persistence.Column;
|
import jakarta.persistence.Column;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
||||||
|
|
||||||
@MappedSuperclass
|
@MappedSuperclass
|
||||||
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
||||||
|
@ -47,7 +47,7 @@ public interface HsOfficeRelationRbacRepository extends Repository<HsOfficeRelat
|
|||||||
OR lower(rel.anchor.givenName) LIKE :personData OR lower(rel.holder.givenName) LIKE :personData )
|
OR lower(rel.anchor.givenName) LIKE :personData OR lower(rel.holder.givenName) LIKE :personData )
|
||||||
AND ( :contactData IS NULL
|
AND ( :contactData IS NULL
|
||||||
OR lower(rel.contact.caption) LIKE :contactData
|
OR lower(rel.contact.caption) LIKE :contactData
|
||||||
OR lower(rel.contact.postalAddress) LIKE :contactData
|
OR lower(CAST(rel.contact.postalAddress AS String)) LIKE :contactData
|
||||||
OR lower(CAST(rel.contact.emailAddresses AS String)) LIKE :contactData
|
OR lower(CAST(rel.contact.emailAddresses AS String)) LIKE :contactData
|
||||||
OR lower(CAST(rel.contact.phoneNumbers AS String)) LIKE :contactData )
|
OR lower(CAST(rel.contact.phoneNumbers AS String)) LIKE :contactData )
|
||||||
""")
|
""")
|
||||||
|
@ -8,5 +8,6 @@ public enum HsOfficeRelationType {
|
|||||||
VIP_CONTACT,
|
VIP_CONTACT,
|
||||||
DEBITOR,
|
DEBITOR,
|
||||||
OPERATIONS,
|
OPERATIONS,
|
||||||
|
OPERATIONS_ALERT,
|
||||||
SUBSCRIBER
|
SUBSCRIBER
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,7 @@ public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi {
|
|||||||
if (entity.getValidity().hasUpperBound()) {
|
if (entity.getValidity().hasUpperBound()) {
|
||||||
resource.setValidTo(entity.getValidity().upper().minusDays(1));
|
resource.setValidTo(entity.getValidity().upper().minusDays(1));
|
||||||
}
|
}
|
||||||
resource.getDebitor().setDebitorNumber(entity.getDebitor().getDebitorNumber());
|
resource.getDebitor().setDebitorNumber(entity.getDebitor().getTaggedDebitorNumber());
|
||||||
};
|
};
|
||||||
|
|
||||||
final BiConsumer<HsOfficeSepaMandateInsertResource, HsOfficeSepaMandateEntity> SEPA_MANDATE_RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
|
final BiConsumer<HsOfficeSepaMandateInsertResource, HsOfficeSepaMandateEntity> SEPA_MANDATE_RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
|
||||||
|
@ -9,8 +9,8 @@ import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
|||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
|
||||||
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
import net.hostsharing.hsadminng.persistence.BaseEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.repr.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||||
import org.hibernate.annotations.Type;
|
import org.hibernate.annotations.Type;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
@ -30,7 +30,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacSubjectRefer
|
|||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.*;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.*;
|
||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.repr.Stringify.stringify;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(schema = "hs_office", name = "sepamandate_rv")
|
@Table(schema = "hs_office", name = "sepamandate_rv")
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package net.hostsharing.hsadminng.stringify;
|
package net.hostsharing.hsadminng.repr;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package net.hostsharing.hsadminng.stringify;
|
package net.hostsharing.hsadminng.repr;
|
||||||
|
|
||||||
public interface Stringifyable {
|
public interface Stringifyable {
|
||||||
|
|
@ -0,0 +1,15 @@
|
|||||||
|
package net.hostsharing.hsadminng.repr;
|
||||||
|
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
|
@UtilityClass
|
||||||
|
public class TaggedNumber {
|
||||||
|
|
||||||
|
public static Integer cropTag(final String tag, final String taggedNumber) {
|
||||||
|
return taggedNumber.startsWith(tag) ? Integer.valueOf(taggedNumber.substring(tag.length())) : invalidTag(tag, taggedNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Integer invalidTag(final String tag, final String taggedNumber) {
|
||||||
|
throw new IllegalArgumentException("Expected " + tag + "... but got: " + taggedNumber);
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,7 @@ public class SystemProcess {
|
|||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private String stdOut;
|
private String stdOut;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private String stdErr;
|
private String stdErr;
|
||||||
|
|
||||||
@ -21,7 +22,6 @@ public class SystemProcess {
|
|||||||
this.processBuilder = new ProcessBuilder(command);
|
this.processBuilder = new ProcessBuilder(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getCommand() {
|
public String getCommand() {
|
||||||
return processBuilder.command().toString();
|
return processBuilder.command().toString();
|
||||||
}
|
}
|
||||||
|
@ -52,11 +52,11 @@ components:
|
|||||||
HsBookingItemInsert:
|
HsBookingItemInsert:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
projectUuid:
|
project.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: false
|
nullable: false
|
||||||
parentItemUuid:
|
parentItem.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: false
|
nullable: false
|
||||||
@ -77,7 +77,7 @@ components:
|
|||||||
$ref: '../hs-hosting/hs-hosting-asset-schemas.yaml#/components/schemas/HsHostingAssetAutoInsert'
|
$ref: '../hs-hosting/hs-hosting-asset-schemas.yaml#/components/schemas/HsHostingAssetAutoInsert'
|
||||||
required:
|
required:
|
||||||
- caption
|
- caption
|
||||||
- projectUuid
|
- project.uuid
|
||||||
- validFrom
|
- validFrom
|
||||||
- resources
|
- resources
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
|
@ -25,7 +25,7 @@ components:
|
|||||||
HsBookingProjectInsert:
|
HsBookingProjectInsert:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
debitorUuid:
|
debitor.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: false
|
nullable: false
|
||||||
@ -35,6 +35,6 @@ components:
|
|||||||
maxLength: 80
|
maxLength: 80
|
||||||
nullable: false
|
nullable: false
|
||||||
required:
|
required:
|
||||||
- debitorUuid
|
- debitor.uuid
|
||||||
- caption
|
- caption
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
|
@ -54,7 +54,7 @@ components:
|
|||||||
caption:
|
caption:
|
||||||
type: string
|
type: string
|
||||||
nullable: true
|
nullable: true
|
||||||
alarmContactUuid:
|
alarmContact.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: true
|
nullable: true
|
||||||
@ -64,11 +64,11 @@ components:
|
|||||||
HsHostingAssetInsert:
|
HsHostingAssetInsert:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
bookingItemUuid:
|
bookingItem.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: true
|
nullable: true
|
||||||
parentAssetUuid:
|
parentAsset.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: true
|
nullable: true
|
||||||
@ -84,7 +84,7 @@ components:
|
|||||||
minLength: 3
|
minLength: 3
|
||||||
maxLength: 80
|
maxLength: 80
|
||||||
nullable: false
|
nullable: false
|
||||||
alarmContactUuid:
|
alarmContact.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: true
|
nullable: true
|
||||||
@ -99,11 +99,11 @@ components:
|
|||||||
HsHostingAssetAutoInsert:
|
HsHostingAssetAutoInsert:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
parentAssetUuid:
|
parentAsset.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: true
|
nullable: true
|
||||||
assignedToAssetUuid:
|
assignedToAsset.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
type:
|
type:
|
||||||
@ -118,7 +118,7 @@ components:
|
|||||||
minLength: 3
|
minLength: 3
|
||||||
maxLength: 80
|
maxLength: 80
|
||||||
nullable: false
|
nullable: false
|
||||||
alarmContactUuid:
|
alarmContact.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: true
|
nullable: true
|
||||||
@ -147,10 +147,10 @@ components:
|
|||||||
minLength: 3
|
minLength: 3
|
||||||
maxLength: 80
|
maxLength: 80
|
||||||
nullable: false
|
nullable: false
|
||||||
assignedToAssetUuid:
|
assignedToAsset.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
alarmContactUuid:
|
alarmContact.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: true
|
nullable: true
|
||||||
|
@ -12,7 +12,7 @@ components:
|
|||||||
caption:
|
caption:
|
||||||
type: string
|
type: string
|
||||||
postalAddress:
|
postalAddress:
|
||||||
type: string
|
$ref: '#/components/schemas/HsOfficeContactPostalAddress'
|
||||||
emailAddresses:
|
emailAddresses:
|
||||||
$ref: '#/components/schemas/HsOfficeContactEmailAddresses'
|
$ref: '#/components/schemas/HsOfficeContactEmailAddresses'
|
||||||
phoneNumbers:
|
phoneNumbers:
|
||||||
@ -24,7 +24,7 @@ components:
|
|||||||
caption:
|
caption:
|
||||||
type: string
|
type: string
|
||||||
postalAddress:
|
postalAddress:
|
||||||
type: string
|
$ref: '#/components/schemas/HsOfficeContactPostalAddress'
|
||||||
emailAddresses:
|
emailAddresses:
|
||||||
$ref: '#/components/schemas/HsOfficeContactEmailAddresses'
|
$ref: '#/components/schemas/HsOfficeContactEmailAddresses'
|
||||||
phoneNumbers:
|
phoneNumbers:
|
||||||
@ -39,21 +39,48 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
nullable: true
|
nullable: true
|
||||||
postalAddress:
|
postalAddress:
|
||||||
type: string
|
$ref: '#/components/schemas/HsOfficeContactPostalAddress'
|
||||||
nullable: true
|
|
||||||
emailAddresses:
|
emailAddresses:
|
||||||
$ref: '#/components/schemas/HsOfficeContactEmailAddresses'
|
$ref: '#/components/schemas/HsOfficeContactEmailAddresses'
|
||||||
phoneNumbers:
|
phoneNumbers:
|
||||||
$ref: '#/components/schemas/HsOfficeContactPhoneNumbers'
|
$ref: '#/components/schemas/HsOfficeContactPhoneNumbers'
|
||||||
|
|
||||||
|
HsOfficeContactPostalAddress:
|
||||||
|
# forces generating a java.lang.Object containing a Map, instead of a class with fixed properties
|
||||||
|
anyOf:
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
firm:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
co:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
street:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
zipcode:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
city:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
country:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
additionalProperties: true
|
||||||
|
|
||||||
HsOfficeContactEmailAddresses:
|
HsOfficeContactEmailAddresses:
|
||||||
# forces generating a java.lang.Object containing a Map, instead of class HsOfficeContactEmailAddresses
|
# forces generating a java.lang.Object containing a Map, instead of a class with fixed properties
|
||||||
anyOf:
|
anyOf:
|
||||||
- type: object
|
- type: object
|
||||||
additionalProperties: true
|
additionalProperties: true
|
||||||
|
|
||||||
HsOfficeContactPhoneNumbers:
|
HsOfficeContactPhoneNumbers:
|
||||||
# forces generating a java.lang.Object containing a Map, instead of class HsOfficeContactEmailAddresses
|
# forces generating a java.lang.Object containing a Map, instead of a class with fixed properties
|
||||||
anyOf:
|
anyOf:
|
||||||
- type: object
|
- type: object
|
||||||
properties:
|
properties:
|
||||||
|
@ -6,7 +6,7 @@ components:
|
|||||||
HsOfficeCoopAssetsTransactionType:
|
HsOfficeCoopAssetsTransactionType:
|
||||||
type: string
|
type: string
|
||||||
enum:
|
enum:
|
||||||
- ADJUSTMENT
|
- REVERSAL
|
||||||
- DEPOSIT
|
- DEPOSIT
|
||||||
- DISBURSAL
|
- DISBURSAL
|
||||||
- TRANSFER
|
- TRANSFER
|
||||||
@ -32,15 +32,15 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
comment:
|
comment:
|
||||||
type: string
|
type: string
|
||||||
adjustedAssetTx:
|
revertedAssetTx:
|
||||||
$ref: '#/components/schemas/HsOfficeReferencedCoopAssetsTransaction'
|
$ref: '#/components/schemas/HsOfficeReferencedCoopAssetsTransaction'
|
||||||
adjustmentAssetTx:
|
reversalAssetTx:
|
||||||
$ref: '#/components/schemas/HsOfficeReferencedCoopAssetsTransaction'
|
$ref: '#/components/schemas/HsOfficeReferencedCoopAssetsTransaction'
|
||||||
|
|
||||||
HsOfficeReferencedCoopAssetsTransaction:
|
HsOfficeReferencedCoopAssetsTransaction:
|
||||||
description:
|
description:
|
||||||
Similar to `HsOfficeCoopAssetsTransaction` but without the self-referencing properties
|
Similar to `HsOfficeCoopAssetsTransaction` but without the self-referencing properties
|
||||||
(`adjustedAssetTx` and `adjustmentAssetTx`), to avoid recursive JSON.
|
(`revertedAssetTx` and `reversalAssetTx`), to avoid recursive JSON.
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
uuid:
|
uuid:
|
||||||
@ -62,7 +62,7 @@ components:
|
|||||||
HsOfficeCoopAssetsTransactionInsert:
|
HsOfficeCoopAssetsTransactionInsert:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
membershipUuid:
|
membership.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: false
|
nullable: false
|
||||||
@ -80,11 +80,11 @@ components:
|
|||||||
maxLength: 48
|
maxLength: 48
|
||||||
comment:
|
comment:
|
||||||
type: string
|
type: string
|
||||||
reverseEntryUuid:
|
revertedAssetTx.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
required:
|
required:
|
||||||
- membershipUuid
|
- membership.uuid
|
||||||
- transactionType
|
- transactionType
|
||||||
- assetValue
|
- assetValue
|
||||||
- valueDate
|
- valueDate
|
||||||
|
@ -2,7 +2,7 @@ get:
|
|||||||
tags:
|
tags:
|
||||||
- hs-office-coopAssets
|
- hs-office-coopAssets
|
||||||
description: 'Fetch a single asset transaction by its uuid, if visible for the current subject.'
|
description: 'Fetch a single asset transaction by its uuid, if visible for the current subject.'
|
||||||
operationId: getCoopAssetTransactionByUuid
|
operationId: getSingleCoopAssetTransactionByUuid
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||||
|
@ -3,7 +3,7 @@ get:
|
|||||||
description: Returns the list of (optionally filtered) cooperative asset transactions which are visible to the current subject or any of it's assumed roles.
|
description: Returns the list of (optionally filtered) cooperative asset transactions which are visible to the current subject or any of it's assumed roles.
|
||||||
tags:
|
tags:
|
||||||
- hs-office-coopAssets
|
- hs-office-coopAssets
|
||||||
operationId: listCoopAssets
|
operationId: getListOfCoopAssets
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||||
@ -46,7 +46,7 @@ post:
|
|||||||
summary: Adds a new cooperative asset transaction.
|
summary: Adds a new cooperative asset transaction.
|
||||||
tags:
|
tags:
|
||||||
- hs-office-coopAssets
|
- hs-office-coopAssets
|
||||||
operationId: addCoopAssetsTransaction
|
operationId: postNewCoopAssetTransaction
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||||
|
@ -6,7 +6,7 @@ components:
|
|||||||
HsOfficeCoopSharesTransactionType:
|
HsOfficeCoopSharesTransactionType:
|
||||||
type: string
|
type: string
|
||||||
enum:
|
enum:
|
||||||
- ADJUSTMENT
|
- REVERSAL
|
||||||
- SUBSCRIPTION
|
- SUBSCRIPTION
|
||||||
- CANCELLATION
|
- CANCELLATION
|
||||||
|
|
||||||
@ -27,15 +27,15 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
comment:
|
comment:
|
||||||
type: string
|
type: string
|
||||||
adjustedShareTx:
|
revertedShareTx:
|
||||||
$ref: '#/components/schemas/HsOfficeReferencedCoopSharesTransaction'
|
$ref: '#/components/schemas/HsOfficeReferencedCoopSharesTransaction'
|
||||||
adjustmentShareTx:
|
reversalShareTx:
|
||||||
$ref: '#/components/schemas/HsOfficeReferencedCoopSharesTransaction'
|
$ref: '#/components/schemas/HsOfficeReferencedCoopSharesTransaction'
|
||||||
|
|
||||||
HsOfficeReferencedCoopSharesTransaction:
|
HsOfficeReferencedCoopSharesTransaction:
|
||||||
description:
|
description:
|
||||||
Similar to `HsOfficeCoopSharesTransaction` but without the self-referencing properties
|
Similar to `HsOfficeCoopSharesTransaction` but without the self-referencing properties
|
||||||
(`adjustedShareTx` and `adjustmentShareTx`), to avoid recursive JSON.
|
(`revertedShareTx` and `reversalShareTx`), to avoid recursive JSON.
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
uuid:
|
uuid:
|
||||||
@ -56,7 +56,7 @@ components:
|
|||||||
HsOfficeCoopSharesTransactionInsert:
|
HsOfficeCoopSharesTransactionInsert:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
membershipUuid:
|
membership.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: false
|
nullable: false
|
||||||
@ -73,11 +73,11 @@ components:
|
|||||||
maxLength: 48
|
maxLength: 48
|
||||||
comment:
|
comment:
|
||||||
type: string
|
type: string
|
||||||
adjustedShareTxUuid:
|
revertedShareTx.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
required:
|
required:
|
||||||
- membershipUuid
|
- membership.uuid
|
||||||
- transactionType
|
- transactionType
|
||||||
- shareCount
|
- shareCount
|
||||||
- valueDate
|
- valueDate
|
||||||
|
@ -2,7 +2,7 @@ get:
|
|||||||
tags:
|
tags:
|
||||||
- hs-office-coopShares
|
- hs-office-coopShares
|
||||||
description: 'Fetch a single share transaction by its uuid, if visible for the current subject.'
|
description: 'Fetch a single share transaction by its uuid, if visible for the current subject.'
|
||||||
operationId: getCoopShareTransactionByUuid
|
operationId: getSingleCoopShareTransactionByUuid
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||||
|
@ -3,7 +3,7 @@ get:
|
|||||||
description: Returns the list of (optionally filtered) cooperative share transactions which are visible to the current subject or any of it's assumed roles.
|
description: Returns the list of (optionally filtered) cooperative share transactions which are visible to the current subject or any of it's assumed roles.
|
||||||
tags:
|
tags:
|
||||||
- hs-office-coopShares
|
- hs-office-coopShares
|
||||||
operationId: listCoopShares
|
operationId: getListOfCoopShares
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||||
@ -46,7 +46,7 @@ post:
|
|||||||
summary: Adds a new cooperative share transaction.
|
summary: Adds a new cooperative share transaction.
|
||||||
tags:
|
tags:
|
||||||
- hs-office-coopShares
|
- hs-office-coopShares
|
||||||
operationId: addCoopSharesTransaction
|
operationId: postNewCoopSharesTransaction
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||||
|
@ -12,15 +12,13 @@ components:
|
|||||||
debitorRel:
|
debitorRel:
|
||||||
$ref: 'hs-office-relation-schemas.yaml#/components/schemas/HsOfficeRelation'
|
$ref: 'hs-office-relation-schemas.yaml#/components/schemas/HsOfficeRelation'
|
||||||
debitorNumber:
|
debitorNumber:
|
||||||
type: integer
|
type: string
|
||||||
format: int32
|
minLength: 9
|
||||||
minimum: 1000000
|
maxLength: 9
|
||||||
maximum: 9999999
|
pattern: 'D-[0-9]{7}'
|
||||||
debitorNumberSuffix:
|
debitorNumberSuffix:
|
||||||
type: integer
|
type: string
|
||||||
format: int8
|
pattern: '^[0-9][0-9]$'
|
||||||
minimum: 00
|
|
||||||
maximum: 99
|
|
||||||
partner:
|
partner:
|
||||||
$ref: 'hs-office-partner-schemas.yaml#/components/schemas/HsOfficePartner'
|
$ref: 'hs-office-partner-schemas.yaml#/components/schemas/HsOfficePartner'
|
||||||
billable:
|
billable:
|
||||||
@ -43,7 +41,7 @@ components:
|
|||||||
HsOfficeDebitorPatch:
|
HsOfficeDebitorPatch:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
debitorRelUuid:
|
debitorRel.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: true
|
nullable: true
|
||||||
@ -63,7 +61,7 @@ components:
|
|||||||
vatReverseCharge:
|
vatReverseCharge:
|
||||||
type: boolean
|
type: boolean
|
||||||
nullable: false
|
nullable: false
|
||||||
refundBankAccountUuid:
|
refundBankAccount.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: true
|
nullable: true
|
||||||
@ -76,15 +74,13 @@ components:
|
|||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
debitorRel:
|
debitorRel:
|
||||||
$ref: 'hs-office-relation-schemas.yaml#/components/schemas/HsOfficeRelationInsert'
|
$ref: 'hs-office-relation-schemas.yaml#/components/schemas/HsOfficeRelationSubInsert'
|
||||||
debitorRelUuid:
|
debitorRel.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
debitorNumberSuffix:
|
debitorNumberSuffix:
|
||||||
type: integer
|
type: string
|
||||||
format: int8
|
pattern: '^[0-9][0-9]$'
|
||||||
minimum: 00
|
|
||||||
maximum: 99
|
|
||||||
billable:
|
billable:
|
||||||
type: boolean
|
type: boolean
|
||||||
vatId:
|
vatId:
|
||||||
@ -96,7 +92,7 @@ components:
|
|||||||
type: boolean
|
type: boolean
|
||||||
vatReverseCharge:
|
vatReverseCharge:
|
||||||
type: boolean
|
type: boolean
|
||||||
refundBankAccountUuid:
|
refundBankAccount.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
defaultPrefix:
|
defaultPrefix:
|
||||||
|
@ -2,7 +2,7 @@ get:
|
|||||||
tags:
|
tags:
|
||||||
- hs-office-debitors
|
- hs-office-debitors
|
||||||
description: 'Fetch a single debitor by its uuid, if visible for the current subject.'
|
description: 'Fetch a single debitor by its uuid, if visible for the current subject.'
|
||||||
operationId: getDebitorByUuid
|
operationId: getSingleDebitorByUuid
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||||
|
@ -3,7 +3,7 @@ get:
|
|||||||
description: Returns the list of (optionally filtered) debitors which are visible to the current subject or any of it's assumed roles.
|
description: Returns the list of (optionally filtered) debitors which are visible to the current subject or any of it's assumed roles.
|
||||||
tags:
|
tags:
|
||||||
- hs-office-debitors
|
- hs-office-debitors
|
||||||
operationId: listDebitors
|
operationId: getListOfDebitors
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||||
@ -17,7 +17,10 @@ get:
|
|||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
schema:
|
schema:
|
||||||
type: integer
|
type: string
|
||||||
|
minLength: 9
|
||||||
|
maxLength: 9
|
||||||
|
pattern: 'D-[0-9]{7}'
|
||||||
description: Debitor number of the requested debitor.
|
description: Debitor number of the requested debitor.
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
@ -37,7 +40,7 @@ post:
|
|||||||
summary: Adds a new debitor.
|
summary: Adds a new debitor.
|
||||||
tags:
|
tags:
|
||||||
- hs-office-debitors
|
- hs-office-debitors
|
||||||
operationId: addDebitor
|
operationId: postNewDebitor
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||||
|
@ -26,9 +26,10 @@ components:
|
|||||||
mainDebitor:
|
mainDebitor:
|
||||||
$ref: 'hs-office-debitor-schemas.yaml#/components/schemas/HsOfficeDebitor'
|
$ref: 'hs-office-debitor-schemas.yaml#/components/schemas/HsOfficeDebitor'
|
||||||
memberNumber:
|
memberNumber:
|
||||||
type: integer
|
type: string
|
||||||
minimum: 1000000
|
minLength: 9
|
||||||
maximum: 9999999
|
maxLength: 9
|
||||||
|
pattern: 'M-[0-9]{7}'
|
||||||
memberNumberSuffix:
|
memberNumberSuffix:
|
||||||
type: string
|
type: string
|
||||||
minLength: 2
|
minLength: 2
|
||||||
@ -62,7 +63,7 @@ components:
|
|||||||
HsOfficeMembershipInsert:
|
HsOfficeMembershipInsert:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
partnerUuid:
|
partner.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: false
|
nullable: false
|
||||||
@ -86,7 +87,7 @@ components:
|
|||||||
nullable: false
|
nullable: false
|
||||||
type: boolean
|
type: boolean
|
||||||
required:
|
required:
|
||||||
- partnerUuid
|
- partner.uuid
|
||||||
- memberNumberSuffix
|
- memberNumberSuffix
|
||||||
- validFrom
|
- validFrom
|
||||||
- membershipFeeBillable
|
- membershipFeeBillable
|
||||||
|
@ -2,7 +2,7 @@ get:
|
|||||||
tags:
|
tags:
|
||||||
- hs-office-memberships
|
- hs-office-memberships
|
||||||
description: 'Fetch a single membership by its uuid, if visible for the current subject.'
|
description: 'Fetch a single membership by its uuid, if visible for the current subject.'
|
||||||
operationId: getMembershipByUuid
|
operationId: getSingleMembershipByUuid
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||||
|
@ -4,7 +4,7 @@ get:
|
|||||||
The list can optionally be filtered by either the `partnerUuid` or the `memberNumber` - not both at the same time.
|
The list can optionally be filtered by either the `partnerUuid` or the `memberNumber` - not both at the same time.
|
||||||
tags:
|
tags:
|
||||||
- hs-office-memberships
|
- hs-office-memberships
|
||||||
operationId: listMemberships
|
operationId: getListOfMemberships
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||||
@ -19,7 +19,10 @@ get:
|
|||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
schema:
|
schema:
|
||||||
type: integer
|
type: string
|
||||||
|
minLength: 9
|
||||||
|
maxLength: 9
|
||||||
|
pattern: 'M-[0-9]{7}'
|
||||||
description: Member number, exclusive to `partnerUuid`.
|
description: Member number, exclusive to `partnerUuid`.
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
@ -39,7 +42,7 @@ post:
|
|||||||
summary: Adds a new membership.
|
summary: Adds a new membership.
|
||||||
tags:
|
tags:
|
||||||
- hs-office-memberships
|
- hs-office-memberships
|
||||||
operationId: addMembership
|
operationId: postNewMembership
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||||
|
@ -10,10 +10,10 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
partnerNumber:
|
partnerNumber:
|
||||||
type: integer
|
type: string
|
||||||
format: int8
|
minLength: 7
|
||||||
minimum: 10000
|
maxLength: 7
|
||||||
maximum: 99999
|
pattern: 'P-[0-9]{5}'
|
||||||
partnerRel:
|
partnerRel:
|
||||||
$ref: 'hs-office-relation-schemas.yaml#/components/schemas/HsOfficeRelation'
|
$ref: 'hs-office-relation-schemas.yaml#/components/schemas/HsOfficeRelation'
|
||||||
details:
|
details:
|
||||||
@ -50,7 +50,7 @@ components:
|
|||||||
HsOfficePartnerPatch:
|
HsOfficePartnerPatch:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
partnerRelUuid:
|
partnerRel.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: true
|
nullable: true
|
||||||
@ -86,10 +86,10 @@ components:
|
|||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
partnerNumber:
|
partnerNumber:
|
||||||
type: integer
|
type: string
|
||||||
format: int8
|
minLength: 7
|
||||||
minimum: 10000
|
maxLength: 7
|
||||||
maximum: 99999
|
pattern: 'P-[0-9]{5}'
|
||||||
partnerRel:
|
partnerRel:
|
||||||
$ref: '#/components/schemas/HsOfficePartnerRelInsert'
|
$ref: '#/components/schemas/HsOfficePartnerRelInsert'
|
||||||
details:
|
details:
|
||||||
@ -103,19 +103,19 @@ components:
|
|||||||
type: object
|
type: object
|
||||||
nullable: false
|
nullable: false
|
||||||
properties:
|
properties:
|
||||||
anchorUuid:
|
anchor.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
holderUuid:
|
holder.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
contactUuid:
|
contact.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
required:
|
required:
|
||||||
- anchorUuid
|
- anchor.uuid
|
||||||
- holderUuid
|
- holder.uuid
|
||||||
- relContactUuid
|
- relContact.uuid
|
||||||
|
|
||||||
HsOfficePartnerDetailsInsert:
|
HsOfficePartnerDetailsInsert:
|
||||||
type: object
|
type: object
|
||||||
|
@ -13,6 +13,7 @@ components:
|
|||||||
- REPRESENTATIVE
|
- REPRESENTATIVE
|
||||||
- VIP_CONTACT
|
- VIP_CONTACT
|
||||||
- OPERATIONS
|
- OPERATIONS
|
||||||
|
- OPERATIONS_ALERT
|
||||||
- SUBSCRIBER
|
- SUBSCRIBER
|
||||||
|
|
||||||
HsOfficeRelation:
|
HsOfficeRelation:
|
||||||
@ -36,18 +37,19 @@ components:
|
|||||||
HsOfficeRelationPatch:
|
HsOfficeRelationPatch:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
contactUuid:
|
contact.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: true
|
nullable: true
|
||||||
|
|
||||||
|
# arbitrary relation with explicit type
|
||||||
HsOfficeRelationInsert:
|
HsOfficeRelationInsert:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
anchorUuid:
|
anchor.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
holderUuid:
|
holder.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
type:
|
type:
|
||||||
@ -56,11 +58,32 @@ components:
|
|||||||
mark:
|
mark:
|
||||||
type: string
|
type: string
|
||||||
nullable: true
|
nullable: true
|
||||||
contactUuid:
|
contact.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
required:
|
required:
|
||||||
- anchorUuid
|
- anchor.uuid
|
||||||
- holderUuid
|
- holder.uuid
|
||||||
- type
|
- type
|
||||||
- contactUuid
|
- contact.uuid
|
||||||
|
|
||||||
|
# relation created as a sub-element with implicitly known type
|
||||||
|
HsOfficeRelationSubInsert:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
anchor.uuid:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
holder.uuid:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
mark:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
contact.uuid:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
required:
|
||||||
|
- anchor.uuid
|
||||||
|
- holder.uuid
|
||||||
|
- contact.uuid
|
||||||
|
@ -48,11 +48,11 @@ components:
|
|||||||
HsOfficeSepaMandateInsert:
|
HsOfficeSepaMandateInsert:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
debitorUuid:
|
debitor.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: false
|
nullable: false
|
||||||
bankAccountUuid:
|
bankAccount.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: false
|
nullable: false
|
||||||
@ -72,8 +72,8 @@ components:
|
|||||||
format: date
|
format: date
|
||||||
nullable: true
|
nullable: true
|
||||||
required:
|
required:
|
||||||
- debitorUuid
|
- debitor.uuid
|
||||||
- bankAccountUuid
|
- bankAccount.uuid
|
||||||
- reference
|
- reference
|
||||||
- agreement
|
- agreement
|
||||||
- validFrom
|
- validFrom
|
||||||
|
@ -7,7 +7,7 @@ get:
|
|||||||
parameters:
|
parameters:
|
||||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||||
- name: name
|
- name: iban
|
||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
schema:
|
schema:
|
||||||
|
@ -8,21 +8,21 @@ components:
|
|||||||
properties:
|
properties:
|
||||||
grantedByRoleIdName:
|
grantedByRoleIdName:
|
||||||
type: string
|
type: string
|
||||||
grantedByRoleUuid:
|
grantedByRole.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
assumed:
|
assumed:
|
||||||
type: boolean
|
type: boolean
|
||||||
grantedRoleIdName:
|
grantedRoleIdName:
|
||||||
type: string
|
type: string
|
||||||
grantedRoleUuid:
|
grantedRole.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
granteeSubjectName:
|
granteeSubjectName:
|
||||||
type: string
|
type: string
|
||||||
granteeSubjectUuid:
|
granteeSubject.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
required:
|
required:
|
||||||
- grantedRoleUuid
|
- grantedRole.uuid
|
||||||
- granteeSubjectUuid
|
- granteeSubject.uuid
|
||||||
|
@ -9,7 +9,7 @@ components:
|
|||||||
uuid:
|
uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
objectUuid:
|
object.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
objectTable:
|
objectTable:
|
||||||
|
@ -14,7 +14,7 @@ components:
|
|||||||
RbacSubjectPermission:
|
RbacSubjectPermission:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
objectUuid:
|
object.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
objectTable:
|
objectTable:
|
||||||
@ -23,10 +23,10 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
roleName:
|
roleName:
|
||||||
type: string
|
type: string
|
||||||
roleUuid:
|
role.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
permissionUuid:
|
permission.uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
op:
|
op:
|
||||||
|
@ -36,7 +36,7 @@ begin
|
|||||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM rbactest.customer WHERE uuid = NEW.customerUuid INTO newCustomer;
|
SELECT * FROM rbactest.customer WHERE uuid = NEW.customerUuid INTO newCustomer;
|
||||||
assert newCustomer.uuid is not null, format('newCustomer must not be null for NEW.customerUuid = %s', NEW.customerUuid);
|
assert newCustomer.uuid is not null, format('newCustomer must not be null for NEW.customerUuid = %s of package', NEW.customerUuid);
|
||||||
|
|
||||||
|
|
||||||
perform rbac.defineRoleWithGrants(
|
perform rbac.defineRoleWithGrants(
|
||||||
@ -102,10 +102,10 @@ begin
|
|||||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM rbactest.customer WHERE uuid = OLD.customerUuid INTO oldCustomer;
|
SELECT * FROM rbactest.customer WHERE uuid = OLD.customerUuid INTO oldCustomer;
|
||||||
assert oldCustomer.uuid is not null, format('oldCustomer must not be null for OLD.customerUuid = %s', OLD.customerUuid);
|
assert oldCustomer.uuid is not null, format('oldCustomer must not be null for OLD.customerUuid = %s of package', OLD.customerUuid);
|
||||||
|
|
||||||
SELECT * FROM rbactest.customer WHERE uuid = NEW.customerUuid INTO newCustomer;
|
SELECT * FROM rbactest.customer WHERE uuid = NEW.customerUuid INTO newCustomer;
|
||||||
assert newCustomer.uuid is not null, format('newCustomer must not be null for NEW.customerUuid = %s', NEW.customerUuid);
|
assert newCustomer.uuid is not null, format('newCustomer must not be null for NEW.customerUuid = %s of package', NEW.customerUuid);
|
||||||
|
|
||||||
|
|
||||||
if NEW.customerUuid <> OLD.customerUuid then
|
if NEW.customerUuid <> OLD.customerUuid then
|
||||||
|
@ -36,7 +36,7 @@ begin
|
|||||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM rbactest.package WHERE uuid = NEW.packageUuid INTO newPackage;
|
SELECT * FROM rbactest.package WHERE uuid = NEW.packageUuid INTO newPackage;
|
||||||
assert newPackage.uuid is not null, format('newPackage must not be null for NEW.packageUuid = %s', NEW.packageUuid);
|
assert newPackage.uuid is not null, format('newPackage must not be null for NEW.packageUuid = %s of domain', NEW.packageUuid);
|
||||||
|
|
||||||
|
|
||||||
perform rbac.defineRoleWithGrants(
|
perform rbac.defineRoleWithGrants(
|
||||||
@ -98,10 +98,10 @@ begin
|
|||||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM rbactest.package WHERE uuid = OLD.packageUuid INTO oldPackage;
|
SELECT * FROM rbactest.package WHERE uuid = OLD.packageUuid INTO oldPackage;
|
||||||
assert oldPackage.uuid is not null, format('oldPackage must not be null for OLD.packageUuid = %s', OLD.packageUuid);
|
assert oldPackage.uuid is not null, format('oldPackage must not be null for OLD.packageUuid = %s of domain', OLD.packageUuid);
|
||||||
|
|
||||||
SELECT * FROM rbactest.package WHERE uuid = NEW.packageUuid INTO newPackage;
|
SELECT * FROM rbactest.package WHERE uuid = NEW.packageUuid INTO newPackage;
|
||||||
assert newPackage.uuid is not null, format('newPackage must not be null for NEW.packageUuid = %s', NEW.packageUuid);
|
assert newPackage.uuid is not null, format('newPackage must not be null for NEW.packageUuid = %s of domain', NEW.packageUuid);
|
||||||
|
|
||||||
|
|
||||||
if NEW.packageUuid <> OLD.packageUuid then
|
if NEW.packageUuid <> OLD.packageUuid then
|
||||||
|
@ -9,7 +9,7 @@ create table if not exists hs_office.contact
|
|||||||
uuid uuid unique references rbac.object (uuid) initially deferred,
|
uuid uuid unique references rbac.object (uuid) initially deferred,
|
||||||
version int not null default 0,
|
version int not null default 0,
|
||||||
caption varchar(128) not null,
|
caption varchar(128) not null,
|
||||||
postalAddress text,
|
postalAddress jsonb not null,
|
||||||
emailAddresses jsonb not null,
|
emailAddresses jsonb not null,
|
||||||
phoneNumbers jsonb not null
|
phoneNumbers jsonb not null
|
||||||
);
|
);
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
create or replace procedure hs_office.contact_create_test_data(contCaption varchar)
|
create or replace procedure hs_office.contact_create_test_data(contCaption varchar)
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
postalAddr varchar;
|
|
||||||
emailAddr varchar;
|
emailAddr varchar;
|
||||||
begin
|
begin
|
||||||
emailAddr = 'contact-admin@' || base.cleanIdentifier(contCaption) || '.example.com';
|
emailAddr = 'contact-admin@' || base.cleanIdentifier(contCaption) || '.example.com';
|
||||||
@ -19,14 +18,18 @@ begin
|
|||||||
perform rbac.create_subject(emailAddr);
|
perform rbac.create_subject(emailAddr);
|
||||||
call base.defineContext('creating contact test-data', null, emailAddr);
|
call base.defineContext('creating contact test-data', null, emailAddr);
|
||||||
|
|
||||||
postalAddr := E'Vorname Nachname\nStraße Hnr\nPLZ Stadt';
|
|
||||||
|
|
||||||
raise notice 'creating test contact: %', contCaption;
|
raise notice 'creating test contact: %', contCaption;
|
||||||
insert
|
insert
|
||||||
into hs_office.contact (caption, postaladdress, emailaddresses, phonenumbers)
|
into hs_office.contact (caption, postaladdress, emailaddresses, phonenumbers)
|
||||||
values (
|
values (
|
||||||
contCaption,
|
contCaption,
|
||||||
postalAddr,
|
( '{ ' ||
|
||||||
|
-- '"name": "' || contCaption || '",' ||
|
||||||
|
-- '"street": "Somewhere 1",' ||
|
||||||
|
-- '"zipcode": "12345",' ||
|
||||||
|
-- '"city": "Where-Ever",' ||
|
||||||
|
'"country": "Germany"' ||
|
||||||
|
'}')::jsonb,
|
||||||
('{ "main": "' || emailAddr || '" }')::jsonb,
|
('{ "main": "' || emailAddr || '" }')::jsonb,
|
||||||
('{ "phone_office": "+49 123 1234567" }')::jsonb
|
('{ "phone_office": "+49 123 1234567" }')::jsonb
|
||||||
);
|
);
|
||||||
|
@ -12,6 +12,7 @@ CREATE TYPE hs_office.RelationType AS ENUM (
|
|||||||
'DEBITOR',
|
'DEBITOR',
|
||||||
'VIP_CONTACT',
|
'VIP_CONTACT',
|
||||||
'OPERATIONS',
|
'OPERATIONS',
|
||||||
|
'OPERATIONS_ALERT',
|
||||||
'SUBSCRIBER');
|
'SUBSCRIBER');
|
||||||
|
|
||||||
CREATE CAST (character varying as hs_office.RelationType) WITH INOUT AS IMPLICIT;
|
CREATE CAST (character varying as hs_office.RelationType) WITH INOUT AS IMPLICIT;
|
||||||
@ -28,6 +29,9 @@ create table if not exists hs_office.relation
|
|||||||
);
|
);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
-- TODO.impl: unique constraint, to prevent using the same person multiple times as a partner, or better:
|
||||||
|
-- ( anchorUuid, holderUuid, type)
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset michael.hoennig:hs-office-relation-MAIN-TABLE-JOURNAL endDelimiter:--//
|
--changeset michael.hoennig:hs-office-relation-MAIN-TABLE-JOURNAL endDelimiter:--//
|
||||||
|
@ -38,13 +38,13 @@ begin
|
|||||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.person WHERE uuid = NEW.holderUuid INTO newHolderPerson;
|
SELECT * FROM hs_office.person WHERE uuid = NEW.holderUuid INTO newHolderPerson;
|
||||||
assert newHolderPerson.uuid is not null, format('newHolderPerson must not be null for NEW.holderUuid = %s', NEW.holderUuid);
|
assert newHolderPerson.uuid is not null, format('newHolderPerson must not be null for NEW.holderUuid = %s of relation', NEW.holderUuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.person WHERE uuid = NEW.anchorUuid INTO newAnchorPerson;
|
SELECT * FROM hs_office.person WHERE uuid = NEW.anchorUuid INTO newAnchorPerson;
|
||||||
assert newAnchorPerson.uuid is not null, format('newAnchorPerson must not be null for NEW.anchorUuid = %s', NEW.anchorUuid);
|
assert newAnchorPerson.uuid is not null, format('newAnchorPerson must not be null for NEW.anchorUuid = %s of relation', NEW.anchorUuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.contact WHERE uuid = NEW.contactUuid INTO newContact;
|
SELECT * FROM hs_office.contact WHERE uuid = NEW.contactUuid INTO newContact;
|
||||||
assert newContact.uuid is not null, format('newContact must not be null for NEW.contactUuid = %s', NEW.contactUuid);
|
assert newContact.uuid is not null, format('newContact must not be null for NEW.contactUuid = %s of relation', NEW.contactUuid);
|
||||||
|
|
||||||
|
|
||||||
perform rbac.defineRoleWithGrants(
|
perform rbac.defineRoleWithGrants(
|
||||||
|
@ -37,10 +37,10 @@ begin
|
|||||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.relation WHERE uuid = NEW.partnerRelUuid INTO newPartnerRel;
|
SELECT * FROM hs_office.relation WHERE uuid = NEW.partnerRelUuid INTO newPartnerRel;
|
||||||
assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.partnerRelUuid = %s', NEW.partnerRelUuid);
|
assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.partnerRelUuid = %s of partner', NEW.partnerRelUuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.partner_details WHERE uuid = NEW.detailsUuid INTO newPartnerDetails;
|
SELECT * FROM hs_office.partner_details WHERE uuid = NEW.detailsUuid INTO newPartnerDetails;
|
||||||
assert newPartnerDetails.uuid is not null, format('newPartnerDetails must not be null for NEW.detailsUuid = %s', NEW.detailsUuid);
|
assert newPartnerDetails.uuid is not null, format('newPartnerDetails must not be null for NEW.detailsUuid = %s of partner', NEW.detailsUuid);
|
||||||
|
|
||||||
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'DELETE'), hs_office.relation_OWNER(newPartnerRel));
|
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'DELETE'), hs_office.relation_OWNER(newPartnerRel));
|
||||||
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'SELECT'), hs_office.relation_TENANT(newPartnerRel));
|
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'SELECT'), hs_office.relation_TENANT(newPartnerRel));
|
||||||
@ -96,16 +96,16 @@ begin
|
|||||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.relation WHERE uuid = OLD.partnerRelUuid INTO oldPartnerRel;
|
SELECT * FROM hs_office.relation WHERE uuid = OLD.partnerRelUuid INTO oldPartnerRel;
|
||||||
assert oldPartnerRel.uuid is not null, format('oldPartnerRel must not be null for OLD.partnerRelUuid = %s', OLD.partnerRelUuid);
|
assert oldPartnerRel.uuid is not null, format('oldPartnerRel must not be null for OLD.partnerRelUuid = %s of partner', OLD.partnerRelUuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.relation WHERE uuid = NEW.partnerRelUuid INTO newPartnerRel;
|
SELECT * FROM hs_office.relation WHERE uuid = NEW.partnerRelUuid INTO newPartnerRel;
|
||||||
assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.partnerRelUuid = %s', NEW.partnerRelUuid);
|
assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.partnerRelUuid = %s of partner', NEW.partnerRelUuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.partner_details WHERE uuid = OLD.detailsUuid INTO oldPartnerDetails;
|
SELECT * FROM hs_office.partner_details WHERE uuid = OLD.detailsUuid INTO oldPartnerDetails;
|
||||||
assert oldPartnerDetails.uuid is not null, format('oldPartnerDetails must not be null for OLD.detailsUuid = %s', OLD.detailsUuid);
|
assert oldPartnerDetails.uuid is not null, format('oldPartnerDetails must not be null for OLD.detailsUuid = %s of partner', OLD.detailsUuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.partner_details WHERE uuid = NEW.detailsUuid INTO newPartnerDetails;
|
SELECT * FROM hs_office.partner_details WHERE uuid = NEW.detailsUuid INTO newPartnerDetails;
|
||||||
assert newPartnerDetails.uuid is not null, format('newPartnerDetails must not be null for NEW.detailsUuid = %s', NEW.detailsUuid);
|
assert newPartnerDetails.uuid is not null, format('newPartnerDetails must not be null for NEW.detailsUuid = %s of partner', NEW.detailsUuid);
|
||||||
|
|
||||||
|
|
||||||
if NEW.partnerRelUuid <> OLD.partnerRelUuid then
|
if NEW.partnerRelUuid <> OLD.partnerRelUuid then
|
||||||
|
@ -44,10 +44,10 @@ begin
|
|||||||
WHERE partnerRel.type = 'PARTNER'
|
WHERE partnerRel.type = 'PARTNER'
|
||||||
AND NEW.debitorRelUuid = debitorRel.uuid
|
AND NEW.debitorRelUuid = debitorRel.uuid
|
||||||
INTO newPartnerRel;
|
INTO newPartnerRel;
|
||||||
assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.debitorRelUuid = %s', NEW.debitorRelUuid);
|
assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.debitorRelUuid = %s of debitor', NEW.debitorRelUuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.relation WHERE uuid = NEW.debitorRelUuid INTO newDebitorRel;
|
SELECT * FROM hs_office.relation WHERE uuid = NEW.debitorRelUuid INTO newDebitorRel;
|
||||||
assert newDebitorRel.uuid is not null, format('newDebitorRel must not be null for NEW.debitorRelUuid = %s', NEW.debitorRelUuid);
|
assert newDebitorRel.uuid is not null, format('newDebitorRel must not be null for NEW.debitorRelUuid = %s of debitor', NEW.debitorRelUuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.bankaccount WHERE uuid = NEW.refundBankAccountUuid INTO newRefundBankAccount;
|
SELECT * FROM hs_office.bankaccount WHERE uuid = NEW.refundBankAccountUuid INTO newRefundBankAccount;
|
||||||
|
|
||||||
|
@ -37,14 +37,14 @@ begin
|
|||||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.bankaccount WHERE uuid = NEW.bankAccountUuid INTO newBankAccount;
|
SELECT * FROM hs_office.bankaccount WHERE uuid = NEW.bankAccountUuid INTO newBankAccount;
|
||||||
assert newBankAccount.uuid is not null, format('newBankAccount must not be null for NEW.bankAccountUuid = %s', NEW.bankAccountUuid);
|
assert newBankAccount.uuid is not null, format('newBankAccount must not be null for NEW.bankAccountUuid = %s of sepamandate', NEW.bankAccountUuid);
|
||||||
|
|
||||||
SELECT debitorRel.*
|
SELECT debitorRel.*
|
||||||
FROM hs_office.relation debitorRel
|
FROM hs_office.relation debitorRel
|
||||||
JOIN hs_office.debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
|
JOIN hs_office.debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
|
||||||
WHERE debitor.uuid = NEW.debitorUuid
|
WHERE debitor.uuid = NEW.debitorUuid
|
||||||
INTO newDebitorRel;
|
INTO newDebitorRel;
|
||||||
assert newDebitorRel.uuid is not null, format('newDebitorRel must not be null for NEW.debitorUuid = %s', NEW.debitorUuid);
|
assert newDebitorRel.uuid is not null, format('newDebitorRel must not be null for NEW.debitorUuid = %s of sepamandate', NEW.debitorUuid);
|
||||||
|
|
||||||
|
|
||||||
perform rbac.defineRoleWithGrants(
|
perform rbac.defineRoleWithGrants(
|
||||||
|
@ -40,7 +40,7 @@ begin
|
|||||||
JOIN hs_office.relation AS partnerRel ON partnerRel.uuid = partner.partnerRelUuid
|
JOIN hs_office.relation AS partnerRel ON partnerRel.uuid = partner.partnerRelUuid
|
||||||
WHERE partner.uuid = NEW.partnerUuid
|
WHERE partner.uuid = NEW.partnerUuid
|
||||||
INTO newPartnerRel;
|
INTO newPartnerRel;
|
||||||
assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.partnerUuid = %s', NEW.partnerUuid);
|
assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.partnerUuid = %s of membership', NEW.partnerUuid);
|
||||||
|
|
||||||
|
|
||||||
perform rbac.defineRoleWithGrants(
|
perform rbac.defineRoleWithGrants(
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
--changeset michael.hoennig:hs-office-coopshares-MAIN-TABLE endDelimiter:--//
|
--changeset michael.hoennig:hs-office-coopshares-MAIN-TABLE endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
CREATE TYPE hs_office.CoopSharesTransactionType AS ENUM ('ADJUSTMENT', 'SUBSCRIPTION', 'CANCELLATION');
|
CREATE TYPE hs_office.CoopSharesTransactionType AS ENUM ('REVERSAL', 'SUBSCRIPTION', 'CANCELLATION');
|
||||||
|
|
||||||
CREATE CAST (character varying as hs_office.CoopSharesTransactionType) WITH INOUT AS IMPLICIT;
|
CREATE CAST (character varying as hs_office.CoopSharesTransactionType) WITH INOUT AS IMPLICIT;
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ create table if not exists hs_office.coopsharetx
|
|||||||
valueDate date not null,
|
valueDate date not null,
|
||||||
shareCount integer not null,
|
shareCount integer not null,
|
||||||
reference varchar(48) not null,
|
reference varchar(48) not null,
|
||||||
adjustedShareTxUuid uuid unique REFERENCES hs_office.coopsharetx(uuid) DEFERRABLE INITIALLY DEFERRED,
|
revertedShareTxUuid uuid unique REFERENCES hs_office.coopsharetx(uuid) DEFERRABLE INITIALLY DEFERRED,
|
||||||
comment varchar(512)
|
comment varchar(512)
|
||||||
);
|
);
|
||||||
--//
|
--//
|
||||||
@ -28,8 +28,8 @@ create table if not exists hs_office.coopsharetx
|
|||||||
|
|
||||||
alter table hs_office.coopsharetx
|
alter table hs_office.coopsharetx
|
||||||
add constraint reverse_entry_missing
|
add constraint reverse_entry_missing
|
||||||
check ( transactionType = 'ADJUSTMENT' and adjustedShareTxUuid is not null
|
check ( transactionType = 'REVERSAL' and revertedShareTxUuid is not null
|
||||||
or transactionType <> 'ADJUSTMENT' and adjustedShareTxUuid is null);
|
or transactionType <> 'REVERSAL' and revertedShareTxUuid is null);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
@ -36,7 +36,7 @@ begin
|
|||||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.membership WHERE uuid = NEW.membershipUuid INTO newMembership;
|
SELECT * FROM hs_office.membership WHERE uuid = NEW.membershipUuid INTO newMembership;
|
||||||
assert newMembership.uuid is not null, format('newMembership must not be null for NEW.membershipUuid = %s', NEW.membershipUuid);
|
assert newMembership.uuid is not null, format('newMembership must not be null for NEW.membershipUuid = %s of coopshares', NEW.membershipUuid);
|
||||||
|
|
||||||
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'SELECT'), hs_office.membership_AGENT(newMembership));
|
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'SELECT'), hs_office.membership_AGENT(newMembership));
|
||||||
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'UPDATE'), hs_office.membership_ADMIN(newMembership));
|
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'UPDATE'), hs_office.membership_ADMIN(newMembership));
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
--changeset michael.hoennig:hs-office-coopshares-MIGRATION-mapping endDelimiter:--//
|
--changeset michael.hoennig:hs-office-coopshares-MIGRATION-mapping endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
CREATE TABLE hs_office.coopsharestransaction_legacy_id
|
CREATE TABLE hs_office.coopsharetx_legacy_id
|
||||||
(
|
(
|
||||||
uuid uuid NOT NULL REFERENCES hs_office.coopsharetx(uuid),
|
uuid uuid NOT NULL REFERENCES hs_office.coopsharetx(uuid),
|
||||||
member_share_id integer NOT NULL
|
member_share_id integer NOT NULL
|
||||||
@ -19,10 +19,10 @@ CREATE TABLE hs_office.coopsharestransaction_legacy_id
|
|||||||
--changeset michael.hoennig:hs-office-coopshares-MIGRATION-sequence endDelimiter:--//
|
--changeset michael.hoennig:hs-office-coopshares-MIGRATION-sequence endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
CREATE SEQUENCE IF NOT EXISTS hs_office.coopsharestransaction_legacy_id_seq
|
CREATE SEQUENCE IF NOT EXISTS hs_office.coopsharetx_legacy_id_seq
|
||||||
AS integer
|
AS integer
|
||||||
START 1000000000
|
START 1000000000
|
||||||
OWNED BY hs_office.coopsharestransaction_legacy_id.member_share_id;
|
OWNED BY hs_office.coopsharetx_legacy_id.member_share_id;
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
@ -30,9 +30,9 @@ CREATE SEQUENCE IF NOT EXISTS hs_office.coopsharestransaction_legacy_id_seq
|
|||||||
--changeset michael.hoennig:hs-office-coopshares-MIGRATION-default endDelimiter:--//
|
--changeset michael.hoennig:hs-office-coopshares-MIGRATION-default endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
ALTER TABLE hs_office.coopsharestransaction_legacy_id
|
ALTER TABLE hs_office.coopsharetx_legacy_id
|
||||||
ALTER COLUMN member_share_id
|
ALTER COLUMN member_share_id
|
||||||
SET DEFAULT nextVal('hs_office.coopsharestransaction_legacy_id_seq');
|
SET DEFAULT nextVal('hs_office.coopsharetx_legacy_id_seq');
|
||||||
|
|
||||||
--/
|
--/
|
||||||
|
|
||||||
@ -41,8 +41,8 @@ ALTER TABLE hs_office.coopsharestransaction_legacy_id
|
|||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
CALL base.defineContext('schema-migration');
|
CALL base.defineContext('schema-migration');
|
||||||
INSERT INTO hs_office.coopsharestransaction_legacy_id(uuid, member_share_id)
|
INSERT INTO hs_office.coopsharetx_legacy_id(uuid, member_share_id)
|
||||||
SELECT uuid, nextVal('hs_office.coopsharestransaction_legacy_id_seq') FROM hs_office.coopsharetx;
|
SELECT uuid, nextVal('hs_office.coopsharetx_legacy_id_seq') FROM hs_office.coopsharetx;
|
||||||
--/
|
--/
|
||||||
|
|
||||||
|
|
||||||
@ -58,8 +58,8 @@ begin
|
|||||||
raise exception 'invalid usage of trigger';
|
raise exception 'invalid usage of trigger';
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
INSERT INTO hs_office.coopsharestransaction_legacy_id VALUES
|
INSERT INTO hs_office.coopsharetx_legacy_id VALUES
|
||||||
(NEW.uuid, nextVal('hs_office.coopsharestransaction_legacy_id_seq'));
|
(NEW.uuid, nextVal('hs_office.coopsharetx_legacy_id_seq'));
|
||||||
|
|
||||||
return NEW;
|
return NEW;
|
||||||
end; $$;
|
end; $$;
|
||||||
@ -83,7 +83,7 @@ begin
|
|||||||
raise exception 'invalid usage of trigger';
|
raise exception 'invalid usage of trigger';
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
DELETE FROM hs_office.coopsharestransaction_legacy_id
|
DELETE FROM hs_office.coopsharetx_legacy_id
|
||||||
WHERE uuid = OLD.uuid;
|
WHERE uuid = OLD.uuid;
|
||||||
|
|
||||||
return OLD;
|
return OLD;
|
||||||
|
@ -27,12 +27,12 @@ begin
|
|||||||
raise notice 'creating test coopSharesTransaction: %', givenPartnerNumber::text || givenMemberNumberSuffix;
|
raise notice 'creating test coopSharesTransaction: %', givenPartnerNumber::text || givenMemberNumberSuffix;
|
||||||
subscriptionEntryUuid := uuid_generate_v4();
|
subscriptionEntryUuid := uuid_generate_v4();
|
||||||
insert
|
insert
|
||||||
into hs_office.coopsharetx(uuid, membershipuuid, transactiontype, valuedate, sharecount, reference, comment, adjustedShareTxUuid)
|
into hs_office.coopsharetx(uuid, membershipuuid, transactiontype, valuedate, sharecount, reference, comment, revertedShareTxUuid)
|
||||||
values
|
values
|
||||||
(uuid_generate_v4(), membership.uuid, 'SUBSCRIPTION', '2010-03-15', 4, 'ref '||givenPartnerNumber::text || givenMemberNumberSuffix||'-1', 'initial subscription', null),
|
(uuid_generate_v4(), membership.uuid, 'SUBSCRIPTION', '2010-03-15', 4, 'ref '||givenPartnerNumber::text || givenMemberNumberSuffix||'-1', 'initial subscription', null),
|
||||||
(uuid_generate_v4(), membership.uuid, 'CANCELLATION', '2021-09-01', -2, 'ref '||givenPartnerNumber::text || givenMemberNumberSuffix||'-2', 'cancelling some', null),
|
(uuid_generate_v4(), membership.uuid, 'CANCELLATION', '2021-09-01', -2, 'ref '||givenPartnerNumber::text || givenMemberNumberSuffix||'-2', 'cancelling some', null),
|
||||||
(subscriptionEntryUuid, membership.uuid, 'SUBSCRIPTION', '2022-10-20', 2, 'ref '||givenPartnerNumber::text || givenMemberNumberSuffix||'-3', 'some subscription', null),
|
(subscriptionEntryUuid, membership.uuid, 'SUBSCRIPTION', '2022-10-20', 2, 'ref '||givenPartnerNumber::text || givenMemberNumberSuffix||'-3', 'some subscription', null),
|
||||||
(uuid_generate_v4(), membership.uuid, 'ADJUSTMENT', '2022-10-21', -2, 'ref '||givenPartnerNumber::text || givenMemberNumberSuffix||'-4', 'some adjustment', subscriptionEntryUuid);
|
(uuid_generate_v4(), membership.uuid, 'REVERSAL', '2022-10-21', -2, 'ref '||givenPartnerNumber::text || givenMemberNumberSuffix||'-4', 'some reversal', subscriptionEntryUuid);
|
||||||
end; $$;
|
end; $$;
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
--changeset michael.hoennig:hs-office-coopassets-MAIN-TABLE endDelimiter:--//
|
--changeset michael.hoennig:hs-office-coopassets-MAIN-TABLE endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
CREATE TYPE hs_office.CoopAssetsTransactionType AS ENUM ('ADJUSTMENT',
|
CREATE TYPE hs_office.CoopAssetsTransactionType AS ENUM ('REVERSAL',
|
||||||
'DEPOSIT',
|
'DEPOSIT',
|
||||||
'DISBURSAL',
|
'DISBURSAL',
|
||||||
'TRANSFER',
|
'TRANSFER',
|
||||||
@ -22,9 +22,9 @@ create table if not exists hs_office.coopassettx
|
|||||||
membershipUuid uuid not null references hs_office.membership(uuid),
|
membershipUuid uuid not null references hs_office.membership(uuid),
|
||||||
transactionType hs_office.CoopAssetsTransactionType not null,
|
transactionType hs_office.CoopAssetsTransactionType not null,
|
||||||
valueDate date not null,
|
valueDate date not null,
|
||||||
assetValue money not null,
|
assetValue numeric(12,2) not null, -- https://wiki.postgresql.org/wiki/Don't_Do_This#Don.27t_use_money
|
||||||
reference varchar(48) not null,
|
reference varchar(48) not null,
|
||||||
adjustedAssetTxUuid uuid unique REFERENCES hs_office.coopassettx(uuid) DEFERRABLE INITIALLY DEFERRED,
|
revertedAssetTxUuid uuid unique REFERENCES hs_office.coopassettx(uuid) DEFERRABLE INITIALLY DEFERRED,
|
||||||
comment varchar(512)
|
comment varchar(512)
|
||||||
);
|
);
|
||||||
--//
|
--//
|
||||||
@ -36,20 +36,20 @@ create table if not exists hs_office.coopassettx
|
|||||||
|
|
||||||
alter table hs_office.coopassettx
|
alter table hs_office.coopassettx
|
||||||
add constraint reverse_entry_missing
|
add constraint reverse_entry_missing
|
||||||
check ( transactionType = 'ADJUSTMENT' and adjustedAssetTxUuid is not null
|
check ( transactionType = 'REVERSAL' and revertedAssetTxUuid is not null
|
||||||
or transactionType <> 'ADJUSTMENT' and adjustedAssetTxUuid is null);
|
or transactionType <> 'REVERSAL' and revertedAssetTxUuid is null);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset michael.hoennig:hs-office-coopassets-ASSET-VALUE-CONSTRAINT endDelimiter:--//
|
--changeset michael.hoennig:hs-office-coopassets-ASSET-VALUE-CONSTRAINT endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
create or replace function hs_office.coopassetstx_check_positive_total(forMembershipUuid UUID, newAssetValue money)
|
create or replace function hs_office.coopassetstx_check_positive_total(forMembershipUuid UUID, newAssetValue numeric(12, 5))
|
||||||
returns boolean
|
returns boolean
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
currentAssetValue money;
|
currentAssetValue numeric(12,2);
|
||||||
totalAssetValue money;
|
totalAssetValue numeric(12,2);
|
||||||
begin
|
begin
|
||||||
select sum(cat.assetValue)
|
select sum(cat.assetValue)
|
||||||
from hs_office.coopassettx cat
|
from hs_office.coopassettx cat
|
||||||
|
@ -36,7 +36,7 @@ begin
|
|||||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.membership WHERE uuid = NEW.membershipUuid INTO newMembership;
|
SELECT * FROM hs_office.membership WHERE uuid = NEW.membershipUuid INTO newMembership;
|
||||||
assert newMembership.uuid is not null, format('newMembership must not be null for NEW.membershipUuid = %s', NEW.membershipUuid);
|
assert newMembership.uuid is not null, format('newMembership must not be null for NEW.membershipUuid = %s of coopasset', NEW.membershipUuid);
|
||||||
|
|
||||||
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'SELECT'), hs_office.membership_AGENT(newMembership));
|
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'SELECT'), hs_office.membership_AGENT(newMembership));
|
||||||
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'UPDATE'), hs_office.membership_ADMIN(newMembership));
|
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'UPDATE'), hs_office.membership_ADMIN(newMembership));
|
||||||
|
@ -27,12 +27,12 @@ begin
|
|||||||
raise notice 'creating test coopAssetsTransaction: %', givenPartnerNumber || givenMemberNumberSuffix;
|
raise notice 'creating test coopAssetsTransaction: %', givenPartnerNumber || givenMemberNumberSuffix;
|
||||||
lossEntryUuid := uuid_generate_v4();
|
lossEntryUuid := uuid_generate_v4();
|
||||||
insert
|
insert
|
||||||
into hs_office.coopassettx(uuid, membershipuuid, transactiontype, valuedate, assetvalue, reference, comment, adjustedAssetTxUuid)
|
into hs_office.coopassettx(uuid, membershipuuid, transactiontype, valuedate, assetvalue, reference, comment, revertedAssetTxUuid)
|
||||||
values
|
values
|
||||||
(uuid_generate_v4(), membership.uuid, 'DEPOSIT', '2010-03-15', 320.00, 'ref '||givenPartnerNumber || givenMemberNumberSuffix||'-1', 'initial deposit', null),
|
(uuid_generate_v4(), membership.uuid, 'DEPOSIT', '2010-03-15', 320.00, 'ref '||givenPartnerNumber || givenMemberNumberSuffix||'-1', 'initial deposit', null),
|
||||||
(uuid_generate_v4(), membership.uuid, 'DISBURSAL', '2021-09-01', -128.00, 'ref '||givenPartnerNumber || givenMemberNumberSuffix||'-2', 'partial disbursal', null),
|
(uuid_generate_v4(), membership.uuid, 'DISBURSAL', '2021-09-01', -128.00, 'ref '||givenPartnerNumber || givenMemberNumberSuffix||'-2', 'partial disbursal', null),
|
||||||
(lossEntryUuid, membership.uuid, 'DEPOSIT', '2022-10-20', 128.00, 'ref '||givenPartnerNumber || givenMemberNumberSuffix||'-3', 'some loss', null),
|
(lossEntryUuid, membership.uuid, 'DEPOSIT', '2022-10-20', 128.00, 'ref '||givenPartnerNumber || givenMemberNumberSuffix||'-3', 'some loss', null),
|
||||||
(uuid_generate_v4(), membership.uuid, 'ADJUSTMENT', '2022-10-21', -128.00, 'ref '||givenPartnerNumber || givenMemberNumberSuffix||'-3', 'some adjustment', lossEntryUuid);
|
(uuid_generate_v4(), membership.uuid, 'REVERSAL', '2022-10-21', -128.00, 'ref '||givenPartnerNumber || givenMemberNumberSuffix||'-3', 'some reversal', lossEntryUuid);
|
||||||
end; $$;
|
end; $$;
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
@ -37,14 +37,14 @@ begin
|
|||||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.debitor WHERE uuid = NEW.debitorUuid INTO newDebitor;
|
SELECT * FROM hs_office.debitor WHERE uuid = NEW.debitorUuid INTO newDebitor;
|
||||||
assert newDebitor.uuid is not null, format('newDebitor must not be null for NEW.debitorUuid = %s', NEW.debitorUuid);
|
assert newDebitor.uuid is not null, format('newDebitor must not be null for NEW.debitorUuid = %s of project', NEW.debitorUuid);
|
||||||
|
|
||||||
SELECT debitorRel.*
|
SELECT debitorRel.*
|
||||||
FROM hs_office.relation debitorRel
|
FROM hs_office.relation debitorRel
|
||||||
JOIN hs_office.debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
|
JOIN hs_office.debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
|
||||||
WHERE debitor.uuid = NEW.debitorUuid
|
WHERE debitor.uuid = NEW.debitorUuid
|
||||||
INTO newDebitorRel;
|
INTO newDebitorRel;
|
||||||
assert newDebitorRel.uuid is not null, format('newDebitorRel must not be null for NEW.debitorUuid = %s', NEW.debitorUuid);
|
assert newDebitorRel.uuid is not null, format('newDebitorRel must not be null for NEW.debitorUuid = %s or project', NEW.debitorUuid);
|
||||||
|
|
||||||
|
|
||||||
perform rbac.defineRoleWithGrants(
|
perform rbac.defineRoleWithGrants(
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
--liquibase formatted sql
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset timotheus.pokorra:hs-integration-SCHEMA endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
CREATE SCHEMA hs_integration;
|
||||||
|
--//
|
@ -0,0 +1,18 @@
|
|||||||
|
--liquibase formatted sql
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset timotheus.pokorra:hs-global-integration-kimai endDelimiter:--//
|
||||||
|
-- TODO.impl: also select column debitorNumber and do not filter anymore for '00'
|
||||||
|
CREATE OR REPLACE VIEW hs_integration.time_customer AS
|
||||||
|
SELECT p.partnernumber, debitor.defaultprefix
|
||||||
|
FROM hs_office.partner p
|
||||||
|
JOIN hs_office.relation AS pRel
|
||||||
|
ON pRel.type = 'PARTNER'
|
||||||
|
AND pRel.uuid = p.partnerRelUuid
|
||||||
|
JOIN hs_office.relation AS dRel
|
||||||
|
ON dRel.type = 'DEBITOR'
|
||||||
|
AND dRel.anchorUuid = pRel.holderUuid
|
||||||
|
JOIN hs_office.debitor AS debitor
|
||||||
|
ON debitor.debitorreluuid = dRel.uuid
|
||||||
|
AND debitor.debitornumbersuffix = '00';
|
||||||
|
--//
|
@ -0,0 +1,102 @@
|
|||||||
|
|
||||||
|
--liquibase formatted sql
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset timotheus.pokorra:hs-global-integration-znuny endDelimiter:--//
|
||||||
|
-- TODO.impl: also select column debitorNumber and do not filter anymore for '00'
|
||||||
|
CREATE OR REPLACE VIEW hs_integration.contact AS
|
||||||
|
SELECT DISTINCT ON (uuid)
|
||||||
|
partner.partnernumber as partnernumber,
|
||||||
|
debitor.defaultprefix as defaultprefix,
|
||||||
|
c.uuid as uuid,
|
||||||
|
(CASE WHEN per.salutation <> '' THEN per.salutation ELSE NULL END) as salutation,
|
||||||
|
(CASE WHEN per.givenname <> '' THEN per.givenname ELSE NULL END) as givenname,
|
||||||
|
(CASE WHEN per.familyname <> '' THEN per.familyname ELSE NULL END) as familyname,
|
||||||
|
(CASE WHEN per.title <> '' THEN per.title ELSE NULL END) as title,
|
||||||
|
(CASE WHEN per.tradename <> '' THEN per.tradename ELSE NULL END) as tradename,
|
||||||
|
(CASE WHEN c.postaladdress->>'co' <> '' THEN c.postaladdress->>'co' ELSE NULL END) as co,
|
||||||
|
c.postaladdress->>'street' as street,
|
||||||
|
c.postaladdress->>'zipcode' as zipcode,
|
||||||
|
c.postaladdress->>'city' as city,
|
||||||
|
c.postaladdress->>'country' as country,
|
||||||
|
c.phonenumbers->>'phone_private' as phone_private,
|
||||||
|
c.phonenumbers->>'phone_office' as phone_office,
|
||||||
|
c.phonenumbers->>'phone_mobile' as phone_mobile,
|
||||||
|
c.phonenumbers->>'fax' as fax,
|
||||||
|
c.emailaddresses->>'main' as email
|
||||||
|
FROM hs_office.partner AS partner
|
||||||
|
JOIN hs_office.partner_legacy_id AS partner_lid ON partner_lid.uuid = partner.uuid
|
||||||
|
JOIN hs_office.relation AS pRel
|
||||||
|
ON pRel.type = 'PARTNER'
|
||||||
|
AND pRel.uuid = partner.partnerRelUuid
|
||||||
|
JOIN hs_office.relation AS dRel
|
||||||
|
ON dRel.type = 'DEBITOR'
|
||||||
|
AND dRel.anchorUuid = pRel.holderUuid
|
||||||
|
JOIN hs_office.debitor AS debitor
|
||||||
|
ON debitor.debitorreluuid = dRel.uuid
|
||||||
|
AND debitor.debitornumbersuffix = '00'
|
||||||
|
JOIN hs_office.contact AS c ON c.uuid = pRel.contactuuid
|
||||||
|
JOIN hs_office.person AS per ON per.uuid = pRel.holderuuid
|
||||||
|
UNION
|
||||||
|
SELECT DISTINCT ON (uuid)
|
||||||
|
partner.partnernumber as partnernumber,
|
||||||
|
debitor.defaultprefix as defaultprefix,
|
||||||
|
c.uuid as uuid,
|
||||||
|
(CASE WHEN per.salutation <> '' THEN per.salutation ELSE NULL END) as salutation,
|
||||||
|
(CASE WHEN per.givenname <> '' THEN per.givenname ELSE NULL END) as givenname,
|
||||||
|
(CASE WHEN per.familyname <> '' THEN per.familyname ELSE NULL END) as familyname,
|
||||||
|
(CASE WHEN per.title <> '' THEN per.title ELSE NULL END) as title,
|
||||||
|
(CASE WHEN per.tradename <> '' THEN per.tradename ELSE NULL END) as tradename,
|
||||||
|
(CASE WHEN c.postaladdress->>'co' <> '' THEN c.postaladdress->>'co' ELSE NULL END) as co,
|
||||||
|
c.postaladdress->>'street' as street,
|
||||||
|
c.postaladdress->>'zipcode' as zipcode,
|
||||||
|
c.postaladdress->>'city' as city,
|
||||||
|
c.postaladdress->>'country' as country,
|
||||||
|
c.phonenumbers->>'phone_private' as phone_private,
|
||||||
|
c.phonenumbers->>'phone_office' as phone_office,
|
||||||
|
c.phonenumbers->>'phone_mobile' as phone_mobile,
|
||||||
|
c.phonenumbers->>'fax' as fax,
|
||||||
|
c.emailaddresses->>'main' as email
|
||||||
|
FROM hs_office.partner AS partner
|
||||||
|
JOIN hs_office.relation AS pRel
|
||||||
|
ON pRel.type = 'PARTNER'
|
||||||
|
AND pRel.uuid = partner.partnerRelUuid
|
||||||
|
JOIN hs_office.relation AS dRel
|
||||||
|
ON dRel.type = 'DEBITOR'
|
||||||
|
AND dRel.anchorUuid = pRel.holderUuid
|
||||||
|
JOIN hs_office.debitor AS debitor
|
||||||
|
ON debitor.debitorreluuid = dRel.uuid
|
||||||
|
AND debitor.debitornumbersuffix = '00'
|
||||||
|
JOIN hs_office.relation AS rs1 ON rs1.uuid = partner.partnerreluuid AND rs1.type = 'PARTNER'
|
||||||
|
JOIN hs_office.relation AS relation ON relation.anchoruuid = rs1.holderuuid
|
||||||
|
JOIN hs_office.contact AS c ON c.uuid = relation.contactuuid
|
||||||
|
JOIN hs_office.person AS per ON per.uuid = relation.holderuuid;
|
||||||
|
|
||||||
|
CREATE OR REPLACE VIEW hs_integration.ticket_customer_user AS
|
||||||
|
SELECT c.uuid,
|
||||||
|
max(c.partnernumber)::text as number,
|
||||||
|
max(c.defaultprefix) as code,
|
||||||
|
max(c.email) as login,
|
||||||
|
max(c.salutation) as salut,
|
||||||
|
max(c.givenname) as firstname,
|
||||||
|
max(c.familyname) as lastname,
|
||||||
|
max(c.title) as title,
|
||||||
|
max(c.tradename) as firma,
|
||||||
|
max(c.co) as co,
|
||||||
|
max(c.street) as street,
|
||||||
|
max(c.zipcode) as zipcode,
|
||||||
|
max(c.city) as city,
|
||||||
|
max(c.country) as country,
|
||||||
|
max(concat_ws(', '::text, c.phone_office, c.phone_private)) AS phone,
|
||||||
|
max(c.phone_private) as phone_private,
|
||||||
|
max(c.phone_office) as phone_office,
|
||||||
|
max(c.phone_mobile) as mobile,
|
||||||
|
max(c.fax) as fax,
|
||||||
|
max(c.email) as email,
|
||||||
|
string_agg(CASE WHEN relation.mark IS NULL THEN relation.type::text ELSE CONCAT(relation.type::text, ':', relation.mark::text) END, '/'::text) AS comment,
|
||||||
|
1 AS valid
|
||||||
|
FROM hs_integration.contact AS c
|
||||||
|
JOIN hs_office.relation AS relation ON c.uuid = relation.contactuuid
|
||||||
|
WHERE (c.defaultprefix != 'hsh' OR (c.partnernumber = 10000 AND c.email = 'hostmaster@hostsharing.net'))
|
||||||
|
GROUP BY c.uuid;
|
||||||
|
--//
|
@ -171,3 +171,9 @@ databaseChangeLog:
|
|||||||
file: db/changelog/7-hs-hosting/701-hosting-asset/7018-hs-hosting-asset-test-data.sql
|
file: db/changelog/7-hs-hosting/701-hosting-asset/7018-hs-hosting-asset-test-data.sql
|
||||||
- include:
|
- include:
|
||||||
file: db/changelog/9-hs-global/9000-statistics.sql
|
file: db/changelog/9-hs-global/9000-statistics.sql
|
||||||
|
- include:
|
||||||
|
file: db/changelog/9-hs-global/9100-hs-integration-schema.sql
|
||||||
|
- include:
|
||||||
|
file: db/changelog/9-hs-global/9110-integration-kimai.sql
|
||||||
|
- include:
|
||||||
|
file: db/changelog/9-hs-global/9120-integration-znuny.sql
|
@ -46,6 +46,7 @@ public class ArchitectureTest {
|
|||||||
"..lambda",
|
"..lambda",
|
||||||
"..generated..",
|
"..generated..",
|
||||||
"..persistence..",
|
"..persistence..",
|
||||||
|
"..reflection",
|
||||||
"..system..",
|
"..system..",
|
||||||
"..validation..",
|
"..validation..",
|
||||||
"..hs.office.bankaccount",
|
"..hs.office.bankaccount",
|
||||||
@ -54,6 +55,7 @@ public class ArchitectureTest {
|
|||||||
"..hs.office.coopshares",
|
"..hs.office.coopshares",
|
||||||
"..hs.office.debitor",
|
"..hs.office.debitor",
|
||||||
"..hs.office.membership",
|
"..hs.office.membership",
|
||||||
|
"..hs.office.scenarios..",
|
||||||
"..hs.migration",
|
"..hs.migration",
|
||||||
"..hs.office.partner",
|
"..hs.office.partner",
|
||||||
"..hs.office.person",
|
"..hs.office.person",
|
||||||
@ -75,7 +77,7 @@ public class ArchitectureTest {
|
|||||||
"..rbac.grant",
|
"..rbac.grant",
|
||||||
"..rbac.role",
|
"..rbac.role",
|
||||||
"..rbac.object",
|
"..rbac.object",
|
||||||
"..stringify"
|
"..repr"
|
||||||
// ATTENTION: Don't simply add packages here, also add arch rules for the new package!
|
// ATTENTION: Don't simply add packages here, also add arch rules for the new package!
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -96,7 +98,7 @@ public class ArchitectureTest {
|
|||||||
public static final ArchRule testClassesAreProperlyNamed = classes()
|
public static final ArchRule testClassesAreProperlyNamed = classes()
|
||||||
.that().haveSimpleNameEndingWith("Test")
|
.that().haveSimpleNameEndingWith("Test")
|
||||||
.and().doNotHaveModifier(ABSTRACT)
|
.and().doNotHaveModifier(ABSTRACT)
|
||||||
.should().haveNameMatching(".*(UnitTest|RestTest|IntegrationTest|AcceptanceTest|ArchitectureTest)$");
|
.should().haveNameMatching(".*(UnitTest|RestTest|IntegrationTest|AcceptanceTest|ScenarioTest|ArchitectureTest)$");
|
||||||
|
|
||||||
@ArchTest
|
@ArchTest
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
@ -150,7 +150,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"projectUuid": "{projectUuid}",
|
"project.uuid": "{projectUuid}",
|
||||||
"type": "MANAGED_SERVER",
|
"type": "MANAGED_SERVER",
|
||||||
"caption": "some new booking",
|
"caption": "some new booking",
|
||||||
"validTo": "{validTo}",
|
"validTo": "{validTo}",
|
||||||
@ -200,8 +200,8 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"projectUuid": "{projectUuid}",
|
"project.uuid": "{projectUuid}",
|
||||||
"parentItemUuid": "{managedServerUuid}",
|
"parentItem.uuid": "{managedServerUuid}",
|
||||||
"type": "MANAGED_WEBSPACE",
|
"type": "MANAGED_WEBSPACE",
|
||||||
"caption": "some managed webspace",
|
"caption": "some managed webspace",
|
||||||
"resources": {
|
"resources": {
|
||||||
@ -270,7 +270,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"projectUuid": "{projectUuid}",
|
"project.uuid": "{projectUuid}",
|
||||||
"type": "DOMAIN_SETUP",
|
"type": "DOMAIN_SETUP",
|
||||||
"caption": "Domain-Setup for example.org",
|
"caption": "Domain-Setup for example.org",
|
||||||
"resources": {
|
"resources": {
|
||||||
@ -285,7 +285,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "DOMAIN_HTTP_SETUP",
|
"type": "DOMAIN_HTTP_SETUP",
|
||||||
"assignedToAssetUuid": "{unixUserUuid}"
|
"assignedToAsset.uuid": "{unixUserUuid}"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "DOMAIN_MBOX_SETUP"
|
"type": "DOMAIN_MBOX_SETUP"
|
||||||
@ -360,7 +360,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"projectUuid": "{projectUuid}",
|
"project.uuid": "{projectUuid}",
|
||||||
"type": "DOMAIN_SETUP",
|
"type": "DOMAIN_SETUP",
|
||||||
"caption": "some new domain-setup booking",
|
"caption": "some new domain-setup booking",
|
||||||
"resources": {
|
"resources": {
|
||||||
@ -375,7 +375,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "DOMAIN_HTTP_SETUP",
|
"type": "DOMAIN_HTTP_SETUP",
|
||||||
"assignedToAssetUuid": "{unixUserUuid}"
|
"assignedToAsset.uuid": "{unixUserUuid}"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "DOMAIN_MBOX_SETUP"
|
"type": "DOMAIN_MBOX_SETUP"
|
||||||
|
@ -105,7 +105,7 @@ class HsBookingItemControllerRestTest {
|
|||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content("""
|
.content("""
|
||||||
{
|
{
|
||||||
"projectUuid": "{projectUuid}",
|
"project.uuid": "{projectUuid}",
|
||||||
"type": "MANAGED_SERVER",
|
"type": "MANAGED_SERVER",
|
||||||
"caption": "some new booking",
|
"caption": "some new booking",
|
||||||
"validTo": "{validTo}",
|
"validTo": "{validTo}",
|
||||||
@ -155,7 +155,7 @@ class HsBookingItemControllerRestTest {
|
|||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content("""
|
.content("""
|
||||||
{
|
{
|
||||||
"projectUuid": "{projectUuid}",
|
"project.uuid": "{projectUuid}",
|
||||||
"type": "MANAGED_SERVER",
|
"type": "MANAGED_SERVER",
|
||||||
"caption": "some new booking",
|
"caption": "some new booking",
|
||||||
"validFrom": "{validFrom}",
|
"validFrom": "{validFrom}",
|
||||||
|
@ -92,7 +92,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"debitorUuid": "%s",
|
"debitor.uuid": "%s",
|
||||||
"caption": "some new project"
|
"caption": "some new project"
|
||||||
}
|
}
|
||||||
""".formatted(givenDebitor.getUuid()))
|
""".formatted(givenDebitor.getUuid()))
|
||||||
|
@ -165,10 +165,10 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"bookingItemUuid": "%s",
|
"bookingItem.uuid": "%s",
|
||||||
"type": "MANAGED_WEBSPACE",
|
"type": "MANAGED_WEBSPACE",
|
||||||
"identifier": "fir10",
|
"identifier": "fir10",
|
||||||
"parentAssetUuid": "%s",
|
"parentAsset.uuid": "%s",
|
||||||
"caption": "some separate ManagedWebspace HA",
|
"caption": "some separate ManagedWebspace HA",
|
||||||
"config": {}
|
"config": {}
|
||||||
}
|
}
|
||||||
@ -227,7 +227,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"parentAssetUuid": "%s",
|
"parentAsset.uuid": "%s",
|
||||||
"type": "UNIX_USER",
|
"type": "UNIX_USER",
|
||||||
"identifier": "fir01-temp",
|
"identifier": "fir01-temp",
|
||||||
"caption": "some new UnixUser in client's ManagedWebspace",
|
"caption": "some new UnixUser in client's ManagedWebspace",
|
||||||
@ -280,7 +280,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"bookingItemUuid": "%s",
|
"bookingItem.uuid": "%s",
|
||||||
"type": "DOMAIN_SETUP",
|
"type": "DOMAIN_SETUP",
|
||||||
"identifier": "example.com",
|
"identifier": "example.com",
|
||||||
"caption": "some unrelated domain-setup",
|
"caption": "some unrelated domain-setup",
|
||||||
@ -326,7 +326,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"bookingItemUuid": "%s",
|
"bookingItem.uuid": "%s",
|
||||||
"type": "MANAGED_SERVER",
|
"type": "MANAGED_SERVER",
|
||||||
"identifier": "vm1400",
|
"identifier": "vm1400",
|
||||||
"caption": "some new ManagedServer",
|
"caption": "some new ManagedServer",
|
||||||
@ -381,7 +381,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"parentAssetUuid": "%s",
|
"parentAsset.uuid": "%s",
|
||||||
"type": "UNIX_USER",
|
"type": "UNIX_USER",
|
||||||
"identifier": "fir01-extra",
|
"identifier": "fir01-extra",
|
||||||
"caption": "some extra UnixUser",
|
"caption": "some extra UnixUser",
|
||||||
@ -508,7 +508,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"alarmContactUuid": "%s",
|
"alarmContact.uuid": "%s",
|
||||||
"config": {
|
"config": {
|
||||||
"monit_max_ssd_usage": 85,
|
"monit_max_ssd_usage": 85,
|
||||||
"monit_max_hdd_usage": null,
|
"monit_max_hdd_usage": null,
|
||||||
|
@ -110,7 +110,6 @@ public class HsHostingAssetControllerRestTest {
|
|||||||
"caption": "some fake cloud-server",
|
"caption": "some fake cloud-server",
|
||||||
"alarmContact": {
|
"alarmContact": {
|
||||||
"caption": "some contact",
|
"caption": "some contact",
|
||||||
"postalAddress": "address of some contact",
|
|
||||||
"emailAddresses": {
|
"emailAddresses": {
|
||||||
"main": "some-contact@example.com"
|
"main": "some-contact@example.com"
|
||||||
}
|
}
|
||||||
@ -141,7 +140,6 @@ public class HsHostingAssetControllerRestTest {
|
|||||||
"caption": "some fake managed-server",
|
"caption": "some fake managed-server",
|
||||||
"alarmContact": {
|
"alarmContact": {
|
||||||
"caption": "some contact",
|
"caption": "some contact",
|
||||||
"postalAddress": "address of some contact",
|
|
||||||
"emailAddresses": {
|
"emailAddresses": {
|
||||||
"main": "some-contact@example.com"
|
"main": "some-contact@example.com"
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ class DomainSetupHostingAssetFactoryUnitTest {
|
|||||||
"subHostingAssets": [
|
"subHostingAssets": [
|
||||||
{
|
{
|
||||||
"type": "DOMAIN_HTTP_SETUP",
|
"type": "DOMAIN_HTTP_SETUP",
|
||||||
"assignedToAssetUuid": "{unixUserHostingAssetUuid}"
|
"assignedToAsset.uuid": "{unixUserHostingAssetUuid}"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "DOMAIN_DNS_SETUP"
|
"type": "DOMAIN_DNS_SETUP"
|
||||||
@ -124,7 +124,7 @@ class DomainSetupHostingAssetFactoryUnitTest {
|
|||||||
"subHostingAssets": [
|
"subHostingAssets": [
|
||||||
{
|
{
|
||||||
"type": "DOMAIN_HTTP_SETUP",
|
"type": "DOMAIN_HTTP_SETUP",
|
||||||
"assignedToAssetUuid": "{unixUserHostingAssetUuid}"
|
"assignedToAsset.uuid": "{unixUserHostingAssetUuid}"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "DOMAIN_DNS_SETUP"
|
"type": "DOMAIN_DNS_SETUP"
|
||||||
@ -164,7 +164,7 @@ class DomainSetupHostingAssetFactoryUnitTest {
|
|||||||
"subHostingAssets": [
|
"subHostingAssets": [
|
||||||
{
|
{
|
||||||
"type": "DOMAIN_HTTP_SETUP",
|
"type": "DOMAIN_HTTP_SETUP",
|
||||||
"assignedToAssetUuid": "{unixUserHostingAssetUuid}"
|
"assignedToAsset.uuid": "{unixUserHostingAssetUuid}"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "DOMAIN_DNS_SETUP"
|
"type": "DOMAIN_DNS_SETUP"
|
||||||
@ -206,7 +206,7 @@ class DomainSetupHostingAssetFactoryUnitTest {
|
|||||||
"subHostingAssets": [
|
"subHostingAssets": [
|
||||||
{
|
{
|
||||||
"type": "DOMAIN_HTTP_SETUP",
|
"type": "DOMAIN_HTTP_SETUP",
|
||||||
"assignedToAssetUuid": "{unixUserHostingAssetUuid}"
|
"assignedToAsset.uuid": "{unixUserHostingAssetUuid}"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "DOMAIN_DNS_SETUP"
|
"type": "DOMAIN_DNS_SETUP"
|
||||||
|
@ -54,7 +54,7 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
|
|||||||
"subscriber:customers-announce"
|
"subscriber:customers-announce"
|
||||||
};
|
};
|
||||||
private static final String[] KNOWN_ROLES = ArrayUtils.addAll(
|
private static final String[] KNOWN_ROLES = ArrayUtils.addAll(
|
||||||
new String[] { "partner", "vip-contact", "ex-partner", "billing", "contractual", "operation" },
|
new String[] { "partner", "vip-contact", "ex-partner", "billing", "contractual", "operation", "silent" },
|
||||||
SUBSCRIBER_ROLES);
|
SUBSCRIBER_ROLES);
|
||||||
|
|
||||||
// at least as the number of lines in business_partners.csv from test-data, but less than real data partner count
|
// at least as the number of lines in business_partners.csv from test-data, but less than real data partner count
|
||||||
@ -65,18 +65,21 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
|
|||||||
static int relationId = INITIAL_RELATION_ID;
|
static int relationId = INITIAL_RELATION_ID;
|
||||||
|
|
||||||
private static final List<Integer> IGNORE_BUSINESS_PARTNERS = Arrays.asList(
|
private static final List<Integer> IGNORE_BUSINESS_PARTNERS = Arrays.asList(
|
||||||
512167, // 11139, partner without contractual contact
|
|
||||||
512170, // 11142, partner without contractual contact
|
|
||||||
511725, // 10764, partner without contractual contact
|
|
||||||
// 512171, // 11143, partner without partner contact -- exception
|
|
||||||
-1
|
-1
|
||||||
);
|
);
|
||||||
|
|
||||||
private static final List<Integer> IGNORE_CONTACTS = Arrays.asList(
|
private static final List<Integer> IGNORE_CONTACTS = Arrays.asList(
|
||||||
90547, // Kontakt hat keine Rolle
|
|
||||||
-1
|
-1
|
||||||
);
|
);
|
||||||
|
|
||||||
|
private static final Map<Integer, HsOfficePersonType> PERSON_TYPES_BY_CONTACT = Map.of(
|
||||||
|
90072, HsOfficePersonType.NATURAL_PERSON,
|
||||||
|
90641, HsOfficePersonType.LEGAL_PERSON,
|
||||||
|
90368, HsOfficePersonType.LEGAL_PERSON,
|
||||||
|
90564, HsOfficePersonType.NATURAL_PERSON,
|
||||||
|
-1, HsOfficePersonType.LEGAL_PERSON
|
||||||
|
);
|
||||||
|
|
||||||
static Map<Integer, HsOfficeContactRealEntity> contacts = new WriteOnceMap<>();
|
static Map<Integer, HsOfficeContactRealEntity> contacts = new WriteOnceMap<>();
|
||||||
static Map<Integer, HsOfficePersonEntity> persons = new WriteOnceMap<>();
|
static Map<Integer, HsOfficePersonEntity> persons = new WriteOnceMap<>();
|
||||||
static Map<Integer, HsOfficePartnerEntity> partners = new WriteOnceMap<>();
|
static Map<Integer, HsOfficePartnerEntity> partners = new WriteOnceMap<>();
|
||||||
@ -192,56 +195,56 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
|
|||||||
|
|
||||||
assertThat(toJsonFormattedString(partners)).isEqualToIgnoringWhitespace("""
|
assertThat(toJsonFormattedString(partners)).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
100=partner(P-10003: ?? Michael Mellis, Herr Michael Mellis , Michael Mellis),
|
100=partner(P-10003: ?? Michael Mellis, Herr Michael Mellis, Michael Mellis),
|
||||||
120=partner(P-10020: LP JM GmbH, Herr Philip Meyer-Contract , JM GmbH),
|
120=partner(P-10020: LP JM GmbH, Herr Philip Meyer-Contract, JM GmbH),
|
||||||
122=partner(P-11022: ?? Test PS, Petra Schmidt , Test PS),
|
122=partner(P-11022: ?? Test PS, Petra Schmidt, Test PS),
|
||||||
132=partner(P-10152: ?? Ragnar IT-Beratung, Herr Ragnar Richter , Ragnar IT-Beratung),
|
132=partner(P-10152: ?? Ragnar IT-Beratung, Herr Ragnar Richter, Ragnar IT-Beratung),
|
||||||
190=partner(P-19090: NP Camus, Cecilia, Frau Cecilia Camus ),
|
190=partner(P-19090: NP Camus, Cecilia, Frau Cecilia Camus),
|
||||||
199=partner(P-19999: null null, null),
|
199=partner(P-19999: null null, null),
|
||||||
213=partner(P-10000: LP Hostsharing e.G., Firma Hostmaster Hostsharing , Hostsharing e.G.),
|
213=partner(P-10000: LP Hostsharing e.G., Firma Hostmaster Hostsharing, Hostsharing e.G.),
|
||||||
541=partner(P-11018: ?? Wasserwerk Südholstein, Frau Christiane Milberg , Wasserwerk Südholstein),
|
541=partner(P-11018: ?? Wasserwerk Südholstein, Frau Christiane Milberg, Wasserwerk Südholstein),
|
||||||
542=partner(P-11019: ?? Das Perfekte Haus, Herr Richard Wiese , Das Perfekte Haus)
|
542=partner(P-11019: ?? Das Perfekte Haus, Herr Richard Wiese, Das Perfekte Haus)
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
assertThat(toJsonFormattedString(contacts)).isEqualToIgnoringWhitespace("""
|
assertThat(toJsonFormattedString(contacts)).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
100=contact(caption='Herr Michael Mellis , Michael Mellis', emailAddresses='{ "main": "michael@Mellis.example.org"}'),
|
100=contact(caption='Herr Michael Mellis, Michael Mellis', emailAddresses='{ "main": "michael@Mellis.example.org"}'),
|
||||||
1200=contact(caption='JM e.K.', emailAddresses='{ "main": "jm-ex-partner@example.org"}'),
|
1200=contact(caption='JM e.K.', emailAddresses='{ "main": "jm-ex-partner@example.org"}'),
|
||||||
1201=contact(caption='Frau Dr. Jenny Meyer-Billing , JM GmbH', emailAddresses='{ "main": "jm-billing@example.org"}'),
|
1201=contact(caption='Frau Dr. Jenny Meyer-Billing, JM GmbH', emailAddresses='{ "main": "jm-billing@example.org"}'),
|
||||||
1202=contact(caption='Herr Andrew Meyer-Operation , JM GmbH', emailAddresses='{ "main": "am-operation@example.org"}'),
|
1202=contact(caption='Herr Andrew Meyer-Operation, JM GmbH', emailAddresses='{ "main": "am-operation@example.org"}'),
|
||||||
1203=contact(caption='Herr Philip Meyer-Contract , JM GmbH', emailAddresses='{ "main": "pm-partner@example.org"}'),
|
1203=contact(caption='Herr Philip Meyer-Contract, JM GmbH', emailAddresses='{ "main": "pm-partner@example.org"}'),
|
||||||
1204=contact(caption='Frau Tammy Meyer-VIP , JM GmbH', emailAddresses='{ "main": "tm-vip@example.org"}'),
|
1204=contact(caption='Frau Tammy Meyer-VIP, JM GmbH', emailAddresses='{ "main": "tm-vip@example.org"}'),
|
||||||
1301=contact(caption='Petra Schmidt , Test PS', emailAddresses='{ "main": "ps@example.com"}'),
|
1301=contact(caption='Petra Schmidt, Test PS', emailAddresses='{ "main": "ps@example.com"}'),
|
||||||
132=contact(caption='Herr Ragnar Richter , Ragnar IT-Beratung', emailAddresses='{ "main": "hostsharing@ragnar-richter.de"}'),
|
132=contact(caption='Herr Ragnar Richter, Ragnar IT-Beratung', emailAddresses='{ "main": "hostsharing@ragnar-richter.de"}'),
|
||||||
1401=contact(caption='Frau Frauke Fanninga ', emailAddresses='{ "main": "ff@example.org"}'),
|
1401=contact(caption='Frau Frauke Fanninga', emailAddresses='{ "main": "ff@example.org"}'),
|
||||||
1501=contact(caption='Frau Cecilia Camus ', emailAddresses='{ "main": "cc@example.org"}'),
|
1501=contact(caption='Frau Cecilia Camus', emailAddresses='{ "main": "cc@example.org"}'),
|
||||||
212=contact(caption='Firma Hostmaster Hostsharing , Hostsharing e.G.', emailAddresses='{ "main": "hostmaster@hostsharing.net"}'),
|
212=contact(caption='Firma Hostmaster Hostsharing, Hostsharing e.G.', emailAddresses='{ "main": "hostmaster@hostsharing.net"}'),
|
||||||
90436=contact(caption='Frau Christiane Milberg , Wasserwerk Südholstein', emailAddresses='{ "main": "rechnung@ww-sholst.example.org"}'),
|
90436=contact(caption='Frau Christiane Milberg, Wasserwerk Südholstein', emailAddresses='{ "main": "rechnung@ww-sholst.example.org"}'),
|
||||||
90437=contact(caption='Herr Richard Wiese , Das Perfekte Haus', emailAddresses='{ "main": "admin@das-perfekte-haus.example.org"}'),
|
90437=contact(caption='Herr Richard Wiese, Das Perfekte Haus', emailAddresses='{ "main": "admin@das-perfekte-haus.example.org"}'),
|
||||||
90438=contact(caption='Herr Karim Metzger , Wasswerwerk Südholstein', emailAddresses='{ "main": "karim.metzger@ww-sholst.example.org"}'),
|
90438=contact(caption='Herr Karim Metzger, Wasswerwerk Südholstein', emailAddresses='{ "main": "karim.metzger@ww-sholst.example.org"}'),
|
||||||
90590=contact(caption='Herr Inhaber R. Wiese , Das Perfekte Haus', emailAddresses='{ "main": "515217@kkemail.example.org"}'),
|
90590=contact(caption='Herr Inhaber R. Wiese, Das Perfekte Haus', emailAddresses='{ "main": "515217@kkemail.example.org"}'),
|
||||||
90629=contact(caption='Ragnar Richter ', emailAddresses='{ "main": "mail@ragnar-richter..example.org"}'),
|
90629=contact(caption='Ragnar Richter', emailAddresses='{ "main": "mail@ragnar-richter..example.org"}'),
|
||||||
90677=contact(caption='Eike Henning ', emailAddresses='{ "main": "hostsharing@eike-henning..example.org"}'),
|
90677=contact(caption='Eike Henning', emailAddresses='{ "main": "hostsharing@eike-henning..example.org"}'),
|
||||||
90698=contact(caption='Jan Henning ', emailAddresses='{ "main": "mail@jan-henning.example.org"}')
|
90698=contact(caption='Jan Henning', emailAddresses='{ "main": "mail@jan-henning.example.org"}')
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
assertThat(toJsonFormattedString(persons)).isEqualToIgnoringWhitespace("""
|
assertThat(toJsonFormattedString(persons)).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
100=person(personType='??', tradeName='Michael Mellis', familyName='Mellis', givenName='Michael'),
|
100=person(personType='??', tradeName='Michael Mellis', salutation='Herr', familyName='Mellis', givenName='Michael'),
|
||||||
1200=person(personType='LP', tradeName='JM e.K.'),
|
1200=person(personType='LP', tradeName='JM e.K.'),
|
||||||
1201=person(personType='LP', tradeName='JM GmbH', familyName='Meyer-Billing', givenName='Jenny'),
|
1201=person(personType='LP', tradeName='JM GmbH', salutation='Frau', title='Dr.', familyName='Meyer-Billing', givenName='Jenny'),
|
||||||
1202=person(personType='LP', tradeName='JM GmbH', familyName='Meyer-Operation', givenName='Andrew'),
|
1202=person(personType='LP', tradeName='JM GmbH', salutation='Herr', familyName='Meyer-Operation', givenName='Andrew'),
|
||||||
1203=person(personType='LP', tradeName='JM GmbH', familyName='Meyer-Contract', givenName='Philip'),
|
1203=person(personType='LP', tradeName='JM GmbH', salutation='Herr', familyName='Meyer-Contract', givenName='Philip'),
|
||||||
1204=person(personType='LP', tradeName='JM GmbH', familyName='Meyer-VIP', givenName='Tammy'),
|
1204=person(personType='LP', tradeName='JM GmbH', salutation='Frau', familyName='Meyer-VIP', givenName='Tammy'),
|
||||||
1301=person(personType='??', tradeName='Test PS', familyName='Schmidt', givenName='Petra'),
|
1301=person(personType='??', tradeName='Test PS', familyName='Schmidt', givenName='Petra'),
|
||||||
132=person(personType='??', tradeName='Ragnar IT-Beratung', familyName='Richter', givenName='Ragnar'),
|
132=person(personType='??', tradeName='Ragnar IT-Beratung', salutation='Herr', familyName='Richter', givenName='Ragnar'),
|
||||||
1401=person(personType='NP', familyName='Fanninga', givenName='Frauke'),
|
1401=person(personType='NP', salutation='Frau', familyName='Fanninga', givenName='Frauke'),
|
||||||
1501=person(personType='NP', familyName='Camus', givenName='Cecilia'),
|
1501=person(personType='NP', salutation='Frau', familyName='Camus', givenName='Cecilia'),
|
||||||
212=person(personType='LP', tradeName='Hostsharing e.G.', familyName='Hostsharing', givenName='Hostmaster'),
|
212=person(personType='LP', tradeName='Hostsharing e.G.', salutation='Firma', familyName='Hostsharing', givenName='Hostmaster'),
|
||||||
90436=person(personType='??', tradeName='Wasserwerk Südholstein', familyName='Milberg', givenName='Christiane'),
|
90436=person(personType='??', tradeName='Wasserwerk Südholstein', salutation='Frau', familyName='Milberg', givenName='Christiane'),
|
||||||
90437=person(personType='??', tradeName='Das Perfekte Haus', familyName='Wiese', givenName='Richard'),
|
90437=person(personType='??', tradeName='Das Perfekte Haus', salutation='Herr', familyName='Wiese', givenName='Richard'),
|
||||||
90438=person(personType='??', tradeName='Wasswerwerk Südholstein', familyName='Metzger', givenName='Karim'),
|
90438=person(personType='??', tradeName='Wasswerwerk Südholstein', salutation='Herr', familyName='Metzger', givenName='Karim'),
|
||||||
90590=person(personType='??', tradeName='Das Perfekte Haus', familyName='Wiese', givenName='Inhaber R.'),
|
90590=person(personType='??', tradeName='Das Perfekte Haus', salutation='Herr', familyName='Wiese', givenName='Inhaber R.'),
|
||||||
90629=person(personType='NP', familyName='Richter', givenName='Ragnar'),
|
90629=person(personType='NP', familyName='Richter', givenName='Ragnar'),
|
||||||
90677=person(personType='NP', familyName='Henning', givenName='Eike'),
|
90677=person(personType='NP', familyName='Henning', givenName='Eike'),
|
||||||
90698=person(personType='NP', familyName='Henning', givenName='Jan')
|
90698=person(personType='NP', familyName='Henning', givenName='Jan')
|
||||||
@ -272,71 +275,81 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
|
|||||||
""");
|
""");
|
||||||
assertThat(toJsonFormattedString(relations)).isEqualToIgnoringWhitespace("""
|
assertThat(toJsonFormattedString(relations)).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
2000000=rel(anchor='LP Hostsharing e.G.', type='PARTNER', holder='?? Michael Mellis', contact='Herr Michael Mellis , Michael Mellis'),
|
2000000=rel(anchor='LP Hostsharing e.G.', type='PARTNER', holder='?? Michael Mellis', contact='Herr Michael Mellis, Michael Mellis'),
|
||||||
2000001=rel(anchor='?? Michael Mellis', type='DEBITOR', holder='?? Michael Mellis', contact='Herr Michael Mellis , Michael Mellis'),
|
2000001=rel(anchor='?? Michael Mellis', type='DEBITOR', holder='?? Michael Mellis', contact='Herr Michael Mellis, Michael Mellis'),
|
||||||
2000002=rel(anchor='LP Hostsharing e.G.', type='PARTNER', holder='?? Ragnar IT-Beratung', contact='Herr Ragnar Richter , Ragnar IT-Beratung'),
|
2000002=rel(anchor='LP Hostsharing e.G.', type='PARTNER', holder='?? Ragnar IT-Beratung', contact='Herr Ragnar Richter, Ragnar IT-Beratung'),
|
||||||
2000003=rel(anchor='?? Ragnar IT-Beratung', type='DEBITOR', holder='?? Ragnar IT-Beratung', contact='Herr Ragnar Richter , Ragnar IT-Beratung'),
|
2000003=rel(anchor='?? Ragnar IT-Beratung', type='DEBITOR', holder='?? Ragnar IT-Beratung', contact='Herr Ragnar Richter, Ragnar IT-Beratung'),
|
||||||
2000004=rel(anchor='LP Hostsharing e.G.', type='PARTNER', holder='LP Hostsharing e.G.', contact='Firma Hostmaster Hostsharing , Hostsharing e.G.'),
|
2000004=rel(anchor='LP Hostsharing e.G.', type='PARTNER', holder='LP Hostsharing e.G.', contact='Firma Hostmaster Hostsharing, Hostsharing e.G.'),
|
||||||
2000005=rel(anchor='LP Hostsharing e.G.', type='DEBITOR', holder='LP Hostsharing e.G.', contact='Firma Hostmaster Hostsharing , Hostsharing e.G.'),
|
2000005=rel(anchor='LP Hostsharing e.G.', type='DEBITOR', holder='LP Hostsharing e.G.', contact='Firma Hostmaster Hostsharing, Hostsharing e.G.'),
|
||||||
2000006=rel(anchor='LP Hostsharing e.G.', type='PARTNER', holder='?? Wasserwerk Südholstein', contact='Frau Christiane Milberg , Wasserwerk Südholstein'),
|
2000006=rel(anchor='LP Hostsharing e.G.', type='PARTNER', holder='?? Wasserwerk Südholstein', contact='Frau Christiane Milberg, Wasserwerk Südholstein'),
|
||||||
2000007=rel(anchor='?? Wasserwerk Südholstein', type='DEBITOR', holder='?? Wasserwerk Südholstein', contact='Frau Christiane Milberg , Wasserwerk Südholstein'),
|
2000007=rel(anchor='?? Wasserwerk Südholstein', type='DEBITOR', holder='?? Wasserwerk Südholstein', contact='Frau Christiane Milberg, Wasserwerk Südholstein'),
|
||||||
2000008=rel(anchor='LP Hostsharing e.G.', type='PARTNER', holder='?? Das Perfekte Haus', contact='Herr Richard Wiese , Das Perfekte Haus'),
|
2000008=rel(anchor='LP Hostsharing e.G.', type='PARTNER', holder='?? Das Perfekte Haus', contact='Herr Richard Wiese, Das Perfekte Haus'),
|
||||||
2000009=rel(anchor='?? Das Perfekte Haus', type='DEBITOR', holder='?? Das Perfekte Haus', contact='Herr Inhaber R. Wiese , Das Perfekte Haus'),
|
2000009=rel(anchor='?? Das Perfekte Haus', type='DEBITOR', holder='?? Das Perfekte Haus', contact='Herr Inhaber R. Wiese, Das Perfekte Haus'),
|
||||||
2000010=rel(anchor='LP Hostsharing e.G.', type='PARTNER', holder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
2000010=rel(anchor='LP Hostsharing e.G.', type='PARTNER', holder='LP JM GmbH', contact='Herr Philip Meyer-Contract, JM GmbH'),
|
||||||
2000011=rel(anchor='LP JM GmbH', type='DEBITOR', holder='LP JM GmbH', contact='Frau Dr. Jenny Meyer-Billing , JM GmbH'),
|
2000011=rel(anchor='LP JM GmbH', type='DEBITOR', holder='LP JM GmbH', contact='Frau Dr. Jenny Meyer-Billing, JM GmbH'),
|
||||||
2000012=rel(anchor='LP Hostsharing e.G.', type='PARTNER', holder='?? Test PS', contact='Petra Schmidt , Test PS'),
|
2000012=rel(anchor='LP Hostsharing e.G.', type='PARTNER', holder='?? Test PS', contact='Petra Schmidt, Test PS'),
|
||||||
2000013=rel(anchor='?? Test PS', type='DEBITOR', holder='?? Test PS', contact='Petra Schmidt , Test PS'),
|
2000013=rel(anchor='?? Test PS', type='DEBITOR', holder='?? Test PS', contact='Petra Schmidt, Test PS'),
|
||||||
2000014=rel(anchor='LP Hostsharing e.G.', type='PARTNER', holder='NP Camus, Cecilia', contact='Frau Cecilia Camus '),
|
2000014=rel(anchor='LP Hostsharing e.G.', type='PARTNER', holder='NP Camus, Cecilia', contact='Frau Cecilia Camus'),
|
||||||
2000015=rel(anchor='NP Camus, Cecilia', type='DEBITOR', holder='NP Camus, Cecilia', contact='Frau Cecilia Camus '),
|
2000015=rel(anchor='NP Camus, Cecilia', type='DEBITOR', holder='NP Camus, Cecilia', contact='Frau Cecilia Camus'),
|
||||||
2000016=rel(anchor='LP Hostsharing e.G.', type='PARTNER', holder='null null, null'),
|
2000016=rel(anchor='LP Hostsharing e.G.', type='PARTNER', holder='null null, null'),
|
||||||
2000017=rel(anchor='null null, null', type='DEBITOR'),
|
2000017=rel(anchor='null null, null', type='DEBITOR'),
|
||||||
2000018=rel(anchor='LP Hostsharing e.G.', type='OPERATIONS', holder='LP Hostsharing e.G.', contact='Firma Hostmaster Hostsharing , Hostsharing e.G.'),
|
2000018=rel(anchor='LP Hostsharing e.G.', type='OPERATIONS_ALERT', holder='LP Hostsharing e.G.', contact='Firma Hostmaster Hostsharing, Hostsharing e.G.'),
|
||||||
2000019=rel(anchor='LP Hostsharing e.G.', type='REPRESENTATIVE', holder='LP Hostsharing e.G.', contact='Firma Hostmaster Hostsharing , Hostsharing e.G.'),
|
2000019=rel(anchor='LP Hostsharing e.G.', type='OPERATIONS', holder='LP Hostsharing e.G.', contact='Firma Hostmaster Hostsharing, Hostsharing e.G.'),
|
||||||
2000020=rel(anchor='?? Michael Mellis', type='OPERATIONS', holder='?? Michael Mellis', contact='Herr Michael Mellis , Michael Mellis'),
|
2000020=rel(anchor='LP Hostsharing e.G.', type='REPRESENTATIVE', holder='LP Hostsharing e.G.', contact='Firma Hostmaster Hostsharing, Hostsharing e.G.'),
|
||||||
2000021=rel(anchor='?? Michael Mellis', type='REPRESENTATIVE', holder='?? Michael Mellis', contact='Herr Michael Mellis , Michael Mellis'),
|
2000021=rel(anchor='?? Michael Mellis', type='OPERATIONS_ALERT', holder='?? Michael Mellis', contact='Herr Michael Mellis, Michael Mellis'),
|
||||||
2000022=rel(anchor='?? Michael Mellis', type='SUBSCRIBER', mark='operations-discussion', holder='?? Michael Mellis', contact='Herr Michael Mellis , Michael Mellis'),
|
2000022=rel(anchor='?? Michael Mellis', type='OPERATIONS', holder='?? Michael Mellis', contact='Herr Michael Mellis, Michael Mellis'),
|
||||||
2000023=rel(anchor='?? Michael Mellis', type='SUBSCRIBER', mark='operations-announce', holder='?? Michael Mellis', contact='Herr Michael Mellis , Michael Mellis'),
|
2000023=rel(anchor='?? Michael Mellis', type='REPRESENTATIVE', holder='?? Michael Mellis', contact='Herr Michael Mellis, Michael Mellis'),
|
||||||
2000024=rel(anchor='?? Michael Mellis', type='SUBSCRIBER', mark='generalversammlung', holder='?? Michael Mellis', contact='Herr Michael Mellis , Michael Mellis'),
|
2000024=rel(anchor='?? Michael Mellis', type='SUBSCRIBER', mark='operations-discussion', holder='?? Michael Mellis', contact='Herr Michael Mellis, Michael Mellis'),
|
||||||
2000025=rel(anchor='?? Michael Mellis', type='SUBSCRIBER', mark='members-announce', holder='?? Michael Mellis', contact='Herr Michael Mellis , Michael Mellis'),
|
2000025=rel(anchor='?? Michael Mellis', type='SUBSCRIBER', mark='operations-announce', holder='?? Michael Mellis', contact='Herr Michael Mellis, Michael Mellis'),
|
||||||
2000026=rel(anchor='?? Michael Mellis', type='SUBSCRIBER', mark='members-discussion', holder='?? Michael Mellis', contact='Herr Michael Mellis , Michael Mellis'),
|
2000026=rel(anchor='?? Michael Mellis', type='SUBSCRIBER', mark='generalversammlung', holder='?? Michael Mellis', contact='Herr Michael Mellis, Michael Mellis'),
|
||||||
2000027=rel(anchor='?? Ragnar IT-Beratung', type='OPERATIONS', holder='?? Ragnar IT-Beratung', contact='Herr Ragnar Richter , Ragnar IT-Beratung'),
|
2000027=rel(anchor='?? Michael Mellis', type='SUBSCRIBER', mark='members-announce', holder='?? Michael Mellis', contact='Herr Michael Mellis, Michael Mellis'),
|
||||||
2000028=rel(anchor='?? Ragnar IT-Beratung', type='SUBSCRIBER', mark='operations-discussion', holder='?? Ragnar IT-Beratung', contact='Herr Ragnar Richter , Ragnar IT-Beratung'),
|
2000028=rel(anchor='?? Michael Mellis', type='SUBSCRIBER', mark='members-discussion', holder='?? Michael Mellis', contact='Herr Michael Mellis, Michael Mellis'),
|
||||||
2000029=rel(anchor='?? Ragnar IT-Beratung', type='SUBSCRIBER', mark='operations-announce', holder='?? Ragnar IT-Beratung', contact='Herr Ragnar Richter , Ragnar IT-Beratung'),
|
2000029=rel(anchor='?? Ragnar IT-Beratung', type='OPERATIONS_ALERT', holder='?? Ragnar IT-Beratung', contact='Herr Ragnar Richter, Ragnar IT-Beratung'),
|
||||||
2000030=rel(anchor='LP JM GmbH', type='EX_PARTNER', holder='LP JM e.K.', contact='JM e.K.'),
|
2000030=rel(anchor='?? Ragnar IT-Beratung', type='OPERATIONS', holder='?? Ragnar IT-Beratung', contact='Herr Ragnar Richter, Ragnar IT-Beratung'),
|
||||||
2000031=rel(anchor='LP JM GmbH', type='OPERATIONS', holder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
|
2000031=rel(anchor='?? Ragnar IT-Beratung', type='SUBSCRIBER', mark='operations-discussion', holder='?? Ragnar IT-Beratung', contact='Herr Ragnar Richter, Ragnar IT-Beratung'),
|
||||||
2000032=rel(anchor='LP JM GmbH', type='VIP_CONTACT', holder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
|
2000032=rel(anchor='?? Ragnar IT-Beratung', type='SUBSCRIBER', mark='operations-announce', holder='?? Ragnar IT-Beratung', contact='Herr Ragnar Richter, Ragnar IT-Beratung'),
|
||||||
2000033=rel(anchor='LP JM GmbH', type='SUBSCRIBER', mark='operations-announce', holder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
|
2000033=rel(anchor='LP JM GmbH', type='EX_PARTNER', holder='LP JM e.K.', contact='JM e.K.'),
|
||||||
2000034=rel(anchor='LP JM GmbH', type='REPRESENTATIVE', holder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
2000034=rel(anchor='LP JM GmbH', type='OPERATIONS_ALERT', holder='LP JM GmbH', contact='Herr Andrew Meyer-Operation, JM GmbH'),
|
||||||
2000035=rel(anchor='LP JM GmbH', type='SUBSCRIBER', mark='members-announce', holder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
2000035=rel(anchor='LP JM GmbH', type='OPERATIONS', holder='LP JM GmbH', contact='Herr Andrew Meyer-Operation, JM GmbH'),
|
||||||
2000036=rel(anchor='LP JM GmbH', type='SUBSCRIBER', mark='customers-announce', holder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
2000036=rel(anchor='LP JM GmbH', type='VIP_CONTACT', holder='LP JM GmbH', contact='Herr Andrew Meyer-Operation, JM GmbH'),
|
||||||
2000037=rel(anchor='LP JM GmbH', type='VIP_CONTACT', holder='LP JM GmbH', contact='Frau Tammy Meyer-VIP , JM GmbH'),
|
2000037=rel(anchor='LP JM GmbH', type='SUBSCRIBER', mark='operations-announce', holder='LP JM GmbH', contact='Herr Andrew Meyer-Operation, JM GmbH'),
|
||||||
2000038=rel(anchor='?? Test PS', type='OPERATIONS', holder='?? Test PS', contact='Petra Schmidt , Test PS'),
|
2000038=rel(anchor='LP JM GmbH', type='REPRESENTATIVE', holder='LP JM GmbH', contact='Herr Philip Meyer-Contract, JM GmbH'),
|
||||||
2000039=rel(anchor='?? Test PS', type='REPRESENTATIVE', holder='?? Test PS', contact='Petra Schmidt , Test PS'),
|
2000039=rel(anchor='LP JM GmbH', type='SUBSCRIBER', mark='members-announce', holder='LP JM GmbH', contact='Herr Philip Meyer-Contract, JM GmbH'),
|
||||||
2000040=rel(anchor='LP JM GmbH', type='SUBSCRIBER', mark='operations-announce', holder='NP Fanninga, Frauke', contact='Frau Frauke Fanninga '),
|
2000040=rel(anchor='LP JM GmbH', type='SUBSCRIBER', mark='customers-announce', holder='LP JM GmbH', contact='Herr Philip Meyer-Contract, JM GmbH'),
|
||||||
2000041=rel(anchor='NP Camus, Cecilia', type='OPERATIONS', holder='NP Camus, Cecilia', contact='Frau Cecilia Camus '),
|
2000041=rel(anchor='LP JM GmbH', type='VIP_CONTACT', holder='LP JM GmbH', contact='Frau Tammy Meyer-VIP, JM GmbH'),
|
||||||
2000042=rel(anchor='NP Camus, Cecilia', type='REPRESENTATIVE', holder='NP Camus, Cecilia', contact='Frau Cecilia Camus '),
|
2000042=rel(anchor='?? Test PS', type='OPERATIONS_ALERT', holder='?? Test PS', contact='Petra Schmidt, Test PS'),
|
||||||
2000043=rel(anchor='?? Wasserwerk Südholstein', type='REPRESENTATIVE', holder='?? Wasserwerk Südholstein', contact='Frau Christiane Milberg , Wasserwerk Südholstein'),
|
2000043=rel(anchor='?? Test PS', type='OPERATIONS', holder='?? Test PS', contact='Petra Schmidt, Test PS'),
|
||||||
2000044=rel(anchor='?? Wasserwerk Südholstein', type='SUBSCRIBER', mark='generalversammlung', holder='?? Wasserwerk Südholstein', contact='Frau Christiane Milberg , Wasserwerk Südholstein'),
|
2000044=rel(anchor='?? Test PS', type='REPRESENTATIVE', holder='?? Test PS', contact='Petra Schmidt, Test PS'),
|
||||||
2000045=rel(anchor='?? Wasserwerk Südholstein', type='SUBSCRIBER', mark='members-announce', holder='?? Wasserwerk Südholstein', contact='Frau Christiane Milberg , Wasserwerk Südholstein'),
|
2000045=rel(anchor='LP JM GmbH', type='SUBSCRIBER', mark='operations-announce', holder='NP Fanninga, Frauke', contact='Frau Frauke Fanninga'),
|
||||||
2000046=rel(anchor='?? Wasserwerk Südholstein', type='SUBSCRIBER', mark='members-discussion', holder='?? Wasserwerk Südholstein', contact='Frau Christiane Milberg , Wasserwerk Südholstein'),
|
2000046=rel(anchor='NP Camus, Cecilia', type='OPERATIONS_ALERT', holder='NP Camus, Cecilia', contact='Frau Cecilia Camus'),
|
||||||
2000047=rel(anchor='?? Das Perfekte Haus', type='OPERATIONS', holder='?? Das Perfekte Haus', contact='Herr Richard Wiese , Das Perfekte Haus'),
|
2000047=rel(anchor='NP Camus, Cecilia', type='OPERATIONS', holder='NP Camus, Cecilia', contact='Frau Cecilia Camus'),
|
||||||
2000048=rel(anchor='?? Das Perfekte Haus', type='REPRESENTATIVE', holder='?? Das Perfekte Haus', contact='Herr Richard Wiese , Das Perfekte Haus'),
|
2000048=rel(anchor='NP Camus, Cecilia', type='REPRESENTATIVE', holder='NP Camus, Cecilia', contact='Frau Cecilia Camus'),
|
||||||
2000049=rel(anchor='?? Das Perfekte Haus', type='SUBSCRIBER', mark='operations-discussion', holder='?? Das Perfekte Haus', contact='Herr Richard Wiese , Das Perfekte Haus'),
|
2000049=rel(anchor='?? Wasserwerk Südholstein', type='REPRESENTATIVE', holder='?? Wasserwerk Südholstein', contact='Frau Christiane Milberg, Wasserwerk Südholstein'),
|
||||||
2000050=rel(anchor='?? Das Perfekte Haus', type='SUBSCRIBER', mark='operations-announce', holder='?? Das Perfekte Haus', contact='Herr Richard Wiese , Das Perfekte Haus'),
|
2000050=rel(anchor='?? Wasserwerk Südholstein', type='SUBSCRIBER', mark='generalversammlung', holder='?? Wasserwerk Südholstein', contact='Frau Christiane Milberg, Wasserwerk Südholstein'),
|
||||||
2000051=rel(anchor='?? Das Perfekte Haus', type='SUBSCRIBER', mark='generalversammlung', holder='?? Das Perfekte Haus', contact='Herr Richard Wiese , Das Perfekte Haus'),
|
2000051=rel(anchor='?? Wasserwerk Südholstein', type='SUBSCRIBER', mark='members-announce', holder='?? Wasserwerk Südholstein', contact='Frau Christiane Milberg, Wasserwerk Südholstein'),
|
||||||
2000052=rel(anchor='?? Das Perfekte Haus', type='SUBSCRIBER', mark='members-announce', holder='?? Das Perfekte Haus', contact='Herr Richard Wiese , Das Perfekte Haus'),
|
2000052=rel(anchor='?? Wasserwerk Südholstein', type='SUBSCRIBER', mark='members-discussion', holder='?? Wasserwerk Südholstein', contact='Frau Christiane Milberg, Wasserwerk Südholstein'),
|
||||||
2000053=rel(anchor='?? Das Perfekte Haus', type='SUBSCRIBER', mark='members-discussion', holder='?? Das Perfekte Haus', contact='Herr Richard Wiese , Das Perfekte Haus'),
|
2000053=rel(anchor='?? Das Perfekte Haus', type='OPERATIONS_ALERT', holder='?? Das Perfekte Haus', contact='Herr Richard Wiese, Das Perfekte Haus'),
|
||||||
2000054=rel(anchor='?? Wasserwerk Südholstein', type='OPERATIONS', holder='?? Wasswerwerk Südholstein', contact='Herr Karim Metzger , Wasswerwerk Südholstein'),
|
2000054=rel(anchor='?? Das Perfekte Haus', type='OPERATIONS', holder='?? Das Perfekte Haus', contact='Herr Richard Wiese, Das Perfekte Haus'),
|
||||||
2000055=rel(anchor='?? Wasserwerk Südholstein', type='SUBSCRIBER', mark='operations-discussion', holder='?? Wasswerwerk Südholstein', contact='Herr Karim Metzger , Wasswerwerk Südholstein'),
|
2000055=rel(anchor='?? Das Perfekte Haus', type='REPRESENTATIVE', holder='?? Das Perfekte Haus', contact='Herr Richard Wiese, Das Perfekte Haus'),
|
||||||
2000056=rel(anchor='?? Wasserwerk Südholstein', type='SUBSCRIBER', mark='operations-announce', holder='?? Wasswerwerk Südholstein', contact='Herr Karim Metzger , Wasswerwerk Südholstein'),
|
2000056=rel(anchor='?? Das Perfekte Haus', type='SUBSCRIBER', mark='operations-discussion', holder='?? Das Perfekte Haus', contact='Herr Richard Wiese, Das Perfekte Haus'),
|
||||||
2000057=rel(anchor='?? Ragnar IT-Beratung', type='REPRESENTATIVE', holder='NP Richter, Ragnar', contact='Ragnar Richter '),
|
2000057=rel(anchor='?? Das Perfekte Haus', type='SUBSCRIBER', mark='operations-announce', holder='?? Das Perfekte Haus', contact='Herr Richard Wiese, Das Perfekte Haus'),
|
||||||
2000058=rel(anchor='?? Ragnar IT-Beratung', type='SUBSCRIBER', mark='generalversammlung', holder='NP Richter, Ragnar', contact='Ragnar Richter '),
|
2000058=rel(anchor='?? Das Perfekte Haus', type='SUBSCRIBER', mark='generalversammlung', holder='?? Das Perfekte Haus', contact='Herr Richard Wiese, Das Perfekte Haus'),
|
||||||
2000059=rel(anchor='?? Ragnar IT-Beratung', type='SUBSCRIBER', mark='members-announce', holder='NP Richter, Ragnar', contact='Ragnar Richter '),
|
2000059=rel(anchor='?? Das Perfekte Haus', type='SUBSCRIBER', mark='members-announce', holder='?? Das Perfekte Haus', contact='Herr Richard Wiese, Das Perfekte Haus'),
|
||||||
2000060=rel(anchor='?? Ragnar IT-Beratung', type='SUBSCRIBER', mark='members-discussion', holder='NP Richter, Ragnar', contact='Ragnar Richter '),
|
2000060=rel(anchor='?? Das Perfekte Haus', type='SUBSCRIBER', mark='members-discussion', holder='?? Das Perfekte Haus', contact='Herr Richard Wiese, Das Perfekte Haus'),
|
||||||
2000061=rel(anchor='?? Ragnar IT-Beratung', type='OPERATIONS', holder='NP Henning, Eike', contact='Eike Henning '),
|
2000061=rel(anchor='?? Wasserwerk Südholstein', type='OPERATIONS_ALERT', holder='?? Wasswerwerk Südholstein', contact='Herr Karim Metzger, Wasswerwerk Südholstein'),
|
||||||
2000062=rel(anchor='?? Ragnar IT-Beratung', type='SUBSCRIBER', mark='operations-discussion', holder='NP Henning, Eike', contact='Eike Henning '),
|
2000062=rel(anchor='?? Wasserwerk Südholstein', type='OPERATIONS', holder='?? Wasswerwerk Südholstein', contact='Herr Karim Metzger, Wasswerwerk Südholstein'),
|
||||||
2000063=rel(anchor='?? Ragnar IT-Beratung', type='SUBSCRIBER', mark='operations-announce', holder='NP Henning, Eike', contact='Eike Henning '),
|
2000063=rel(anchor='?? Wasserwerk Südholstein', type='SUBSCRIBER', mark='operations-discussion', holder='?? Wasswerwerk Südholstein', contact='Herr Karim Metzger, Wasswerwerk Südholstein'),
|
||||||
2000064=rel(anchor='?? Ragnar IT-Beratung', type='OPERATIONS', holder='NP Henning, Jan', contact='Jan Henning ')
|
2000064=rel(anchor='?? Wasserwerk Südholstein', type='SUBSCRIBER', mark='operations-announce', holder='?? Wasswerwerk Südholstein', contact='Herr Karim Metzger, Wasswerwerk Südholstein'),
|
||||||
|
2000065=rel(anchor='?? Ragnar IT-Beratung', type='REPRESENTATIVE', holder='NP Richter, Ragnar', contact='Ragnar Richter'),
|
||||||
|
2000066=rel(anchor='?? Ragnar IT-Beratung', type='SUBSCRIBER', mark='generalversammlung', holder='NP Richter, Ragnar', contact='Ragnar Richter'),
|
||||||
|
2000067=rel(anchor='?? Ragnar IT-Beratung', type='SUBSCRIBER', mark='members-announce', holder='NP Richter, Ragnar', contact='Ragnar Richter'),
|
||||||
|
2000068=rel(anchor='?? Ragnar IT-Beratung', type='SUBSCRIBER', mark='members-discussion', holder='NP Richter, Ragnar', contact='Ragnar Richter'),
|
||||||
|
2000069=rel(anchor='?? Ragnar IT-Beratung', type='OPERATIONS_ALERT', holder='NP Henning, Eike', contact='Eike Henning'),
|
||||||
|
2000070=rel(anchor='?? Ragnar IT-Beratung', type='OPERATIONS', holder='NP Henning, Eike', contact='Eike Henning'),
|
||||||
|
2000071=rel(anchor='?? Ragnar IT-Beratung', type='SUBSCRIBER', mark='operations-discussion', holder='NP Henning, Eike', contact='Eike Henning'),
|
||||||
|
2000072=rel(anchor='?? Ragnar IT-Beratung', type='SUBSCRIBER', mark='operations-announce', holder='NP Henning, Eike', contact='Eike Henning'),
|
||||||
|
2000073=rel(anchor='?? Ragnar IT-Beratung', type='OPERATIONS_ALERT', holder='NP Henning, Jan', contact='Jan Henning'),
|
||||||
|
2000074=rel(anchor='?? Ragnar IT-Beratung', type='OPERATIONS', holder='NP Henning, Jan', contact='Jan Henning')
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
@ -442,7 +455,7 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
|
|||||||
34002=CoopAssetsTransaction(M-1002000: 2016-12-31, DISBURSAL, -100.00, 1002000, for cancellation D),
|
34002=CoopAssetsTransaction(M-1002000: 2016-12-31, DISBURSAL, -100.00, 1002000, for cancellation D),
|
||||||
34003=CoopAssetsTransaction(M-1002000: 2016-12-31, LOSS, -20.00, 1002000, for cancellation D),
|
34003=CoopAssetsTransaction(M-1002000: 2016-12-31, LOSS, -20.00, 1002000, for cancellation D),
|
||||||
35001=CoopAssetsTransaction(M-1909000: 2024-01-15, DEPOSIT, 128.00, 1909000, for subscription E),
|
35001=CoopAssetsTransaction(M-1909000: 2024-01-15, DEPOSIT, 128.00, 1909000, for subscription E),
|
||||||
35002=CoopAssetsTransaction(M-1909000: 2024-01-20, ADJUSTMENT, -128.00, 1909000, chargeback for subscription E, M-1909000:DEP:+128.00),
|
35002=CoopAssetsTransaction(M-1909000: 2024-01-20, REVERSAL, -128.00, 1909000, chargeback for subscription E, M-1909000:DEP:+128.00),
|
||||||
358=CoopAssetsTransaction(M-1000300: 2000-12-06, DEPOSIT, 5120, 1000300, for subscription A),
|
358=CoopAssetsTransaction(M-1000300: 2000-12-06, DEPOSIT, 5120, 1000300, for subscription A),
|
||||||
442=CoopAssetsTransaction(M-1015200: 2003-07-07, DEPOSIT, 64, 1015200),
|
442=CoopAssetsTransaction(M-1015200: 2003-07-07, DEPOSIT, 64, 1015200),
|
||||||
577=CoopAssetsTransaction(M-1000300: 2011-12-12, DEPOSIT, 1024, 1000300),
|
577=CoopAssetsTransaction(M-1000300: 2011-12-12, DEPOSIT, 1024, 1000300),
|
||||||
@ -502,7 +515,7 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
|
|||||||
// this happens if a natural person is marked as 'contractual' for itself
|
// this happens if a natural person is marked as 'contractual' for itself
|
||||||
final var idsToRemove = new HashSet<Integer>();
|
final var idsToRemove = new HashSet<Integer>();
|
||||||
relations.forEach((id, r) -> {
|
relations.forEach((id, r) -> {
|
||||||
if (r.getHolder() == r.getAnchor()) {
|
if (r.getType() == HsOfficeRelationType.REPRESENTATIVE && r.getHolder() == r.getAnchor()) {
|
||||||
idsToRemove.add(id);
|
idsToRemove.add(id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -670,7 +683,7 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
|
|||||||
jpaAttempt.transacted(() -> {
|
jpaAttempt.transacted(() -> {
|
||||||
context(rbacSuperuser);
|
context(rbacSuperuser);
|
||||||
coopShares.forEach(this::persist);
|
coopShares.forEach(this::persist);
|
||||||
updateLegacyIds(coopShares, "hs_office.coopsharestransaction_legacy_id", "member_share_id");
|
updateLegacyIds(coopShares, "hs_office.coopsharetx_legacy_id", "member_share_id");
|
||||||
|
|
||||||
}).assertSuccessful();
|
}).assertSuccessful();
|
||||||
|
|
||||||
@ -795,23 +808,23 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
|
|||||||
? HsOfficeCoopSharesTransactionType.SUBSCRIPTION
|
? HsOfficeCoopSharesTransactionType.SUBSCRIPTION
|
||||||
: "UNSUBSCRIPTION".equals(rec.getString("action"))
|
: "UNSUBSCRIPTION".equals(rec.getString("action"))
|
||||||
? HsOfficeCoopSharesTransactionType.CANCELLATION
|
? HsOfficeCoopSharesTransactionType.CANCELLATION
|
||||||
: HsOfficeCoopSharesTransactionType.ADJUSTMENT
|
: HsOfficeCoopSharesTransactionType.REVERSAL
|
||||||
)
|
)
|
||||||
.shareCount(rec.getInteger("quantity"))
|
.shareCount(rec.getInteger("quantity"))
|
||||||
.comment(rec.getString("comment"))
|
.comment(rec.getString("comment"))
|
||||||
.reference(member.getMemberNumber().toString())
|
.reference(member.getMemberNumber().toString())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
if (shareTransaction.getTransactionType() == HsOfficeCoopSharesTransactionType.ADJUSTMENT) {
|
if (shareTransaction.getTransactionType() == HsOfficeCoopSharesTransactionType.REVERSAL) {
|
||||||
final var negativeValue = -shareTransaction.getShareCount();
|
final var negativeValue = -shareTransaction.getShareCount();
|
||||||
final var adjustedShareTx = coopShares.values().stream().filter(a ->
|
final var revertedShareTx = coopShares.values().stream().filter(a ->
|
||||||
a.getTransactionType() != HsOfficeCoopSharesTransactionType.ADJUSTMENT &&
|
a.getTransactionType() != HsOfficeCoopSharesTransactionType.REVERSAL &&
|
||||||
a.getMembership() == shareTransaction.getMembership() &&
|
a.getMembership() == shareTransaction.getMembership() &&
|
||||||
a.getShareCount() == negativeValue)
|
a.getShareCount() == negativeValue)
|
||||||
.findAny()
|
.findAny()
|
||||||
.orElseThrow(() -> new IllegalStateException(
|
.orElseThrow(() -> new IllegalStateException(
|
||||||
"cannot determine share reverse entry for adjustment " + shareTransaction));
|
"cannot determine share reverse entry for reversal " + shareTransaction));
|
||||||
shareTransaction.setAdjustedShareTx(adjustedShareTx);
|
shareTransaction.setRevertedShareTx(revertedShareTx);
|
||||||
}
|
}
|
||||||
coopShares.put(rec.getInteger("member_share_id"), shareTransaction);
|
coopShares.put(rec.getInteger("member_share_id"), shareTransaction);
|
||||||
});
|
});
|
||||||
@ -837,7 +850,7 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
|
|||||||
final var assetTypeMapping = new HashMap<String, HsOfficeCoopAssetsTransactionType>() {
|
final var assetTypeMapping = new HashMap<String, HsOfficeCoopAssetsTransactionType>() {
|
||||||
|
|
||||||
{
|
{
|
||||||
put("ADJUSTMENT", HsOfficeCoopAssetsTransactionType.ADJUSTMENT);
|
put("ADJUSTMENT", HsOfficeCoopAssetsTransactionType.REVERSAL);
|
||||||
put("HANDOVER", HsOfficeCoopAssetsTransactionType.TRANSFER);
|
put("HANDOVER", HsOfficeCoopAssetsTransactionType.TRANSFER);
|
||||||
put("ADOPTION", HsOfficeCoopAssetsTransactionType.ADOPTION);
|
put("ADOPTION", HsOfficeCoopAssetsTransactionType.ADOPTION);
|
||||||
put("LOSS", HsOfficeCoopAssetsTransactionType.LOSS);
|
put("LOSS", HsOfficeCoopAssetsTransactionType.LOSS);
|
||||||
@ -865,16 +878,16 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
|
|||||||
.reference(member.getMemberNumber().toString())
|
.reference(member.getMemberNumber().toString())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
if (assetTransaction.getTransactionType() == HsOfficeCoopAssetsTransactionType.ADJUSTMENT) {
|
if (assetTransaction.getTransactionType() == HsOfficeCoopAssetsTransactionType.REVERSAL) {
|
||||||
final var negativeValue = assetTransaction.getAssetValue().negate();
|
final var negativeValue = assetTransaction.getAssetValue().negate();
|
||||||
final var adjustedAssetTx = coopAssets.values().stream().filter(a ->
|
final var revertedAssetTx = coopAssets.values().stream().filter(a ->
|
||||||
a.getTransactionType() != HsOfficeCoopAssetsTransactionType.ADJUSTMENT &&
|
a.getTransactionType() != HsOfficeCoopAssetsTransactionType.REVERSAL &&
|
||||||
a.getMembership() == assetTransaction.getMembership() &&
|
a.getMembership() == assetTransaction.getMembership() &&
|
||||||
a.getAssetValue().equals(negativeValue))
|
a.getAssetValue().equals(negativeValue))
|
||||||
.findAny()
|
.findAny()
|
||||||
.orElseThrow(() -> new IllegalStateException(
|
.orElseThrow(() -> new IllegalStateException(
|
||||||
"cannot determine asset reverse entry for adjustment " + assetTransaction));
|
"cannot determine asset reverse entry for reversal " + assetTransaction));
|
||||||
assetTransaction.setAdjustedAssetTx(adjustedAssetTx);
|
assetTransaction.setRevertedAssetTx(revertedAssetTx);
|
||||||
}
|
}
|
||||||
|
|
||||||
coopAssets.put(rec.getInteger("member_asset_id"), assetTransaction);
|
coopAssets.put(rec.getInteger("member_asset_id"), assetTransaction);
|
||||||
@ -958,6 +971,9 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
|
|||||||
|
|
||||||
HsOfficePersonEntity contactPerson = partnerPerson;
|
HsOfficePersonEntity contactPerson = partnerPerson;
|
||||||
if (!StringUtils.equals(rec.getString("firma"), partnerPerson.getTradeName()) ||
|
if (!StringUtils.equals(rec.getString("firma"), partnerPerson.getTradeName()) ||
|
||||||
|
partnerPerson.getPersonType() != determinePersonType(rec) ||
|
||||||
|
!StringUtils.equals(rec.getString("title"), partnerPerson.getTitle()) ||
|
||||||
|
!StringUtils.equals(rec.getString("salut"), partnerPerson.getSalutation()) ||
|
||||||
!StringUtils.equals(rec.getString("first_name"), partnerPerson.getGivenName()) ||
|
!StringUtils.equals(rec.getString("first_name"), partnerPerson.getGivenName()) ||
|
||||||
!StringUtils.equals(rec.getString("last_name"), partnerPerson.getFamilyName())) {
|
!StringUtils.equals(rec.getString("last_name"), partnerPerson.getFamilyName())) {
|
||||||
contactPerson = addPerson(HsOfficePersonEntity.builder().build(), rec);
|
contactPerson = addPerson(HsOfficePersonEntity.builder().build(), rec);
|
||||||
@ -976,6 +992,10 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
|
|||||||
debitor.getDebitorRel().setContact(contact);
|
debitor.getDebitorRel().setContact(contact);
|
||||||
}
|
}
|
||||||
if (containsRole(rec, "operation")) {
|
if (containsRole(rec, "operation")) {
|
||||||
|
addRelation(HsOfficeRelationType.OPERATIONS_ALERT, partnerPerson, contactPerson, contact);
|
||||||
|
addRelation(HsOfficeRelationType.OPERATIONS, partnerPerson, contactPerson, contact);
|
||||||
|
}
|
||||||
|
if (containsRole(rec, "silent")) {
|
||||||
addRelation(HsOfficeRelationType.OPERATIONS, partnerPerson, contactPerson, contact);
|
addRelation(HsOfficeRelationType.OPERATIONS, partnerPerson, contactPerson, contact);
|
||||||
}
|
}
|
||||||
if (containsRole(rec, "contractual")) {
|
if (containsRole(rec, "contractual")) {
|
||||||
@ -1053,34 +1073,60 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private HsOfficePersonEntity addPerson(final HsOfficePersonEntity person, final Record contactRecord) {
|
private HsOfficePersonEntity addPerson(final HsOfficePersonEntity person, final Record contactRecord) {
|
||||||
// TODO: title+salutation: add to person
|
person.setSalutation(contactRecord.getString("salut"));
|
||||||
|
person.setTitle(contactRecord.getString("title"));
|
||||||
person.setGivenName(contactRecord.getString("first_name"));
|
person.setGivenName(contactRecord.getString("first_name"));
|
||||||
person.setFamilyName(contactRecord.getString("last_name"));
|
person.setFamilyName(contactRecord.getString("last_name"));
|
||||||
person.setTradeName(contactRecord.getString("firma"));
|
person.setTradeName(contactRecord.getString("firma"));
|
||||||
determinePersonType(person, contactRecord.getString("roles"));
|
person.setPersonType(determinePersonType(contactRecord));
|
||||||
|
|
||||||
persons.put(contactRecord.getInteger("contact_id"), person);
|
persons.put(contactRecord.getInteger("contact_id"), person);
|
||||||
return person;
|
return person;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void determinePersonType(final HsOfficePersonEntity person, final String roles) {
|
private static HsOfficePersonType determinePersonType(final Record contactRecord) {
|
||||||
if (person.getTradeName().isBlank()) {
|
String roles = contactRecord.getString("roles");
|
||||||
person.setPersonType(HsOfficePersonType.NATURAL_PERSON);
|
String country = contactRecord.getString("country");
|
||||||
|
String familyName = contactRecord.getString("last_name");
|
||||||
|
String givenName = contactRecord.getString("first_name");
|
||||||
|
String tradeName = contactRecord.getString("firma");
|
||||||
|
|
||||||
|
if (PERSON_TYPES_BY_CONTACT.containsKey(contactRecord.getInteger("contact_id"))) {
|
||||||
|
return PERSON_TYPES_BY_CONTACT.get(contactRecord.getInteger("contact_id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tradeName.isBlank() || tradeName.startsWith("verstorben")) {
|
||||||
|
return HsOfficePersonType.NATURAL_PERSON;
|
||||||
} else
|
} else
|
||||||
// contractual && !partner with a firm and a natural person name
|
// contractual && !partner with a firm and a natural person name
|
||||||
// should actually be split up into two persons
|
// should actually be split up into two persons
|
||||||
// but the legacy database consists such records
|
// but the legacy database consists such records
|
||||||
if (roles.contains("contractual") && !roles.contains("partner") &&
|
|
||||||
!person.getFamilyName().isBlank() && !person.getGivenName().isBlank()) {
|
if (endsWithWord(tradeName, "OHG", "GbR", "KG", "UG", "PartGmbB", "mbB")) {
|
||||||
person.setPersonType(HsOfficePersonType.NATURAL_PERSON);
|
return HsOfficePersonType.INCORPORATED_FIRM; // Personengesellschaft. Gesellschafter haften persönlich.
|
||||||
} else if (endsWithWord(person.getTradeName(), "e.K.", "e.G.", "eG", "GmbH", "AG", "KG")) {
|
} else if (containsWord(tradeName, "e.K.", "e.G.", "eG", "gGmbH", "GmbH", "mbH", "AG", "e.V.", "eV", "e.V")
|
||||||
person.setPersonType(HsOfficePersonType.LEGAL_PERSON);
|
|| tradeName.toLowerCase().contains("haftungsbeschränkt")
|
||||||
} else if (endsWithWord(person.getTradeName(), "OHG")) {
|
|| tradeName.toLowerCase().contains("stiftung")
|
||||||
person.setPersonType(HsOfficePersonType.INCORPORATED_FIRM);
|
|| tradeName.toLowerCase().contains("stichting")
|
||||||
} else if (endsWithWord(person.getTradeName(), "GbR")) {
|
|| tradeName.toLowerCase().contains("foundation")
|
||||||
person.setPersonType(HsOfficePersonType.INCORPORATED_FIRM);
|
|| tradeName.toLowerCase().contains("schule")
|
||||||
|
|| tradeName.toLowerCase().contains("verein")
|
||||||
|
|| tradeName.toLowerCase().contains("gewerkschaft")
|
||||||
|
|| tradeName.toLowerCase().contains("gesellschaft")
|
||||||
|
|| tradeName.toLowerCase().contains("kirche")
|
||||||
|
|| tradeName.toLowerCase().contains("fraktion")
|
||||||
|
|| tradeName.toLowerCase().contains("landkreis")
|
||||||
|
|| tradeName.toLowerCase().contains("behörde")
|
||||||
|
|| tradeName.toLowerCase().contains("bundesamt")
|
||||||
|
|| tradeName.toLowerCase().contains("bezirksamt")
|
||||||
|
) {
|
||||||
|
return HsOfficePersonType.LEGAL_PERSON; // Haftungsbeschränkt
|
||||||
|
} else if (roles.contains("contractual") && !roles.contains("partner") &&
|
||||||
|
!familyName.isBlank() && !givenName.isBlank()) {
|
||||||
|
// REPRESENTATIVES are always natural persons
|
||||||
|
return HsOfficePersonType.NATURAL_PERSON;
|
||||||
} else {
|
} else {
|
||||||
person.setPersonType(HsOfficePersonType.UNKNOWN_PERSON_TYPE);
|
return HsOfficePersonType.UNKNOWN_PERSON_TYPE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1094,6 +1140,19 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean containsWord(final String value, final String... endings) {
|
||||||
|
final var lowerCaseValue = value.toLowerCase();
|
||||||
|
for (String ending : endings) {
|
||||||
|
if (lowerCaseValue.equals(ending.toLowerCase()) ||
|
||||||
|
lowerCaseValue.startsWith(ending.toLowerCase() + " ") ||
|
||||||
|
lowerCaseValue.contains(" " + ending.toLowerCase() + " ") ||
|
||||||
|
lowerCaseValue.endsWith(" " + ending.toLowerCase())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private void verifyContainsOnlyKnownRoles(final String roles) {
|
private void verifyContainsOnlyKnownRoles(final String roles) {
|
||||||
final var allowedRolesSet = stream(KNOWN_ROLES).collect(Collectors.toSet());
|
final var allowedRolesSet = stream(KNOWN_ROLES).collect(Collectors.toSet());
|
||||||
final var givenRolesSet = stream(roles.replace(" ", "").split(",")).collect(Collectors.toSet());
|
final var givenRolesSet = stream(roles.replace(" ", "").split(",")).collect(Collectors.toSet());
|
||||||
@ -1111,7 +1170,7 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
|
|||||||
contactRecord.getString("last_name"),
|
contactRecord.getString("last_name"),
|
||||||
contactRecord.getString("firma")));
|
contactRecord.getString("firma")));
|
||||||
contact.putEmailAddresses(Map.of("main", contactRecord.getString("email")));
|
contact.putEmailAddresses(Map.of("main", contactRecord.getString("email")));
|
||||||
contact.setPostalAddress(toAddress(contactRecord));
|
contact.putPostalAddress(toAddress(contactRecord));
|
||||||
contact.putPhoneNumbers(toPhoneNumbers(contactRecord));
|
contact.putPhoneNumbers(toPhoneNumbers(contactRecord));
|
||||||
|
|
||||||
contacts.put(contactRecord.getInteger("contact_id"), contact);
|
contacts.put(contactRecord.getInteger("contact_id"), contact);
|
||||||
@ -1131,36 +1190,23 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
|
|||||||
return phoneNumbers;
|
return phoneNumbers;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String toAddress(final Record rec) {
|
private Map<String, String> toAddress(final Record rec) {
|
||||||
final var result = new StringBuilder();
|
final var result = new LinkedHashMap<String, String>();
|
||||||
final var name = toName(
|
final var name = toName(
|
||||||
rec.getString("salut"),
|
rec.getString("salut"),
|
||||||
rec.getString("title"),
|
rec.getString("title"),
|
||||||
rec.getString("first_name"),
|
rec.getString("first_name"),
|
||||||
rec.getString("last_name"));
|
rec.getString("last_name"));
|
||||||
if (isNotBlank(name))
|
if (isNotBlank(name))
|
||||||
result.append(name + "\n");
|
result.put("name", name);
|
||||||
if (isNotBlank(rec.getString("firma")))
|
if (isNotBlank(rec.getString("firma")))
|
||||||
result.append(rec.getString("firma") + "\n");
|
result.put("firm", name);
|
||||||
if (isNotBlank(rec.getString("co")))
|
|
||||||
result.append("c/o " + rec.getString("co") + "\n");
|
|
||||||
if (isNotBlank(rec.getString("street")))
|
|
||||||
result.append(rec.getString("street") + "\n");
|
|
||||||
final var zipcodeAndCity = toZipcodeAndCity(rec);
|
|
||||||
if (isNotBlank(zipcodeAndCity))
|
|
||||||
result.append(zipcodeAndCity + "\n");
|
|
||||||
return result.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private String toZipcodeAndCity(final Record rec) {
|
List.of("co", "street", "zipcode", "city", "country").forEach(key -> {
|
||||||
final var result = new StringBuilder();
|
if (isNotBlank(rec.getString(key)))
|
||||||
if (isNotBlank(rec.getString("country")))
|
result.put(key, rec.getString(key));
|
||||||
result.append(rec.getString("country") + " ");
|
});
|
||||||
if (isNotBlank(rec.getString("zipcode")))
|
return result;
|
||||||
result.append(rec.getString("zipcode") + " ");
|
|
||||||
if (isNotBlank(rec.getString("city")))
|
|
||||||
result.append(rec.getString("city"));
|
|
||||||
return result.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String toCaption(
|
private String toCaption(
|
||||||
@ -1171,13 +1217,13 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
|
|||||||
final String firm) {
|
final String firm) {
|
||||||
final var result = new StringBuilder();
|
final var result = new StringBuilder();
|
||||||
if (isNotBlank(salut))
|
if (isNotBlank(salut))
|
||||||
result.append(salut + " ");
|
result.append((isBlank(result) ? "" : " ") + salut);
|
||||||
if (isNotBlank(title))
|
if (isNotBlank(title))
|
||||||
result.append(title + " ");
|
result.append((isBlank(result) ? "" : " ") + title);
|
||||||
if (isNotBlank(firstname))
|
if (isNotBlank(firstname))
|
||||||
result.append(firstname + " ");
|
result.append((isBlank(result) ? "" : " ") + firstname);
|
||||||
if (isNotBlank(lastname))
|
if (isNotBlank(lastname))
|
||||||
result.append(lastname + " ");
|
result.append((isBlank(result) ? "" : " ") + lastname);
|
||||||
if (isNotBlank(firm)) {
|
if (isNotBlank(firm)) {
|
||||||
result.append((isBlank(result) ? "" : ", ") + firm);
|
result.append((isBlank(result) ? "" : ", ") + firm);
|
||||||
}
|
}
|
||||||
|
@ -255,7 +255,7 @@ public class CsvDataImport extends ContextBasedTest {
|
|||||||
em.createNativeQuery("delete from hs_office.coopassettx where true").executeUpdate();
|
em.createNativeQuery("delete from hs_office.coopassettx where true").executeUpdate();
|
||||||
em.createNativeQuery("delete from hs_office.coopassettx_legacy_id where true").executeUpdate();
|
em.createNativeQuery("delete from hs_office.coopassettx_legacy_id where true").executeUpdate();
|
||||||
em.createNativeQuery("delete from hs_office.coopsharetx where true").executeUpdate();
|
em.createNativeQuery("delete from hs_office.coopsharetx where true").executeUpdate();
|
||||||
em.createNativeQuery("delete from hs_office.coopsharestransaction_legacy_id where true").executeUpdate();
|
em.createNativeQuery("delete from hs_office.coopsharetx_legacy_id where true").executeUpdate();
|
||||||
em.createNativeQuery("delete from hs_office.membership where true").executeUpdate();
|
em.createNativeQuery("delete from hs_office.membership where true").executeUpdate();
|
||||||
em.createNativeQuery("delete from hs_office.sepamandate where true").executeUpdate();
|
em.createNativeQuery("delete from hs_office.sepamandate where true").executeUpdate();
|
||||||
em.createNativeQuery("delete from hs_office.sepamandate_legacy_id where true").executeUpdate();
|
em.createNativeQuery("delete from hs_office.sepamandate_legacy_id where true").executeUpdate();
|
||||||
@ -275,7 +275,7 @@ public class CsvDataImport extends ContextBasedTest {
|
|||||||
em.createNativeQuery("alter sequence hs_office.contact_legacy_id_seq restart with 1000000000;").executeUpdate();
|
em.createNativeQuery("alter sequence hs_office.contact_legacy_id_seq restart with 1000000000;").executeUpdate();
|
||||||
em.createNativeQuery("alter sequence hs_office.coopassettx_legacy_id_seq restart with 1000000000;")
|
em.createNativeQuery("alter sequence hs_office.coopassettx_legacy_id_seq restart with 1000000000;")
|
||||||
.executeUpdate();
|
.executeUpdate();
|
||||||
em.createNativeQuery("alter sequence public.hs_office.coopsharestransaction_legacy_id_seq restart with 1000000000;")
|
em.createNativeQuery("alter sequence public.hs_office.coopsharetx_legacy_id_seq restart with 1000000000;")
|
||||||
.executeUpdate();
|
.executeUpdate();
|
||||||
em.createNativeQuery("alter sequence public.hs_office.partner_legacy_id_seq restart with 1000000000;")
|
em.createNativeQuery("alter sequence public.hs_office.partner_legacy_id_seq restart with 1000000000;")
|
||||||
.executeUpdate();
|
.executeUpdate();
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user