diff --git a/Jenkinsfile b/Jenkinsfile index 22323c7f5d6d196b0fb2e09f53d260dcefc37e71..2d2b8428ddba5668d101555dc3aae8ca1a19c026 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -78,11 +78,11 @@ pipeline { } } } -// post { -// always{ -// junit testResults: 'alfa-client/test-report.xml', skipPublishingChecks: true -// } -// } + // post { + // always{ + // junit testResults: 'alfa-client/test-report.xml', skipPublishingChecks: true + // } + // } } stage('Build and push client container') { @@ -144,6 +144,11 @@ pipeline { sh 'mvn --no-transfer-progress -s $MAVEN_SETTINGS sonar:sonar' } } + dir('alfa-xdomea'){ + withSonarQubeEnv('sonarqube-ozg-sh'){ + sh 'mvn --no-transfer-progress -s $MAVEN_SETTINGS sonar:sonar' + } + } } catch (Exception e) { unstable("SonarQube failed") @@ -192,7 +197,7 @@ pipeline { } } - stage('Test, build and deploy Helm Chart') { + stage('Test, build and deploy Alfa Helm Chart') { steps { script { FAILED_STAGE=env.STAGE_NAME @@ -204,7 +209,27 @@ pipeline { sh "helm package --version=${HELM_CHART_VERSION} ." - deployHelmChart(HELM_CHART_VERSION) + deployHelmChart(HELM_CHART_VERSION, "alfa") + } + } + } + } + + stage('Test, build and deploy Alfa-Client Helm Chart') { + steps { + script { + dir('alfa-client') { + FAILED_STAGE=env.STAGE_NAME + HELM_CHART_VERSION = generateHelmChartVersion() + + sh "./run_helm_test.sh" + + dir('src/main/helm') { + + sh "helm package --version=${HELM_CHART_VERSION} ." + + deployHelmChart(HELM_CHART_VERSION, "alfa-client") + } } } } @@ -292,13 +317,13 @@ pipeline { } } -Void deployHelmChart(String helmChartVersion) { +Void deployHelmChart(String helmChartVersion, String app ) { withCredentials([usernamePassword(credentialsId: 'jenkins-nexus-login', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]){ if (isReleaseBranch()) { - result = sh script: '''curl -u $USERNAME:$PASSWORD https://nexus.ozg-sh.de/service/rest/v1/components?repository=ozg-base-apps -F file=@alfa-'''+helmChartVersion+'''.tgz''', returnStdout: true + result = sh script: '''curl -u $USERNAME:$PASSWORD https://nexus.ozg-sh.de/service/rest/v1/components?repository=ozg-base-apps -F file=@'''+app+'''-'''+helmChartVersion+'''.tgz''', returnStdout: true } else { - result = sh script: '''curl -u $USERNAME:$PASSWORD https://nexus.ozg-sh.de/service/rest/v1/components?repository=ozg-base-apps-snapshot -F file=@alfa-'''+helmChartVersion+'''.tgz''', returnStdout: true + result = sh script: '''curl -u $USERNAME:$PASSWORD https://nexus.ozg-sh.de/service/rest/v1/components?repository=ozg-base-apps-snapshot -F file=@'''+app+'''-'''+helmChartVersion+'''.tgz''', returnStdout: true } if (result != '') { @@ -398,6 +423,7 @@ String getElementAccessToken() { Void setNewDevVersion() { setNewGitopsVersion("dev") + } Void setNewTestVersion() { @@ -407,16 +433,20 @@ Void setNewTestVersion() { Void setNewGitopsVersion(String environment) { def envFile = "${environment}/application/values/alfa-values.yaml" def commitMessage = "jenkins rollout ${environment} alfa version ${IMAGE_TAG}"; - setNewGitopsVersion(envFile, commitMessage); + setNewAlfaGitopsVersion(envFile, commitMessage); + + envFile = "${environment}/application/values/alfa-client-values.yaml" + commitMessage = "jenkins rollout ${environment} alfa-client version ${IMAGE_TAG}"; + setNewAlfaClientGitopsVersion(envFile, commitMessage); } Void setNewBarrierefreiheitVersion() { def envFile = "dev/namespace/namespaces/by-barrierefreiheit-dev.yaml" def commitMessage = "jenkins rollout ${IMAGE_TAG} for Barrierefreiheit Dev" - setNewGitopsVersion(envFile, commitMessage); + setNewAlfaGitopsVersion(envFile, commitMessage); } -Void setNewGitopsVersion(String envFile, String commitMessage) { +Void setNewAlfaGitopsVersion(String envFile, String commitMessage) { dir("gitops") { def envVersions = readYaml file: envFile @@ -432,6 +462,22 @@ Void setNewGitopsVersion(String envFile, String commitMessage) { } } +Void setNewAlfaClientGitopsVersion(String envFile, String commitMessage) { + dir("gitops") { + def envVersions = readYaml file: envFile + + envVersions.alfa_client.image.tag = IMAGE_TAG + envVersions.alfa_client.helm.version = HELM_CHART_VERSION + + writeYaml file: envFile, data: envVersions, overwrite: true + + if (hasValuesFileChanged(envFile)) { + sh "git add ${envFile}" + sh "git commit -m '${commitMessage}'" + } + } +} + String getCommitHash() { return "-${env.GIT_COMMIT.take(7)}"; } diff --git a/alfa-client/apps/alfa-e2e/Jenkinsfile b/alfa-client/Jenkinsfile.e2e similarity index 69% rename from alfa-client/apps/alfa-e2e/Jenkinsfile rename to alfa-client/Jenkinsfile.e2e index 4d9192728334431b0219afb7c8ac6372cf9bdaab..9b55f66a5146de14b99bdb88d22821c906c2d13e 100644 --- a/alfa-client/apps/alfa-e2e/Jenkinsfile +++ b/alfa-client/Jenkinsfile.e2e @@ -23,7 +23,10 @@ pipeline { FAILED_PARALLEL_STAGE = " " EA_BEZEICHNER = generateBezeichner("e2e-ea") MAIN_BEZEICHNER = generateBezeichner("e2e-main") + ADMIN_BEZEICHNER = generateBezeichner("e2e-admin") SH_SUCCESS_STATUS_CODE = 0 + KEYCLOAK_CLIENT_ADMIN_APP = "admin" + KEYCLOAK_CLIENT_ALFA_APP = "alfa" } options { @@ -98,6 +101,7 @@ pipeline { script { FAILED_STAGE = env.STAGE_NAME + initEnvAdminDefaultVersions() initEnvAlfaDefaultVersions() initEnvVorgangManagerDefaultVersions() initEnvUserManagerDefaultVersions() @@ -122,6 +126,12 @@ pipeline { string(name: "AlfaImageTag", defaultValue: env.ALFA_IMAGE_TAG, trim: true), string(name: "AlfaHelmChartVersion", defaultValue: env.ALFA_HELM_CHART_VERSION, trim: true), string(name: "AlfaHelmRepoUrl", defaultValue: env.ALFA_HELM_REPO_URL, trim: true), + string(name: "AdministrationImageTag", defaultValue: env.ADMINISTRATION_IMAGE_TAG, trim: true), + string(name: "AdministrationHelmChartVersion", defaultValue: env.ADMINISTRATION_HELM_CHART_VERSION, trim: true), + string(name: "AdministrationHelmRepoUrl", defaultValue: env.ADMINISTRATION_HELM_REPO_URL, trim: true), + string(name: "AdminClientImageTag", defaultValue: env.ADMIN_CLIENT_IMAGE_TAG, trim: true), + string(name: "AdminClientHelmChartVersion", defaultValue: env.ADMIN_CLIENT_HELM_CHART_VERSION, trim: true), + string(name: "AdminClientHelmRepoUrl", defaultValue: env.ADMIN_CLIENT_HELM_REPO_URL, trim: true), string(name: "VorgangManagerImageTag", defaultValue: env.VORGANG_MANAGER_IMAGE_TAG, trim: true), string(name: "VorgangManagerHelmChartVersion", defaultValue: env.VORGANG_MANAGER_HELM_CHART_VERSION, trim: true), string(name: "VorgangManagerHelmRepoUrl", defaultValue: env.VORGANG_MANAGER_HELM_REPO_URL, trim: true), @@ -165,10 +175,9 @@ pipeline { checkoutGitopsE2eBranch() - deleteOzgCloudStack([env.EA_BEZEICHNER, env.MAIN_BEZEICHNER]) + deleteNamespaces([env.EA_BEZEICHNER, env.MAIN_BEZEICHNER, env.ADMIN_BEZEICHNER]) - generateMainNamespaceYaml() - generateEaNamespaceYaml() + generateNamespaces() pushGitopsRepo() } @@ -176,7 +185,7 @@ pipeline { post { failure { script { - deleteOzgCloudStack([env.EA_BEZEICHNER, env.MAIN_BEZEICHNER]) + deleteNamespaces([env.EA_BEZEICHNER, env.MAIN_BEZEICHNER, env.ADMIN_BEZEICHNER]) } } } @@ -211,13 +220,14 @@ pipeline { script { FAILED_STAGE = env.STAGE_NAME - waitForOzgCloudStackRollout([env.EA_BEZEICHNER, env.MAIN_BEZEICHNER]) + waitForAdminRollout(env.ADMIN_BEZEICHNER) + waitForAlfaRollout([env.EA_BEZEICHNER, env.MAIN_BEZEICHNER]) } } post { failure { script { - deleteOzgCloudStack([env.EA_BEZEICHNER, env.MAIN_BEZEICHNER]) + deleteNamespaces([env.EA_BEZEICHNER, env.MAIN_BEZEICHNER, env.ADMIN_BEZEICHNER]) } } } @@ -236,14 +246,14 @@ pipeline { } } -// stage('Run E2E-Tests') { -// when { -// expression { !SKIP_RUN } -// } -// failFast false + stage('Run E2E-Tests') { + when { + expression { !SKIP_RUN } + } + failFast false -// parallel { - stage('E2E-EA') { + parallel { + stage('E2E-Alfa-EA') { when { expression { !SKIP_RUN } } @@ -254,7 +264,7 @@ pipeline { Integer mongoDbPort = forwardMongoDbPort(generateNamespace(bezeichner)) - runTests(bezeichner, 'einheitlicher-ansprechpartner', mongoDbPort, env.STAGE_NAME) + runTests(bezeichner, 'alfa-e2e', 'einheitlicher-ansprechpartner', env.KEYCLOAK_CLIENT_ALFA_APP, mongoDbPort, env.STAGE_NAME) stopForwardMongoDbPort(generateNamespace(bezeichner)) } @@ -268,13 +278,13 @@ pipeline { } always { script { - publishE2ETestResult("einheitlicher-ansprechpartner", "Alfa E2E-Tests EA") + publishAlfaE2ETestResult("einheitlicher-ansprechpartner", "Alfa E2E-Tests EA") } } } } - stage('E2E-Main') { + stage('E2E-Alfa-Main') { when { expression { !SKIP_RUN } } @@ -285,7 +295,7 @@ pipeline { Integer mongoDbPort = forwardMongoDbPort(generateNamespace(bezeichner)) - runTests(bezeichner, 'main-tests', mongoDbPort, env.STAGE_NAME) + runTests(bezeichner, 'alfa-e2e', 'main-tests', env.KEYCLOAK_CLIENT_ALFA_APP, mongoDbPort, env.STAGE_NAME) stopForwardMongoDbPort(generateNamespace(bezeichner)) } @@ -299,13 +309,43 @@ pipeline { } always { script { - publishE2ETestResult("main-tests", "Alfa E2E-Tests main") + publishAlfaE2ETestResult("main-tests", "Alfa E2E-Tests main") } } } } -// } -// } + stage('E2E-Admin-Main') { + when { + expression { !SKIP_RUN } + } + steps { + catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') { + script { + String bezeichner = env.ADMIN_BEZEICHNER + + Integer mongoDbPort = forwardMongoDbPort(generateNamespace(bezeichner)) + + runTests(bezeichner, 'admin-e2e', 'main-tests', env.KEYCLOAK_CLIENT_ADMIN_APP, mongoDbPort, env.STAGE_NAME) + + stopForwardMongoDbPort(generateNamespace(bezeichner)) + } + } + } + post { + failure { + script { + FAILED_PARALLEL_STAGE += "${env.STAGE_NAME} " + } + } + always { + script { + publishAdminE2ETestResult() + } + } + } + } + } + } stage('Delete E2E Namespaces') { when { @@ -315,7 +355,7 @@ pipeline { script { FAILED_STAGE = env.STAGE_NAME - deleteOzgCloudStack([env.EA_BEZEICHNER, env.MAIN_BEZEICHNER]) + deleteNamespaces([env.EA_BEZEICHNER, env.MAIN_BEZEICHNER, env.ADMIN_BEZEICHNER]) } } } @@ -376,21 +416,6 @@ String getHelmChartVersion(Map applicationValues) { return applicationValues.helm.version } -Void initEnvAlfaDefaultVersions() { - if (isMasterBranch() || isReleaseBranch()) { - values = getApplicationValues('alfa') - - env.ALFA_IMAGE_TAG = getImageTag(values) - env.ALFA_HELM_CHART_VERSION = getHelmChartVersion(values) - } - else { - env.ALFA_IMAGE_TAG = getFeatureBranchImageTag() - env.ALFA_HELM_CHART_VERSION = getFeatureBranchHelmChartVersion() - } - - env.ALFA_HELM_REPO_URL = getHelmRepoUrl() -} - Boolean isMasterBranch() { return env.BRANCH_NAME == 'master' } @@ -417,6 +442,33 @@ String getRootPomVersion() { return rootPom.version } +Void initEnvAdminDefaultVersions() { + def values = getApplicationValues('administration') + env.ADMINISTRATION_IMAGE_TAG = getImageTag(values) + env.ADMINISTRATION_HELM_CHART_VERSION = getHelmChartVersion(values) + env.ADMINISTRATION_HELM_REPO_URL = getHelmRepoUrl() + + values = getApplicationValues('admin-client') + env.ADMIN_CLIENT_IMAGE_TAG = getImageTag(values) + env.ADMIN_CLIENT_HELM_CHART_VERSION = getHelmChartVersion(values) + env.ADMIN_CLIENT_HELM_REPO_URL = getHelmRepoUrl() +} + +Void initEnvAlfaDefaultVersions() { + if (isMasterBranch() || isReleaseBranch()) { + values = getApplicationValues('alfa') + + env.ALFA_IMAGE_TAG = getImageTag(values) + env.ALFA_HELM_CHART_VERSION = getHelmChartVersion(values) + } + else { + env.ALFA_IMAGE_TAG = getFeatureBranchImageTag() + env.ALFA_HELM_CHART_VERSION = getFeatureBranchHelmChartVersion() + } + + env.ALFA_HELM_REPO_URL = getHelmRepoUrl() +} + Void initEnvVorgangManagerDefaultVersions() { def values = getApplicationValues('vorgang-manager') @@ -437,6 +489,12 @@ Void initEnvUserVersions(userVersions) { env.ALFA_IMAGE_TAG = userVersions.AlfaImageTag env.ALFA_HELM_CHART_VERSION = userVersions.AlfaHelmChartVersion env.ALFA_HELM_REPO_URL = userVersions.AlfaHelmRepoUrl + env.ADMINISTRATION_IMAGE_TAG = userVersions.AdministrationImageTag + env.ADMINISTRATION_HELM_CHART_VERSION = userVersions.AdministrationHelmChartVersion + env.ADMINISTRATION_HELM_REPO_URL = userVersions.AdministrationHelmRepoUrl + env.ADMIN_CLIENT_IMAGE_TAG = userVersions.AdminClientImageTag + env.ADMIN_CLIENT_HELM_CHART_VERSION = userVersions.AdminClientHelmChartVersion + env.ADMIN_CLIENT_HELM_REPO_URL = userVersions.AdminClientHelmRepoUrl env.VORGANG_MANAGER_IMAGE_TAG = userVersions.VorgangManagerImageTag env.VORGANG_MANAGER_HELM_CHART_VERSION = userVersions.VorgangManagerHelmChartVersion env.VORGANG_MANAGER_HELM_REPO_URL = userVersions.VorgangManagerHelmRepoUrl @@ -468,15 +526,43 @@ Void checkoutGitopsE2eBranch() { } } -Void generateEaNamespaceYaml() { - generateNamespaceYaml(env.EA_BEZEICHNER, "by-ea-dev.yaml"); +Void generateNamespaces() { + def y1 = generateAdminNamespaceYaml() + def y2 = generateEaNamespaceYaml() + def y3 = generateMainNamespaceYaml() + + dir("gitops") { + sh "git add ${y1} ${y2} ${y3}" + sh "git commit -m 'add e2e namespaces for testrun'" + } + +} + +Void generateAdminNamespaceYaml() { + def bezeichner = env.ADMIN_BEZEICHNER + def envValues + dir("alfa-client/apps/admin-e2e/") { + envValues = readYaml file: "src/fixtures/argocd/by-admin-dev.yaml"; + + envValues.ozgcloud.bezeichner = bezeichner + envValues.administration.put("image", ['tag': env.ADMINISTRATION_IMAGE_TAG]) + envValues.administration.put("helm", ['version': env.ADMINISTRATION_HELM_CHART_VERSION, 'repoUrl': env.ADMINISTRATION_HELM_REPO_URL]) + + envValues.admin_client.put("image", ['tag': env.ADMIN_CLIENT_IMAGE_TAG]) + envValues.admin_client.put("helm", ['version': env.ADMIN_CLIENT_HELM_CHART_VERSION, 'repoUrl': env.ADMIN_CLIENT_HELM_REPO_URL]) + } + return writeYamlToGitOps(bezeichner, envValues); +} + +String generateEaNamespaceYaml() { + return generateNamespaceYaml(env.EA_BEZEICHNER, "by-ea-dev.yaml"); } -Void generateMainNamespaceYaml() { - generateNamespaceYaml(env.MAIN_BEZEICHNER, "by-main-dev.yaml"); +String generateMainNamespaceYaml() { + return generateNamespaceYaml(env.MAIN_BEZEICHNER, "by-main-dev.yaml"); } -Void generateNamespaceYaml(String bezeichner, String valuesPathSuffix) { +String generateNamespaceYaml(String bezeichner, String valuesPathSuffix) { def envValues dir('alfa-client/apps/alfa-e2e/') { envValues = readYaml file: "src/fixtures/argocd/" + valuesPathSuffix; @@ -491,18 +577,20 @@ Void generateNamespaceYaml(String bezeichner, String valuesPathSuffix) { envValues.user_manager.put("image", ['tag': env.USER_MANAGER_IMAGE_TAG]) envValues.user_manager.put("helm", ['version': env.USER_MANAGER_HELM_CHART_VERSION, 'repoUrl': env.USER_MANAGER_HELM_REPO_URL]) } + return writeYamlToGitOps(bezeichner, envValues); +} - writeYaml file: "gitops/dev/namespace/namespaces/by-${bezeichner}-dev.yaml", data: envValues, overwrite: true +String writeYamlToGitOps(String bezeichner, Object envValues){ + def bezeichnerYaml = "dev/namespace/namespaces/by-${bezeichner}-dev.yaml" - sh "cat gitops/dev/namespace/namespaces/by-${bezeichner}-dev.yaml" + writeYaml file: "gitops/${bezeichnerYaml}", data: envValues, overwrite: true - dir("gitops") { - sh "git add dev/namespace/namespaces/by-${bezeichner}-dev.yaml" - sh "git commit -m 'add e2e by-${bezeichner}-dev'" - } + sh "cat gitops/${bezeichnerYaml}" + + return bezeichnerYaml; } -Void deleteOzgCloudStack(ozgCloudBezeichner) { +Void deleteNamespaces(ozgCloudBezeichner) { for(bezeichner in ozgCloudBezeichner) { if (hasNamespaceFile(bezeichner)) { removeNamespaceFile(bezeichner) @@ -536,13 +624,19 @@ Void waitForDeletion(String bezeichner) { } } -Void waitForOzgCloudStackRollout(ozgCloudBezeichner) { +Void waitForAlfaRollout(ozgCloudBezeichner) { for(bezeichner in ozgCloudBezeichner) { - waitForRollout(bezeichner) + waitForAlfaRollout(bezeichner) } } -Void waitForRollout(String bezeichner) { +Void waitForAdminRollout(String bezeichner) { + waitForAlfaRollout([bezeichner]) + waitForHealthyApplication(bezeichner, 'administration') + waitForHealthyApplication(bezeichner, 'admin-client') +} + +Void waitForAlfaRollout(String bezeichner) { waitForHealthyApplication(bezeichner, 'application') waitForHealthyApplication(bezeichner, 'vorgang-manager') waitForHealthyApplication(bezeichner, 'user-manager') @@ -580,32 +674,41 @@ Void waitForHealthyStatus(String bezeichner, String application) { sh "kubectl wait --for=jsonpath='{.status.health.status}'=Healthy applications/by-${bezeichner}-dev-${application} -n argocd --timeout=900s" } -Void publishE2ETestResult(String reportFolder, String reportName) { - publishHTML ( - target: [ - allowMissing: false, - alwaysLinkToLastBuild: false, - keepAll: true, - reportDir: "alfa-client/apps/alfa-e2e/reports/${reportFolder}", - reportFiles: 'report.html', - reportName: reportName - ] - ) +Void publishAlfaE2ETestResult(String appVariant, String reportName) { + publishE2ETestResult("alfa-e2e", appVariant, reportName); } -String runTests(String bezeichner, String reportFolder, Integer dbPort, String stageName) { - def config = generateCypressConfig(bezeichner, reportFolder, dbPort) +Void publishAdminE2ETestResult() { + publishE2ETestResult("admin-e2e", "main-tests", "Admin E2E-Tests main"); +} - try { - dir('alfa-client'){ - sh "npm run cypress:version" - sh "apps/alfa-e2e/run-tests.sh ${reportFolder} ${config}" - } - } catch (Exception e) { - printNpmDebugLog() +Void publishE2ETestResult(String appName, String appVariant, String reportName) { + def reportDir = "alfa-client/apps/"+appName+"/reports/"+appVariant; - error("Fehler in Stage ${stageName}") + publishHTML ( + target: [ + allowMissing: false, + alwaysLinkToLastBuild: false, + keepAll: true, + reportDir: reportDir, + reportFiles: 'report.html', + reportName: reportName + ] + ) +} + +String runTests(String bezeichner, String appName, String appVariant, String keycloakClientName, Integer dbPort, String stageName) { + def config = generateCypressConfig(bezeichner, appName, appVariant, keycloakClientName, dbPort) + try { + dir('alfa-client'){ + sh "npm run cypress:version" + sh "apps/run-tests.sh ${appName} ${appVariant} ${config}" } + } catch (Exception e) { + printNpmDebugLog() + + error("Fehler in Stage ${stageName}") + } } Void printNpmDebugLog() { @@ -636,39 +739,49 @@ String cutBranchNameForKeycloakRealm(String branchName, String stageName) { return branchName.take(cutBranchNamePosition) } -String generateCypressConfig(String bezeichner, String testFolder, Integer dbPort) { - def namespace = generateNamespace(bezeichner) - def configName = "cypress-ci-"+testFolder+".json" +String generateCypressConfig(String bezeichner, String appName, String appVariant, String keycloakClientName, Integer dbPort) { + def namespace = generateNamespace(bezeichner) + def configName = "cypress-ci-"+appVariant+".json" - dir('alfa-client/apps/alfa-e2e/'){ - def config = readJSON file: 'cypress-ci.json' + dir("alfa-client/apps/${appName}/"){ + def config = readJSON file: 'cypress-ci.json' - def vorgangManagerDatabaseSecret = getVorgangManagerDatabaseSecret(namespace); - def decodedPassword = decodeString(vorgangManagerDatabaseSecret.password); - def parsablePassword = makePasswordUrlConform(decodedPassword); + def vorgangManagerDatabaseSecret = getVorgangManagerDatabaseSecret(namespace); + def decodedPassword = decodeString(vorgangManagerDatabaseSecret.password); + def parsablePassword = makePasswordUrlConform(decodedPassword); - config.baseUrl = "https://${bezeichner}.${env.CLUSTER_BASE_URL}" as String - config.env.dbUrl = "mongodb://${decodeString(vorgangManagerDatabaseSecret.username)}:${parsablePassword}@localhost:${dbPort}/admin?ssl=false&directConnection=true&socketTimeoutMS=30000&heartbeatFrequencyMS=10000" as String - config.env.keycloakUrl = "https://${env.SSO_URL}/" as String - config.env.keycloakRealm = namespace as String - config.videosFolder = "./reports/${testFolder}/videos" as String - config.screenshotsFolder = "./reports/${testFolder}/screenshots" as String - config.reporterOptions.reportDir = "./reports/${testFolder}/mochawesome-report" as String + config.baseUrl = "https://${generateUrlBezeichner(bezeichner, appName)}.${env.CLUSTER_BASE_URL}" as String + config.env.dbUrl = "mongodb://${decodeString(vorgangManagerDatabaseSecret.username)}:${parsablePassword}@localhost:${dbPort}/admin?ssl=false&directConnection=true&socketTimeoutMS=30000&heartbeatFrequencyMS=10000" as String + config.env.keycloakUrl = "https://${env.SSO_URL}/" as String + config.env.keycloakRealm = namespace as String + config.env.keycloakClient = keycloakClientName as String + config.videosFolder = "./reports/${appVariant}/videos" as String + config.screenshotsFolder = "./reports/${appVariant}/screenshots" as String + config.reporterOptions.reportDir = "./reports/${appVariant}/mochawesome-report" as String - config.specPattern = "src/e2e/${testFolder}/**/*.cy.{js,jsx,ts,tsx}" as String + config.specPattern = "src/e2e/${appVariant}/**/*.cy.{js,jsx,ts,tsx}" as String - config.env.put("search", getElasticsearchEnv(namespace)) - config.env.put("userManager", getUserManagerEnv(namespace, dbPort)) - config.env.put("smocker", getSmockerEnv(namespace)) + config.env.put("search", getElasticsearchEnv(namespace)) + config.env.put("userManager", getUserManagerEnv(namespace, dbPort)) + config.env.put("smocker", getSmockerEnv(namespace)) - writeJSON file: configName, json: config + writeJSON file: configName, json: config - sh "cat ${configName}" - } + sh "cat ${configName}" + } - return "cypress-ci-"+testFolder+".config.ts" + return "cypress-ci-"+appVariant+".config.ts" } +String generateUrlBezeichner(String bezeichner, String appName){ + if(appName == 'admin-e2e'){ + return "${bezeichner}-admin"; + } + return bezeichner; +} + + + String makePasswordUrlConform(String password) { return sh (script: "printf %s ${password} | jq -sRr @uri", returnStdout: true); } @@ -793,7 +906,7 @@ String generateNamespace(String bezeichner) { } String decodeString(String encoded) { - return sh (script: "echo -n ${encoded} | base64 --decode", returnStdout: true) + return sh (script: "echo -n ${encoded} | base64 --decode", returnStdout: true) } Map getElasticsearchSecret(String namespace) { diff --git a/alfa-client/apps/alfa-e2e/Jenkinsfile-static b/alfa-client/Jenkinsfile.e2e.static similarity index 99% rename from alfa-client/apps/alfa-e2e/Jenkinsfile-static rename to alfa-client/Jenkinsfile.e2e.static index 49a92dd823cb02a53f072fa3a55f21facc3c6527..2e499f9abbaf8c2918628b462f2f79a056df66d6 100644 --- a/alfa-client/apps/alfa-e2e/Jenkinsfile-static +++ b/alfa-client/Jenkinsfile.e2e.static @@ -16,7 +16,7 @@ pipeline { environment { BLUE_OCEAN_URL = "https://jenkins.ozg-sh.de/job/E2E%20Tests/job/${env.BRANCH_NAME}/${env.BUILD_NUMBER}/" BUNDESLAND = 'by' - ENVIRONMENT = 'dev' + ENVIRONMENT = 'dev' SSO_URL = 'sso.dev.by.ozg-cloud.de' CLUSTER_BASE_URL = 'dev.by.ozg-cloud.de' FAILED_STAGE = '' @@ -552,7 +552,7 @@ String generateNamespace(String bezeichner) { } String decodeString(String encoded) { - return sh(script: "echo -n ${encoded} | base64 --decode", returnStdout: true) + return sh(script: "echo -n ${encoded} | base64 --decode", returnStdout: true) } Map getElasticsearchSecret(String namespace) { diff --git a/alfa-client/apps/admin-e2e/README.md b/alfa-client/apps/admin-e2e/README.md new file mode 100644 index 0000000000000000000000000000000000000000..cc1f1c46a2e2c7c034d661d9595990bbd606b370 --- /dev/null +++ b/alfa-client/apps/admin-e2e/README.md @@ -0,0 +1,9 @@ +## Allgemein + +Dieses Teilprojekt enthält die End-2-End Tests für die Admin-Anwendung. + +Der Aufbau ist analog der [E2E-Tests für Alfa](../alfa-e2e/README.md). + +Bei Ausführung mit Jenkins im Cluster wird das [Jenkinsfile.e2e](../../Jenkinsfile.e2e) verwendet. + +Bei lokaler Ausführung die hier abgelegte [docker-compose.yml](docker-compose.yml) verwenden. diff --git a/alfa-client/apps/admin-e2e/cypress-ci-main-tests.config.ts b/alfa-client/apps/admin-e2e/cypress-ci-main-tests.config.ts new file mode 100644 index 0000000000000000000000000000000000000000..debc5e3e19864e0afbd6b3376b24aec1be23d3c4 --- /dev/null +++ b/alfa-client/apps/admin-e2e/cypress-ci-main-tests.config.ts @@ -0,0 +1,25 @@ +import { nxE2EPreset } from '@nx/cypress/plugins/cypress-preset'; +import { defineConfig } from 'cypress'; + +//Cypress config is generated by JenkinsFile +const cypressConfig = require('./cypress-ci-main-tests.json'); +const cypressEvents = require('./src/support/cypress-tasks.ts'); + +export default defineConfig({ + e2e: { + ...nxE2EPreset(__dirname), + ...cypressConfig, + setupNodeEvents(on, config) { + return cypressEvents(on, config); + }, + }, + retries: { + experimentalStrategy: 'detect-flake-and-pass-on-threshold', + experimentalOptions: { + maxRetries: 2, + passesRequired: 1, + }, + openMode: true, + runMode: true, + }, +}); diff --git a/alfa-client/apps/admin-e2e/cypress-ci.json b/alfa-client/apps/admin-e2e/cypress-ci.json new file mode 100644 index 0000000000000000000000000000000000000000..ca9f95c11d0896e1559b198fe1521e9f5c95b423 --- /dev/null +++ b/alfa-client/apps/admin-e2e/cypress-ci.json @@ -0,0 +1,22 @@ +{ + "env": { + "database": "vorgang-manager-database", + "keycloakClient": "admin" + }, + "fileServerFolder": ".", + "fixturesFolder": "./src/fixtures", + "modifyObstructiveCode": false, + "video": true, + "chromeWebSecurity": false, + "reporter": "../../node_modules/cypress-mochawesome-reporter", + "defaultCommandTimeout": 10000, + "supportFile": "./src/support/e2e.ts", + "testIsolation": false, + "reporterOptions": { + "html": false, + "json": true, + "quite": true, + "reportFilename": "report", + "overwrite": false + } +} diff --git a/alfa-client/apps/admin-e2e/cypress.config.json b/alfa-client/apps/admin-e2e/cypress.config.json index 136d40d4f8a967df5e477627ba6c81b37d58080d..7bab4470a97551fc92eee55d557dfd983d382fe3 100644 --- a/alfa-client/apps/admin-e2e/cypress.config.json +++ b/alfa-client/apps/admin-e2e/cypress.config.json @@ -19,7 +19,7 @@ "reporterOptions": { "html": false, "json": true, - "reportDir": "./reports/mochawesome-report", + "reportDir": "./reports/main-tests/mochawesome-report", "reportFilename": "report", "overwrite": true } diff --git a/alfa-client/apps/admin-e2e/src/components/benutzer/benutzer.e2e.component.ts b/alfa-client/apps/admin-e2e/src/components/benutzer/benutzer.e2e.component.ts index 474b719fef02f95377505bb0d34c85df693b46ae..5a67a4226ff7d7d4eda4f7d57a69fdca18bd4d72 100644 --- a/alfa-client/apps/admin-e2e/src/components/benutzer/benutzer.e2e.component.ts +++ b/alfa-client/apps/admin-e2e/src/components/benutzer/benutzer.e2e.component.ts @@ -1,8 +1,18 @@ +import 'cypress-real-events'; import { exist } from '../../support/cypress.util'; export class BenutzerE2EComponent { - private readonly benutzerHinzufuegenButton: string = 'add-user-button'; - private readonly userEntry: string = 'user-entry-'; + private readonly benutzerHinzufuegenButton: string = 'Add-user-button'; + private readonly userEntry: string = 'User-entry-'; + private readonly userVorname: string = 'Vorname-text-input'; + private readonly userNachname: string = 'Nachname-text-input'; + private readonly userBenutzername: string = 'Benutzername-text-input'; + private readonly userMail: string = 'E-Mail-text-input'; + private readonly addOEButton: string = 'Add-organisationseinheit-button'; + private readonly adminCheckbox: string = 'Admin-checkbox-editor'; + private readonly loeschenCheckbox: string = 'Loschen-checkbox-editor'; + private readonly userCheckbox: string = 'User-checkbox-editor'; + private readonly postCheckbox: string = 'Poststelle-checkbox-editor'; public getHinzufuegenButton(): Cypress.Chainable<Element> { return cy.getTestElement(this.benutzerHinzufuegenButton); @@ -22,4 +32,60 @@ export class BenutzerE2EComponent { exist(cy.contains(phrase)); }); } + + public getVornameInput(): Cypress.Chainable<Element> { + return cy.getTestElement(this.userVorname); + } + + public getNachnameInput(): Cypress.Chainable<Element> { + return cy.getTestElement(this.userNachname); + } + + public getBenutzernameInput(): Cypress.Chainable<Element> { + return cy.getTestElement(this.userBenutzername); + } + + public getMailInput(): Cypress.Chainable<Element> { + return cy.getTestElement(this.userMail); + } + + public getOEButton(): Cypress.Chainable<Element> { + return cy.getTestElement(this.addOEButton); + } + + public addOrganisationseinheit(): void { + this.getOEButton().click(); + } + + public getAdminCheckbox(): Cypress.Chainable<Element> { + return cy.getTestElement(this.adminCheckbox); + } + + public clickAdminCheckbox(): void { + this.getAdminCheckbox().click(); + } + + public getLoeschenCheckbox() { + return cy.getTestElement(this.loeschenCheckbox); + } + + public clickLoeschenCheckbox(): void { + this.getLoeschenCheckbox().click(); + } + + public getUserCheckbox(): Cypress.Chainable<Element> { + return cy.getTestElement(this.userCheckbox); + } + + public clickUserCheckbox(): void { + this.getUserCheckbox().click(); + } + + public getPostCheckbox(): Cypress.Chainable<Element> { + return cy.getTestElement(this.postCheckbox); + } + + public clickPostCheckbox(): void { + this.getPostCheckbox().click(); + } } diff --git a/alfa-client/apps/admin-e2e/src/components/buildinfo/buildinfo.e2e.component.ts b/alfa-client/apps/admin-e2e/src/components/buildinfo/buildinfo.e2e.component.ts index 5bede900428396575e45c322fe1357c7ac9d3a3a..e6521431d3c69f85ff9dfc9aa060605a0f38e349 100644 --- a/alfa-client/apps/admin-e2e/src/components/buildinfo/buildinfo.e2e.component.ts +++ b/alfa-client/apps/admin-e2e/src/components/buildinfo/buildinfo.e2e.component.ts @@ -1,9 +1,9 @@ export class BuildInfoE2EComponent { - private readonly locatorVersion: string = 'build-version'; + private readonly locatorBuildInfo: string = 'build-info'; private readonly locatorBuildTime: string = 'build-time'; - public getVersion() { - return cy.getTestElement(this.locatorVersion); + public getBuildInfo() { + return cy.getTestElement(this.locatorBuildInfo); } public getBuildTime() { diff --git a/alfa-client/apps/admin-e2e/src/e2e/app/buildinfo.cy.ts b/alfa-client/apps/admin-e2e/src/e2e/app/buildinfo.cy.ts deleted file mode 100644 index 9ba459c3402f408b6a1813da97d3a16d1df224a6..0000000000000000000000000000000000000000 --- a/alfa-client/apps/admin-e2e/src/e2e/app/buildinfo.cy.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { BuildInfoE2EComponent } from '../../components/buildinfo/buildinfo.e2e.component'; -import { HeaderE2EComponent } from '../../page-objects/header.po'; -import { MainPage } from '../../page-objects/main.po'; -import { exist } from '../../support/cypress.util'; -import { loginAsAriane } from '../../support/user-util'; - -describe('Buildinfo', () => { - const mainPage: MainPage = new MainPage(); - const header: HeaderE2EComponent = mainPage.getHeader(); - const buildInfo: BuildInfoE2EComponent = mainPage.getBuildInfo(); - - it('should login as Ariane', () => { - loginAsAriane(); - }); - - describe('get buildinfo', () => { - it('should show version', () => { - exist(buildInfo.getVersion()); - header.getCurrentUserProfile().logout(); - }); - }); -}); diff --git a/alfa-client/apps/admin-e2e/src/e2e/benutzer_rollen/benutzer_rollen.cy.ts b/alfa-client/apps/admin-e2e/src/e2e/benutzer_rollen/benutzer_rollen.cy.ts deleted file mode 100644 index 45b22031b07206ebfc1b7a5ce62c288c99f62e95..0000000000000000000000000000000000000000 --- a/alfa-client/apps/admin-e2e/src/e2e/benutzer_rollen/benutzer_rollen.cy.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { BenutzerE2EComponent } from '../../components/benutzer/benutzer.e2e.component'; -import { MainPage } from '../../page-objects/main.po'; -import { exist } from '../../support/cypress.util'; -import { loginAsAriane } from '../../support/user-util'; - -const mainPage: MainPage = new MainPage(); -const benutzerPage: BenutzerE2EComponent = new BenutzerE2EComponent(); -const role1: string = 'VERWALTUNG_USER'; -const role2: string = 'VERWALTUNG_LOESCHEN'; -const role3: string = 'VERWALTUNG_POSTSTELLE'; -const orga1: string = 'Ordnungsamt'; -const orga2: string = 'Landesamt für Denkmalpflege'; -const orga3: string = 'Wirtschaftsförderung'; -const orga_none: string = 'keine zuständige Stelle zugewiesen'; -const mail1: string = 'peter.von.der.post@ozg-sh.de'; - -describe('Benutzer und Rollen', () => { - before(() => { - loginAsAriane(); - }); - - it('should open Benutzer tab and show Hinzufuegen button', () => { - mainPage.clickBenutzerTab(); - - exist(benutzerPage.getHinzufuegenButton()); - }); - - it('should show users and attributes in table', () => { - exist(benutzerPage.getUserEntry('ariane')); - benutzerPage.stringExistsInUserEntry(role1, 'dorothea'); - benutzerPage.stringExistsInUserEntry(orga1, 'ludwig'); - benutzerPage.stringExistsInUserEntry(role1, 'zelda'); - benutzerPage.stringExistsInUserEntry(role2, 'zelda'); - benutzerPage.stringExistsInUserEntry(orga2, 'zelda'); - benutzerPage.stringExistsInUserEntry(orga3, 'zelda'); - benutzerPage.stringExistsInUserEntry(orga_none, 'adelheit'); - benutzerPage.stringExistsInUserEntry(mail1, 'peter'); - benutzerPage.stringExistsInUserEntry(role3, 'peter'); - }); -}); diff --git a/alfa-client/apps/admin-e2e/src/e2e/app/0-login-logout.cy.ts b/alfa-client/apps/admin-e2e/src/e2e/main-tests/app/0-login-logout.cy.ts similarity index 68% rename from alfa-client/apps/admin-e2e/src/e2e/app/0-login-logout.cy.ts rename to alfa-client/apps/admin-e2e/src/e2e/main-tests/app/0-login-logout.cy.ts index fc19b08d96e0a250e5fa64f323c0e44095458ab1..cbee0dcfa84f4ca39bc865b67cebb499194b7920 100644 --- a/alfa-client/apps/admin-e2e/src/e2e/app/0-login-logout.cy.ts +++ b/alfa-client/apps/admin-e2e/src/e2e/main-tests/app/0-login-logout.cy.ts @@ -1,8 +1,8 @@ -import { HeaderE2EComponent } from '../../page-objects/header.po'; -import { MainPage } from '../../page-objects/main.po'; -import { reload } from '../../support/cypress-helper'; -import { exist } from '../../support/cypress.util'; -import { loginByUi } from '../../support/user-util'; +import { HeaderE2EComponent } from '../../../page-objects/header.po'; +import { MainPage } from '../../../page-objects/main.po'; +import { reload } from '../../../support/cypress-helper'; +import { exist } from '../../../support/cypress.util'; +import { loginByUi } from '../../../support/user-util'; describe('Login and Logout', () => { const mainPage: MainPage = new MainPage(); diff --git a/alfa-client/apps/admin-e2e/src/e2e/main-tests/app/buildinfo.cy.ts b/alfa-client/apps/admin-e2e/src/e2e/main-tests/app/buildinfo.cy.ts new file mode 100644 index 0000000000000000000000000000000000000000..aa93008afd7b2a61765af4cfc88fc712fe691dec --- /dev/null +++ b/alfa-client/apps/admin-e2e/src/e2e/main-tests/app/buildinfo.cy.ts @@ -0,0 +1,22 @@ +import { BuildInfoE2EComponent } from '../../../components/buildinfo/buildinfo.e2e.component'; +import { HeaderE2EComponent } from '../../../page-objects/header.po'; +import { MainPage } from '../../../page-objects/main.po'; +import { exist } from '../../../support/cypress.util'; +import { loginAsAriane } from '../../../support/user-util'; + +describe('Buildinfo', () => { + const mainPage: MainPage = new MainPage(); + const header: HeaderE2EComponent = mainPage.getHeader(); + const buildInfo: BuildInfoE2EComponent = mainPage.getBuildInfo(); + + it('should login as Ariane', () => { + loginAsAriane(); + }); + + describe('get buildinfo', () => { + it('should show build info', () => { + exist(buildInfo.getBuildInfo()); + header.getCurrentUserProfile().logout(); + }); + }); +}); diff --git a/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer_rollen.cy.ts b/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer_rollen.cy.ts new file mode 100644 index 0000000000000000000000000000000000000000..df8ad2a80810e40567c1788ce9d2af63ed96e912 --- /dev/null +++ b/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer_rollen.cy.ts @@ -0,0 +1,101 @@ +import { BenutzerE2EComponent } from '../../components/benutzer/benutzer.e2e.component'; +import { MainPage } from '../../page-objects/main.po'; +import { beChecked, beEnabled, exist, notBeChecked, notBeEnabled } from '../../support/cypress.util'; +import { loginAsAriane } from '../../support/user-util'; + +const mainPage: MainPage = new MainPage(); +const benutzerPage: BenutzerE2EComponent = new BenutzerE2EComponent(); +const role1: string = 'VERWALTUNG_USER'; +const role2: string = 'VERWALTUNG_LOESCHEN'; +const role3: string = 'VERWALTUNG_POSTSTELLE'; +const orga1: string = 'Ordnungsamt'; +const orga2: string = 'Denkmalpflege'; +const orga3: string = 'Wirtschaftsförderung'; +const orga_none: string = 'keine zuständige Stelle zugewiesen'; +const mail1: string = 'peter.von.der.post@ozg-sh.de'; + +describe('Benutzer und Rollen', () => { + before(() => { + loginAsAriane(); + }); + + it('should open Benutzer tab and show Hinzufuegen button', () => { + mainPage.clickBenutzerTab(); + + exist(benutzerPage.getHinzufuegenButton()); + }); + + it('should show users and attributes in table', () => { + exist(benutzerPage.getUserEntry('ariane')); + benutzerPage.stringExistsInUserEntry(role1, 'dorothea'); + benutzerPage.stringExistsInUserEntry(orga1, 'ludwig'); + benutzerPage.stringExistsInUserEntry(role1, 'zelda'); + benutzerPage.stringExistsInUserEntry(role2, 'zelda'); + benutzerPage.stringExistsInUserEntry(orga2, 'zelda'); + benutzerPage.stringExistsInUserEntry(orga3, 'zelda'); + benutzerPage.stringExistsInUserEntry(orga_none, 'adelheit'); + benutzerPage.stringExistsInUserEntry(mail1, 'peter'); + benutzerPage.stringExistsInUserEntry(role3, 'peter'); + }); + + it('should show single user screen on click', () => { + benutzerPage.addUser(); + + exist(benutzerPage.getVornameInput()); + exist(benutzerPage.getNachnameInput()); + exist(benutzerPage.getBenutzernameInput()); + exist(benutzerPage.getMailInput()); + + notBeChecked(benutzerPage.getAdminCheckbox()); + notBeChecked(benutzerPage.getLoeschenCheckbox()); + notBeChecked(benutzerPage.getUserCheckbox()); + notBeChecked(benutzerPage.getPostCheckbox()); + }); + + it('should activate loeschen checkbox and deactivate the other two checkboxes', () => { + benutzerPage.clickLoeschenCheckbox(); + beChecked(benutzerPage.getLoeschenCheckbox()); + notBeEnabled(benutzerPage.getUserCheckbox()); + notBeEnabled(benutzerPage.getPostCheckbox()); + + benutzerPage.clickLoeschenCheckbox(); + notBeChecked(benutzerPage.getLoeschenCheckbox()); + beEnabled(benutzerPage.getUserCheckbox()); + beEnabled(benutzerPage.getPostCheckbox()); + }); + + it('should additionally activate and deactivate admin checkbox', () => { + benutzerPage.clickLoeschenCheckbox(); + benutzerPage.clickAdminCheckbox(); + beChecked(benutzerPage.getLoeschenCheckbox()); + beChecked(benutzerPage.getAdminCheckbox()); + + benutzerPage.clickAdminCheckbox(); + notBeChecked(benutzerPage.getAdminCheckbox()); + }); + + it('should activate user checkbox and deactivate the other two checkboxes', () => { + benutzerPage.clickLoeschenCheckbox(); + benutzerPage.clickUserCheckbox(); + beChecked(benutzerPage.getUserCheckbox()); + notBeEnabled(benutzerPage.getLoeschenCheckbox()); + notBeEnabled(benutzerPage.getPostCheckbox()); + + benutzerPage.clickUserCheckbox(); + notBeChecked(benutzerPage.getUserCheckbox()); + beEnabled(benutzerPage.getLoeschenCheckbox()); + beEnabled(benutzerPage.getPostCheckbox()); + }); + + it('should activate post checkbox and deactivate the other two checkboxes', () => { + benutzerPage.clickPostCheckbox(); + beChecked(benutzerPage.getPostCheckbox()); + notBeEnabled(benutzerPage.getLoeschenCheckbox()); + notBeEnabled(benutzerPage.getUserCheckbox()); + + benutzerPage.clickPostCheckbox(); + notBeChecked(benutzerPage.getPostCheckbox()); + beEnabled(benutzerPage.getLoeschenCheckbox()); + beEnabled(benutzerPage.getUserCheckbox()); + }); +}); diff --git a/alfa-client/apps/admin-e2e/src/e2e/postfach/signatur.cy.ts b/alfa-client/apps/admin-e2e/src/e2e/main-tests/postfach/signatur.cy.ts similarity index 63% rename from alfa-client/apps/admin-e2e/src/e2e/postfach/signatur.cy.ts rename to alfa-client/apps/admin-e2e/src/e2e/main-tests/postfach/signatur.cy.ts index 1a9d07d9cd02a699d33ad6f24e3df8fb94d24d89..32323b02826811f53d7c617bf4558f870a1d29b4 100644 --- a/alfa-client/apps/admin-e2e/src/e2e/postfach/signatur.cy.ts +++ b/alfa-client/apps/admin-e2e/src/e2e/main-tests/postfach/signatur.cy.ts @@ -1,8 +1,8 @@ -import { PostfachE2EComponent } from '../../components/postfach/postfach.e2e.component'; -import { HeaderE2EComponent } from '../../page-objects/header.po'; -import { MainPage, waitForSpinnerToDisappear } from '../../page-objects/main.po'; -import { exist } from '../../support/cypress.util'; -import { loginAsAriane } from '../../support/user-util'; +import { PostfachE2EComponent } from '../../../components/postfach/postfach.e2e.component'; +import { HeaderE2EComponent } from '../../../page-objects/header.po'; +import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; +import { exist } from '../../../support/cypress.util'; +import { loginAsAriane } from '../../../support/user-util'; describe('Signatur', () => { const mainPage: MainPage = new MainPage(); @@ -15,7 +15,7 @@ describe('Signatur', () => { loginAsAriane(); }); - it('should clear current signature0', () => { + it('should clear current signature', () => { waitForSpinnerToDisappear(); exist(postfachTab.getSignaturText()); diff --git a/alfa-client/apps/admin-e2e/src/fixtures/argocd/by-admin-dev.yaml b/alfa-client/apps/admin-e2e/src/fixtures/argocd/by-admin-dev.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f307b1c0c8ff3aaf6d33b000ec7500a4e55ae065 --- /dev/null +++ b/alfa-client/apps/admin-e2e/src/fixtures/argocd/by-admin-dev.yaml @@ -0,0 +1,37 @@ +ozgcloud: + bezeichner: admine2emain + environment: dev +e2eTest: true +project: + destinations: + - namespace: "*" + server: https://kubernetes.default.svc + +administration: + enabled: true + +admin_client: + enabled: true + ingress: + use_staging_cert: true + +alfa: + env: + overrideSpringProfiles: "oc,e2e,dev" + ingress: + use_staging_cert: true + +vorgang_manager: + env: + overrideSpringProfiles: "oc,e2e,dev" + +user_manager: + ozgcloud: + usersync: + onstart: false + period: disabled + ingress: + use_staging_cert: true + +smocker: + enabled: false \ No newline at end of file diff --git a/alfa-client/apps/admin-e2e/src/page-objects/main.po.ts b/alfa-client/apps/admin-e2e/src/page-objects/main.po.ts index 14c867e8b121a71674c1ef602bf52b8a5234ed31..0d49928d6e5f08c470ff6489717098322ef970ef 100644 --- a/alfa-client/apps/admin-e2e/src/page-objects/main.po.ts +++ b/alfa-client/apps/admin-e2e/src/page-objects/main.po.ts @@ -4,8 +4,9 @@ import { HeaderE2EComponent } from './header.po'; export class MainPage { private readonly buildInfo: BuildInfoE2EComponent = new BuildInfoE2EComponent(); private readonly header: HeaderE2EComponent = new HeaderE2EComponent(); - private readonly benutzerTab: string = 'nav-item-Benutzer__Rollen'; - private readonly postfachTab: string = 'nav-item-Postfach'; + private readonly benutzerTab: string = 'caption-Benutzer__Rollen'; + private readonly postfachTab: string = 'caption-Postfach'; + private readonly organisationseinheitenTab: string = 'caption-Organisationseinheiten'; public getBuildInfo(): BuildInfoE2EComponent { return this.buildInfo; @@ -22,6 +23,14 @@ export class MainPage { public clickBenutzerTab(): void { this.getBenutzerTab().click(); } + + public getOrganisationseinheitenTab(): Cypress.Chainable<Element> { + return cy.getTestElement(this.organisationseinheitenTab); + } + + public clickOrganisationseinheitenTab(): void { + this.getOrganisationseinheitenTab().click(); + } } export function waitForSpinnerToDisappear(): boolean { diff --git a/alfa-client/apps/admin-e2e/src/support/cypress.util.ts b/alfa-client/apps/admin-e2e/src/support/cypress.util.ts index 9b68b3206ff29d0c3eab2ea3c9f292b4d776030d..4b45f922abb7e64be5329d03112af9769196c9fa 100644 --- a/alfa-client/apps/admin-e2e/src/support/cypress.util.ts +++ b/alfa-client/apps/admin-e2e/src/support/cypress.util.ts @@ -2,104 +2,104 @@ import { wait } from './cypress-helper'; //TODO Naming der Methoden geradeziehen -export function containClass(element: any, cssClass: string): void { +export function containClass(element: Cypress.Chainable<Element>, cssClass: string): void { element.should('have.class', cssClass); } -export function notContainClass(element: any, cssClass: string): void { +export function notContainClass(element: Cypress.Chainable<Element>, cssClass: string): void { element.should('not.have.class', cssClass); } -export function exist(element: any): void { +export function exist(element: Cypress.Chainable<Element>): void { element.should('exist'); } -export function notExist(element: any): void { +export function notExist(element: Cypress.Chainable<Element>): void { element.should('not.exist'); } -export function haveText(element: any, text: string): void { +export function haveText(element: Cypress.Chainable<Element>, text: string): void { element .invoke('text') .then((elementText) => elementText.trim()) .should('equal', text); } -export function haveValue(element: any, value: string): void { +export function haveValue(element: Cypress.Chainable<Element>, value: string): void { element.should('have.value', value); } -export function haveFocus(element: any): void { +export function haveFocus(element: Cypress.Chainable<Element>): void { element.should('have.focus'); } -export function mouseEnter(element: any): void { +export function mouseEnter(element: Cypress.Chainable<Element>): void { element.trigger('mouseenter'); } -export function mouseOver(element: any): void { +export function mouseOver(element: Cypress.Chainable<Element>): void { element.trigger('mouseover'); } -export function contains(element: any, containing: string): void { +export function contains(element: Cypress.Chainable<Element>, containing: string): void { element.should('exist').contains(containing); } -export function notContains(element: any, containing: string): void { +export function notContains(element: Cypress.Chainable<Element>, containing: string): void { element.contains(containing).should('not.exist'); } -export function haveLength(element: any, length: number): void { +export function haveLength(element: Cypress.Chainable<Element>, length: number): void { element.should('have.length', length); } -export function beChecked(element: any): void { +export function beChecked(element: Cypress.Chainable<Element>): void { element.should('be.checked'); } -export function notBeChecked(element: any): void { +export function notBeChecked(element: Cypress.Chainable<Element>): void { element.should('not.be.checked'); } +export function beEnabled(element: Cypress.Chainable<Element>): void { + element.should('be.enabled'); +} + +export function notBeEnabled(element: Cypress.Chainable<Element>): void { + element.should('not.be.enabled'); +} + //TODO: "first()" rausnehmen -> im html eine entprechende data-test-id ansprechen?! | trennen in "get" und "verify" -export function shouldFirstContains(element: any, containing: string) { +export function shouldFirstContains(element: Cypress.Chainable<Element>, containing: string) { element.first().should('exist').contains(containing); } -export function shouldHaveAttributeBeGreaterThan( - element: any, - attributeName: string, - value: number, -) { +export function shouldHaveAttributeBeGreaterThan(element: Cypress.Chainable<Element>, attributeName: string, value: number) { element.first().should('exist').invoke(attributeName).should('be.gt', value); } -export function shouldHaveAttributeBeLowerThan(element: any, attributeName: string, value: number) { +export function shouldHaveAttributeBeLowerThan(element: Cypress.Chainable<Element>, attributeName: string, value: number) { element.first().should('exist').invoke(attributeName).should('be.gt', value); } // -export function shouldHaveAttribute(element: any, name: string, value: string) { +export function shouldHaveAttribute(element: Cypress.Chainable<Element>, name: string, value: string) { element.should('have.attr', name, value); } -export function visible(element: any) { +export function visible(element: Cypress.Chainable<Element>) { element.should('be.visible'); } -export function notBeVisible(element: any) { +export function notBeVisible(element: Cypress.Chainable<Element>) { element.should('not.be.visible'); } -export function enter(element: any): void { +export function enter(element: Cypress.Chainable<Element>): void { element.clear().type(CypressKeyboardActions.ENTER); } -export function enterWith( - element: Cypress.Chainable<JQuery<HTMLElement>>, - value: string, - delayBeforeEnter: number = 200, -): void { +export function enterWith(element: Cypress.Chainable<JQuery<HTMLElement>>, value: string, delayBeforeEnter: number = 200): void { element.clear().type(value); wait(delayBeforeEnter); element.type(CypressKeyboardActions.ENTER); @@ -109,7 +109,7 @@ export function typeText(element: Cypress.Chainable<JQuery<HTMLElement>>, value: element.type(value); } -export function backspaceOn(element: any): void { +export function backspaceOn(element: Cypress.Chainable<Element>): void { element.type(CypressKeyboardActions.BACKSPACE); } diff --git a/alfa-client/apps/admin/project.json b/alfa-client/apps/admin/project.json index e113da51b11ba0f7afa5d2a0e194ba9aea7a1e82..a823b06f67d3c4bea4fa758699ea1583d1a00c68 100644 --- a/alfa-client/apps/admin/project.json +++ b/alfa-client/apps/admin/project.json @@ -8,24 +8,22 @@ "targets": { "build": { "executor": "@angular-devkit/build-angular:browser", - "outputs": [ - "{options.outputPath}" - ], + "outputs": ["{options.outputPath}"], "options": { "outputPath": "dist/apps/admin", "index": "apps/admin/src/index.html", "main": "apps/admin/src/main.ts", - "polyfills": [ - "zone.js" - ], + "polyfills": ["zone.js"], "tsConfig": "apps/admin/tsconfig.app.json", "assets": [ - "apps/admin/src/favicon.ico", - "apps/admin/src/assets" - ], - "styles": [ - "apps/admin/src/styles.scss" + "apps/admin/src/assets", + { + "input": "apps/admin/src/favicon", + "glob": "**/*", + "output": "" + } ], + "styles": ["apps/admin/src/styles.scss"], "scripts": [], "stylePreprocessorOptions": { "includePaths": [ @@ -87,15 +85,11 @@ }, "lint": { "executor": "@nx/eslint:lint", - "outputs": [ - "{options.outputFile}" - ] + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nx/jest:jest", - "outputs": [ - "{workspaceRoot}/coverage/{projectRoot}" - ], + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], "options": { "jestConfig": "apps/admin/jest.config.ts" } @@ -108,22 +102,16 @@ }, "container": { "executor": "@nx-tools/nx-container:build", - "dependsOn": [ - "build" - ], + "dependsOn": ["build"], "options": { "engine": "docker", "push": false, "metadata": { - "images": [ - "docker.ozg-sh.de/admin-client" - ], + "images": ["docker.ozg-sh.de/admin-client"], "load": true, - "tags": [ - "build-latest" - ] + "tags": ["build-latest"] } } } } -} \ No newline at end of file +} diff --git a/alfa-client/apps/admin/src/app/app.component.html b/alfa-client/apps/admin/src/app/app.component.html index f2b6f351107b9ad56a829832c750d7b9f6956033..9e3f549e41e574184c74dbba19273cf2693c4385 100644 --- a/alfa-client/apps/admin/src/app/app.component.html +++ b/alfa-client/apps/admin/src/app/app.component.html @@ -1,6 +1,6 @@ <ng-container *ngIf="(apiRootStateResource$ | async)?.resource as apiRoot"> <header - class="flex h-16 items-center justify-between border-b border-b-ozggray-300 bg-white px-9 py-2" + class="z-50 flex h-16 items-center justify-between border-b border-b-ozggray-300 bg-white px-9 py-2" data-test-id="admin-header" > <a @@ -37,6 +37,8 @@ <unavailable-page></unavailable-page> </ng-template> </main> + <section class="w-5"> + <alfa-build-info *ngIf="apiRoot" [apiRoot]="apiRoot" data-test-id="build-info" /> + </section> </div> - <footer data-test-id="build-version">Version: {{ apiRoot.version }}</footer> </ng-container> diff --git a/alfa-client/apps/admin/src/app/app.component.spec.ts b/alfa-client/apps/admin/src/app/app.component.spec.ts index fbf5f0baf5ba16a4c33e3140833521efb6e7a367..547e09233158c2f9343e0550a9345ff97ac3dab5 100644 --- a/alfa-client/apps/admin/src/app/app.component.spec.ts +++ b/alfa-client/apps/admin/src/app/app.component.spec.ts @@ -1,9 +1,6 @@ import { ApiRootLinkRel, ApiRootResource, ApiRootService } from '@alfa-client/api-root-shared'; -import { - HasLinkPipe, - createEmptyStateResource, - createStateResource, -} from '@alfa-client/tech-shared'; +import { BuildInfoComponent } from '@alfa-client/common'; +import { HasLinkPipe, createEmptyStateResource, createStateResource } from '@alfa-client/tech-shared'; import { Mock, dispatchEventFromFixture, @@ -13,7 +10,7 @@ import { notExistsAsHtmlElement, } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { Router, RouterOutlet } from '@angular/router'; +import { ActivatedRoute, Router, RouterOutlet } from '@angular/router'; import { AdminLogoIconComponent, MailboxIconComponent, @@ -36,7 +33,7 @@ describe('AppComponent', () => { let fixture: ComponentFixture<AppComponent>; const adminHeaderSelector: string = getDataTestIdOf('admin-header'); - const buildVersionSelector: string = getDataTestIdOf('build-version'); + const buildInfoSelector: string = getDataTestIdOf('build-info'); const userProfileButtonSelector: string = getDataTestIdOf('user-profile-button'); const navigationSelector: string = getDataTestIdOf('navigation'); const logoLink: string = getDataTestIdOf('logo-link'); @@ -48,6 +45,18 @@ describe('AppComponent', () => { }; const router: Mock<Router> = mock(Router); + const route: Mock<ActivatedRoute> = { + ...mock(ActivatedRoute), + snapshot: { + queryParams: { + iss: 'some-iss', + state: 'some-state', + session_state: 'some-session-state', + code: 'some-code', + }, + } as any, + }; + const apiRootService: Mock<ApiRootService> = mock(ApiRootService); beforeEach(async () => { @@ -62,6 +71,7 @@ describe('AppComponent', () => { MockComponent(UnavailablePageComponent), MockComponent(NavbarComponent), MockComponent(NavItemComponent), + MockComponent(BuildInfoComponent), HasLinkPipe, MockDirective(RouterOutlet), ], @@ -78,6 +88,10 @@ describe('AppComponent', () => { provide: Router, useValue: router, }, + { + provide: ActivatedRoute, + useValue: route, + }, ], }).compileComponents(); }); @@ -87,26 +101,28 @@ describe('AppComponent', () => { component = fixture.componentInstance; }); - it(`should have as title 'admin'`, () => { - const appTitle: string = fixture.componentInstance.title; + describe('component', () => { + it(`should have as title 'admin'`, () => { + const appTitle: string = fixture.componentInstance.title; - expect(appTitle).toEqual('admin'); - }); + expect(appTitle).toEqual('admin'); + }); - describe('ngOnInit', () => { - it('should call authService login', () => { - component.ngOnInit(); + describe('ngOnInit', () => { + it('should call authService login', () => { + component.ngOnInit(); - expect(authenticationService.login).toHaveBeenCalled(); - }); + expect(authenticationService.login).toHaveBeenCalled(); + }); - it('should call doAfterLoggedIn', async () => { - component.doAfterLoggedIn = jest.fn(); + it('should call doAfterLoggedIn', async () => { + component.doAfterLoggedIn = jest.fn(); - component.ngOnInit(); - await fixture.whenStable(); + component.ngOnInit(); + await fixture.whenStable(); - expect(component.doAfterLoggedIn).toHaveBeenCalled(); + expect(component.doAfterLoggedIn).toHaveBeenCalled(); + }); }); describe('do after logged in', () => { @@ -116,104 +132,109 @@ describe('AppComponent', () => { expect(apiRootService.getApiRoot).toHaveBeenCalled(); }); - it('should navigate to default route', () => { + it('should call forwardWithoutAuthenticationParams', () => { + component.forwardWithoutAuthenticationParams = jest.fn(); + component.doAfterLoggedIn(); - expect(router.navigate).toHaveBeenCalledWith(['/']); + expect(component.forwardWithoutAuthenticationParams).toHaveBeenCalled(); }); }); - }); - it('show not show header if apiRoot is not loaded', () => { - component.apiRootStateResource$ = of(createEmptyStateResource<ApiRootResource>()); + describe('forward without authentication params', () => { + it('should navigate to same route without authentication params', () => { + component.forwardWithoutAuthenticationParams(); - notExistsAsHtmlElement(fixture, adminHeaderSelector); + expect(router.navigate).toHaveBeenCalledWith([], { queryParams: {} }); + }); + }); }); - describe('user profile button', () => { - beforeEach(() => { - component.apiRootStateResource$ = of(createStateResource(createApiRootResource())); + describe('template', () => { + it('show not show header if apiRoot is not loaded', () => { + component.apiRootStateResource$ = of(createEmptyStateResource<ApiRootResource>()); + + notExistsAsHtmlElement(fixture, adminHeaderSelector); }); - it('should show if apiRoot exists', () => { - fixture.detectChanges(); + describe('user profile button', () => { + beforeEach(() => { + component.apiRootStateResource$ = of(createStateResource(createApiRootResource())); + }); + + it('should show if apiRoot exists', () => { + fixture.detectChanges(); - existsAsHtmlElement(fixture, userProfileButtonSelector); + existsAsHtmlElement(fixture, userProfileButtonSelector); + }); }); - }); - describe('administration logo', () => { - const apiResource: ApiRootResource = createApiRootResource(); + describe('administration logo', () => { + const apiResource: ApiRootResource = createApiRootResource(); - beforeEach(() => { - component.apiRootStateResource$ = of(createStateResource(apiResource)); - fixture.detectChanges(); - }); + beforeEach(() => { + component.apiRootStateResource$ = of(createStateResource(apiResource)); + fixture.detectChanges(); + }); - it('should navigate to start page on click', () => { - dispatchEventFromFixture(fixture, logoLink, 'click'); + it('should navigate to start page on click', () => { + dispatchEventFromFixture(fixture, logoLink, 'click'); - expect(router.navigate).toHaveBeenCalledWith(['/']); + expect(router.navigate).toHaveBeenCalledWith([], { queryParams: {} }); + }); }); - }); - describe('navigation', () => { - beforeEach(() => {}); - it('should show links if configuration link exists', () => { - component.apiRootStateResource$ = of( - createStateResource(createApiRootResource([ApiRootLinkRel.CONFIGURATION])), - ); - fixture.detectChanges(); + describe('navigation', () => { + it('should show links if configuration link exists', () => { + component.apiRootStateResource$ = of(createStateResource(createApiRootResource([ApiRootLinkRel.CONFIGURATION]))); + fixture.detectChanges(); - const navbarElement: HTMLElement = getElementFromFixture(fixture, navigationSelector); + const navbarElement: HTMLElement = getElementFromFixture(fixture, navigationSelector); - expect(navbarElement.children.length).toBeGreaterThan(0); - }); + expect(navbarElement.children.length).toBeGreaterThan(0); + }); - it('should not not show links if configuration resource not available', () => { - component.apiRootStateResource$ = of(createStateResource(createApiRootResource([]))); - fixture.detectChanges(); + it('should not not show links if configuration resource not available', () => { + component.apiRootStateResource$ = of(createStateResource(createApiRootResource([]))); + fixture.detectChanges(); - const navbarElement: HTMLElement = getElementFromFixture(fixture, navigationSelector); + const navbarElement: HTMLElement = getElementFromFixture(fixture, navigationSelector); - expect(navbarElement.children.length).toBe(0); + expect(navbarElement.children.length).toBe(0); + }); }); - }); - describe('build version', () => { - const apiResource: ApiRootResource = createApiRootResource(); - - beforeEach(() => { - component.apiRootStateResource$ = of(createStateResource(apiResource)); - }); + describe('build version', () => { + it('should not be rendered if api root not loaded', () => { + notExistsAsHtmlElement(fixture, buildInfoSelector); + }); - it('should show after apiRoot loaded', () => { - fixture.detectChanges(); + it('should show after apiRoot loaded', () => { + component.apiRootStateResource$ = of(createStateResource(createApiRootResource())); + fixture.detectChanges(); - const buildVersionElement = getElementFromFixture(fixture, buildVersionSelector); - expect(buildVersionElement.textContent.trim()).toEqual(`Version: ${apiResource.version}`); + existsAsHtmlElement(fixture, buildInfoSelector); + }); }); - }); - describe('router outlet', () => { - beforeEach(() => {}); + describe('router outlet', () => { + beforeEach(() => {}); - it('should exist if configuration resource available', () => { - component.apiRootStateResource$ = of( - createStateResource(createApiRootResource([ApiRootLinkRel.CONFIGURATION])), - ); + it('should exist if configuration resource available', () => { + component.apiRootStateResource$ = of(createStateResource(createApiRootResource([ApiRootLinkRel.CONFIGURATION]))); - fixture.detectChanges(); + fixture.detectChanges(); - existsAsHtmlElement(fixture, routerOutletSelector); - }); + existsAsHtmlElement(fixture, routerOutletSelector); + }); - it('should not exist if configuration resource not available', () => { - component.apiRootStateResource$ = of(createStateResource(createApiRootResource())); + it('should not exist if configuration resource not available', () => { + component.apiRootStateResource$ = of(createStateResource(createApiRootResource())); - fixture.detectChanges(); + fixture.detectChanges(); - notExistsAsHtmlElement(fixture, routerOutletSelector); + notExistsAsHtmlElement(fixture, routerOutletSelector); + }); }); }); }); diff --git a/alfa-client/apps/admin/src/app/app.component.ts b/alfa-client/apps/admin/src/app/app.component.ts index bccefbebc1e14ca084e18329ba7f604e28434731..e1d4c6d2a424c489756ec2966dde744126e360fa 100644 --- a/alfa-client/apps/admin/src/app/app.component.ts +++ b/alfa-client/apps/admin/src/app/app.component.ts @@ -1,7 +1,7 @@ import { ApiRootLinkRel, ApiRootResource, ApiRootService } from '@alfa-client/api-root-shared'; import { StateResource } from '@alfa-client/tech-shared'; import { Component, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; +import { ActivatedRoute, Params, Router } from '@angular/router'; import { AuthenticationService } from 'libs/authentication/src/lib/authentication.service'; import { Observable } from 'rxjs'; @@ -19,6 +19,7 @@ export class AppComponent implements OnInit { public authenticationService: AuthenticationService, private apiRootService: ApiRootService, private router: Router, + private route: ActivatedRoute, ) {} ngOnInit(): void { @@ -27,7 +28,17 @@ export class AppComponent implements OnInit { doAfterLoggedIn(): void { this.apiRootStateResource$ = this.apiRootService.getApiRoot(); - this.router.navigate(['/']); + this.forwardWithoutAuthenticationParams(); + } + + forwardWithoutAuthenticationParams() { + const queryParams = this.getQueryParamsWithoutAuthentication(); + this.router.navigate([], { queryParams }); + } + + private getQueryParamsWithoutAuthentication(): Params { + const { iss, state, session_state, code, ...queryParams } = this.route.snapshot.queryParams; + return queryParams; } protected readonly ApiRootLinkRel = ApiRootLinkRel; diff --git a/alfa-client/apps/admin/src/app/app.module.ts b/alfa-client/apps/admin/src/app/app.module.ts index 01643aecf53c02179b296544043e2dd10f3fca65..2b32d7c65df119f3c0b6469b6d7fa3d8cd43d259 100644 --- a/alfa-client/apps/admin/src/app/app.module.ts +++ b/alfa-client/apps/admin/src/app/app.module.ts @@ -1,9 +1,11 @@ import { AdminSettingsModule } from '@admin-client/admin-settings'; import { ApiRootModule } from '@alfa-client/api-root-shared'; +import { BuildInfoComponent } from '@alfa-client/common'; import { EnvironmentModule } from '@alfa-client/environment-shared'; import { TechSharedModule } from '@alfa-client/tech-shared'; -import { CommonModule } from '@angular/common'; +import { CommonModule, registerLocaleData } from '@angular/common'; import { HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import localeDe from '@angular/common/locales/de'; import { NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { BrowserModule } from '@angular/platform-browser'; @@ -32,10 +34,13 @@ import { OrganisationsEinheitFormPageComponent } from '../pages/organisationsein import { OrganisationsEinheitPageComponent } from '../pages/organisationseinheit/organisationseinheit-page/organisationseinheit-page.component'; import { PostfachPageComponent } from '../pages/postfach/postfach-page/postfach-page.component'; import { UnavailablePageComponent } from '../pages/unavailable/unavailable-page/unavailable-page.component'; +import { UserAddPageComponent } from '../pages/users-roles/user-add-page/user-add-page.component'; import { UserRolesPageComponent } from '../pages/users-roles/user-roles-page/user-roles-page.component'; import { AppComponent } from './app.component'; import { appRoutes } from './app.routes'; +registerLocaleData(localeDe); + @NgModule({ declarations: [ AppComponent, @@ -45,6 +50,7 @@ import { appRoutes } from './app.routes'; OrganisationsEinheitFormPageComponent, UserProfileButtonContainerComponent, UnavailablePageComponent, + UserAddPageComponent, ], imports: [ CommonModule, @@ -75,6 +81,7 @@ import { appRoutes } from './app.routes'; }, }), TechSharedModule, + BuildInfoComponent, ], providers: [ { diff --git a/alfa-client/apps/admin/src/app/app.routes.ts b/alfa-client/apps/admin/src/app/app.routes.ts index 4225458cdaeb73330edbafa34f76c46209ebfc27..6f9acc7ca367f1914ae7d4ff21e72c5004316463 100644 --- a/alfa-client/apps/admin/src/app/app.routes.ts +++ b/alfa-client/apps/admin/src/app/app.routes.ts @@ -1,32 +1,39 @@ import { Route } from '@angular/router'; +import { ROUTES } from 'libs/admin/shared'; import { OrganisationsEinheitFormPageComponent } from '../pages/organisationseinheit/organisationseinheit-form-page/organisationseinheit-form-page.component'; import { OrganisationsEinheitPageComponent } from '../pages/organisationseinheit/organisationseinheit-page/organisationseinheit-page.component'; import { PostfachPageComponent } from '../pages/postfach/postfach-page/postfach-page.component'; +import { UserAddPageComponent } from '../pages/users-roles/user-add-page/user-add-page.component'; import { UserRolesPageComponent } from '../pages/users-roles/user-roles-page/user-roles-page.component'; export const appRoutes: Route[] = [ { path: '', - redirectTo: 'postfach', + redirectTo: ROUTES.POSTFACH, pathMatch: 'full', }, { - path: 'postfach', + path: ROUTES.POSTFACH, component: PostfachPageComponent, title: 'Admin | Postfach', }, { - path: 'benutzer_und_rollen', + path: ROUTES.BENUTZER_UND_ROLLEN, component: UserRolesPageComponent, title: 'Admin | Benutzer & Rollen', }, { - path: 'organisationseinheiten', + path: ROUTES.BENUTZER_UND_ROLLEN_NEU, + component: UserAddPageComponent, + title: 'Admin | Benutzer anlegen', + }, + { + path: ROUTES.ORGANISATIONSEINHEITEN, component: OrganisationsEinheitPageComponent, title: 'Admin | Organisationseinheiten', }, { - path: 'organisationseinheiten/:organisationsEinheitUrl', + path: `${ROUTES.ORGANISATIONSEINHEITEN}/:organisationsEinheitUrl`, component: OrganisationsEinheitFormPageComponent, title: 'Admin | Organisationseinheit', }, diff --git a/alfa-client/apps/admin/src/favicon.ico b/alfa-client/apps/admin/src/favicon.ico deleted file mode 100644 index 317ebcb2336e0833a22dddf0ab287849f26fda57..0000000000000000000000000000000000000000 Binary files a/alfa-client/apps/admin/src/favicon.ico and /dev/null differ diff --git a/alfa-client/apps/admin/src/favicon/apple-touch-icon.png b/alfa-client/apps/admin/src/favicon/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d1e03d655a5aa8d259aacdf45f1fcf28a09251be Binary files /dev/null and b/alfa-client/apps/admin/src/favicon/apple-touch-icon.png differ diff --git a/alfa-client/apps/admin/src/favicon/favicon.svg b/alfa-client/apps/admin/src/favicon/favicon.svg new file mode 100644 index 0000000000000000000000000000000000000000..f610ada33f00495a5ce2e6e6f8f1936de57dec4c --- /dev/null +++ b/alfa-client/apps/admin/src/favicon/favicon.svg @@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg id="Ebene_1" data-name="Ebene 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 250.45 291.68"> + <defs> + <style> + .cls-1 { + clip-path: url(#clippath-4); + } + + .cls-2 { + fill: none; + } + + .cls-3 { + clip-path: url(#clippath-1); + } + + .cls-4 { + clip-path: url(#clippath-5); + } + + .cls-5 { + clip-path: url(#clippath-3); + } + + .cls-6 { + fill: url(#Unbenannter_Verlauf_11); + } + + .cls-7 { + clip-path: url(#clippath-2); + } + + .cls-8 { + clip-path: url(#clippath); + } + + .cls-9 { + fill: #003064; + } + </style> + <linearGradient id="Unbenannter_Verlauf_11" data-name="Unbenannter Verlauf 11" x1="149.23" y1="174.09" x2="250.45" y2="174.09" gradientUnits="userSpaceOnUse"> + <stop offset="0" stop-color="#003064"/> + <stop offset="1" stop-color="#d4004b"/> + </linearGradient> + <clipPath id="clippath"> + <path class="cls-2" d="M182.48,248.08c0,21.25-17.11,38.59-38.15,38.59s-36.9-15.93-38.04-36.14c0-31.09-21.39-57.24-50.08-64.28,12.79-4.17,22.94-14.36,27.02-27.3,6.96,29.06,32.78,50.65,63.36,50.65,20.1,1.15,35.88,18.03,35.88,38.48Z"/> + </clipPath> + <clipPath id="clippath-1"> + <rect class="cls-2" x="51.21" y="153.95" width="136.27" height="137.73"/> + </clipPath> + <clipPath id="clippath-2"> + <rect class="cls-2" x="51.21" y="153.95" width="136.27" height="137.73"/> + </clipPath> + <clipPath id="clippath-3"> + <path class="cls-2" d="M182.48,43.59c0,20.45-15.75,37.33-35.73,38.48-35.43,0-64.42,28.83-65.33,64.51-.04.61-.04,1.19-.04,1.8-1.1,19.72-17.03,35.26-36.56,36.1h-.15c-.49.04-1.02.04-1.51.04-2.08,0-4.12-.15-6.13-.54-.61-.11-1.21-.23-1.82-.34-1.78-.34-3.48-.84-5.15-1.45-2.12-.8-4.13-1.76-6.06-2.91-.61-.34-1.17-.69-1.7-1.07-.15-.08-.3-.19-.45-.31-.76-.5-1.48-1.03-2.16-1.57-.11-.08-.23-.15-.34-.31-.87-.69-1.7-1.42-2.5-2.18-.49-.5-.98-1-1.48-1.53-1.67-1.72-3.1-3.6-4.35-5.63-.3-.5-.61-1.03-.91-1.53-.91-1.53-1.7-3.18-2.35-4.86-.68-1.68-1.25-3.45-1.67-5.25-.15-.61-.3-1.19-.38-1.8-.11-.61-.23-1.23-.3-1.84-.19-1.23-.3-2.49-.38-3.75-.04-.57-.04-1.15-.04-1.72,0-.8.04-1.57.08-2.34.08-1.11.19-2.22.34-3.33.11-.88.27-1.76.45-2.64.04-.08.04-.15.08-.19.15-.88.38-1.76.64-2.6.15-.54.34-1.11.53-1.65.19-.57.42-1.19.64-1.76.38-.96.8-1.91,1.25-2.83.34-.73.72-1.42,1.1-2.07.64-1.15,1.36-2.26,2.12-3.33.61-.88,1.25-1.72,1.93-2.53.04-.04.08-.08.11-.11.42-.5.83-.96,1.29-1.42.34-.38.68-.73,1.02-1.07.53-.54,1.06-1.03,1.63-1.49.49-.46.98-.88,1.51-1.26,1.21-1,2.5-1.88,3.82-2.68.83-.5,1.67-.96,2.54-1.38.49-.31,1.02-.54,1.55-.77.38-.19.76-.34,1.17-.5.38-.19.79-.34,1.21-.46,3.33-1.26,6.89-2.03,10.6-2.22h.49c1.14,0,2.27-.04,3.37-.11h.11c34.37-2.07,61.69-30.9,61.69-65.89,1.13-20.33,17.83-36.3,38.04-36.3s38.15,17.34,38.15,38.59Z"/> + </clipPath> + <clipPath id="clippath-4"> + <rect class="cls-2" y="0" width="187.48" height="189.53"/> + </clipPath> + <clipPath id="clippath-5"> + <rect class="cls-2" y="0" width="187.48" height="189.53"/> + </clipPath> + </defs> + <g> + <path class="cls-9" d="M207.42,137.73h-67.63c-8.36,0-15.14-6.86-15.14-15.31s6.78-15.31,15.14-15.31h67.63c8.36,0,15.14,6.86,15.14,15.31s-6.78,15.31-15.14,15.31Z"/> + <path class="cls-6" d="M235.31,189.41h-70.94c-8.36,0-15.14-6.86-15.14-15.31s6.78-15.31,15.14-15.31h70.94c8.36,0,15.14,6.86,15.14,15.31s-6.78,15.31-15.14,15.31Z"/> + </g> + <g class="cls-8"> + <g class="cls-3"> + <g class="cls-7"> + <image width="285" height="288" transform="translate(50.88 153.49) scale(.48)" xlink:href="data:image/png;base64,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"/> + </g> + </g> + </g> + <g class="cls-5"> + <g class="cls-1"> + <g class="cls-4"> + <image width="391" height="396" transform="translate(0 -.11) scale(.48)" xlink:href="data:image/png;base64,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"/> + </g> + </g> + </g> +</svg> \ No newline at end of file diff --git a/alfa-client/apps/admin/src/favicon/logo192.png b/alfa-client/apps/admin/src/favicon/logo192.png new file mode 100644 index 0000000000000000000000000000000000000000..058c5bb8a8fc79b10adea359c97563030c09bc91 Binary files /dev/null and b/alfa-client/apps/admin/src/favicon/logo192.png differ diff --git a/alfa-client/apps/admin/src/favicon/logo512.png b/alfa-client/apps/admin/src/favicon/logo512.png new file mode 100644 index 0000000000000000000000000000000000000000..86e8c57ac21fd004a424962e4d46bf13bfcfcdef Binary files /dev/null and b/alfa-client/apps/admin/src/favicon/logo512.png differ diff --git a/alfa-client/apps/admin/src/favicon/manifest.json b/alfa-client/apps/admin/src/favicon/manifest.json new file mode 100644 index 0000000000000000000000000000000000000000..ab5afa131edbb266f434c9ce991db50fc685633b --- /dev/null +++ b/alfa-client/apps/admin/src/favicon/manifest.json @@ -0,0 +1,24 @@ +{ + "name": "Alfa Administration", + "short_name": "Administration Client", + "icons": [ + { + "src": "favicon.svg", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "logo192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "logo512.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/alfa-client/apps/admin/src/index.html b/alfa-client/apps/admin/src/index.html index e9b77e77d1493dd0f7e67f051941b5c48fff1b33..667d6ae9fdd9724394c4018d6c6526ee13e177c1 100644 --- a/alfa-client/apps/admin/src/index.html +++ b/alfa-client/apps/admin/src/index.html @@ -5,11 +5,11 @@ <title>admin</title> <base href="/" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> - <link rel="icon" type="image/x-icon" href="favicon.ico" /> + <link rel="icon" href="/favicon.svg" type="image/svg+xml" /> + <link rel="apple-touch-icon" href="/apple-touch-icon.png" /> + <link rel="manifest" href="/manifest.json" /> </head> - <body - class="flex max-h-full min-h-full overflow-hidden bg-white text-black dark:bg-slate-900 dark:text-slate-100" - > + <body class="flex max-h-full min-h-full overflow-hidden bg-white text-black dark:bg-slate-900 dark:text-slate-100"> <app-root class="flex w-full flex-col"></app-root> </body> </html> diff --git a/alfa-client/apps/admin/src/pages/users-roles/user-add-page/user-add-page.component.html b/alfa-client/apps/admin/src/pages/users-roles/user-add-page/user-add-page.component.html new file mode 100644 index 0000000000000000000000000000000000000000..dad58a8662dd19eb059273474e2df1474305d3b4 --- /dev/null +++ b/alfa-client/apps/admin/src/pages/users-roles/user-add-page/user-add-page.component.html @@ -0,0 +1 @@ +<admin-user-add-form /> diff --git a/alfa-client/apps/admin/src/pages/users-roles/user-add-page/user-add-page.component.spec.ts b/alfa-client/apps/admin/src/pages/users-roles/user-add-page/user-add-page.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..eecaa8e5c0c24be917a8b968d2af926dbf1ff56f --- /dev/null +++ b/alfa-client/apps/admin/src/pages/users-roles/user-add-page/user-add-page.component.spec.ts @@ -0,0 +1,23 @@ +import { UserAddFormComponent } from '@admin-client/admin-settings'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { MockComponent } from 'ng-mocks'; +import { UserAddPageComponent } from './user-add-page.component'; + +describe('UserAddPageComponent', () => { + let component: UserAddPageComponent; + let fixture: ComponentFixture<UserAddPageComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [UserAddPageComponent, MockComponent(UserAddFormComponent)], + }).compileComponents(); + + fixture = TestBed.createComponent(UserAddPageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/alfa-client/apps/admin/src/pages/users-roles/user-add-page/user-add-page.component.ts b/alfa-client/apps/admin/src/pages/users-roles/user-add-page/user-add-page.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3bcc1eaf5f74df921a17932bea865ce96a61907 --- /dev/null +++ b/alfa-client/apps/admin/src/pages/users-roles/user-add-page/user-add-page.component.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'user-add-page', + templateUrl: './user-add-page.component.html', +}) +export class UserAddPageComponent {} diff --git a/alfa-client/apps/admin/src/styles.scss b/alfa-client/apps/admin/src/styles.scss index 4e5a7a5c68a63422c4523a58efe6f664c0a6e13e..f3ad3e7e325ea8827c9128b64e18eeb5ec083c9b 100644 --- a/alfa-client/apps/admin/src/styles.scss +++ b/alfa-client/apps/admin/src/styles.scss @@ -7,12 +7,17 @@ @import 'libs/design-system/src/lib/tailwind-preset/root.css'; @import 'libs/ui/src/lib/font/font_material'; @import 'variables'; +@import 'typeface-roboto/index.css'; @include mat.all-component-typographies(); @include mat.core(); @include mat.all-component-themes($alfaTheme); +body { + font-family: Roboto, 'Helvetica Neue', sans-serif; +} + body.dark { @include mat.all-component-colors($alfaDarkTheme); } diff --git a/alfa-client/apps/alfa-e2e/README.md b/alfa-client/apps/alfa-e2e/README.md index e54e685002d7a1d2eddf7ddbcf68214f741a5f0f..e8fd2fba20457053b9a043e3cdbadfa696692c5e 100644 --- a/alfa-client/apps/alfa-e2e/README.md +++ b/alfa-client/apps/alfa-e2e/README.md @@ -1,14 +1,39 @@ -# E2E - ## Allgemein -Die E2E Tests werden in parallen Jenkins Stages in seperaten Namespaces durchgeführt. -`einheitlicher-ansprechpartener` -> 'EA'-Umgebung -`main-tests` -> 'Dev'-Umgebung --> es dürfen nur die der Umgebung entsprechenden User für die Tests genutzt werden. -(siehe dokumentation/Anwender/Standardbenutzer.md) +Dieses Teilprojekt bündelt: +* Die End-2-End Tests für die Alfa-Anwendung +* Das Setup für verschiedene Konfigurationsvarianten + +Die Konfigurationsvarianten sind: +* Ausführungsart und Umgebung + * lokal + * Im Cluster (dynamisch deployed) + * Im Cluster (statisch) +* Fachlich unterschiedliche Testgruppen + * `einheitlicher-ansprechpartner` -> 'EA'-Umgebung + * `main-tests` -> 'Dev'-Umgebung + +Dabei benötigen die Testgruppen (sogenannte "App-Varianten", siehe Verzeichnis [src/e2e](src/e2e)) jeweils eine eigene Umgebung in der gewählten Ausführungsart. + +## Lokale Ausführung +Siehe [Entwicklungsdokumentation](https://git.ozg-sh.de/ozgcloud-doc/dokumentation/src/branch/master/Entwicklungsumgebung#e2e-tests). + +## Jenkins/Cluster Ausführung +Die E2E Tests werden in parallelen Jenkins Stages in separaten Namespaces durchgeführt. -## Gegen ein bestehenden Namespace testen +Es dürfen nur die der Umgebung entsprechenden User für die Tests genutzt werden (siehe [Standardbenutzer](https://git.ozg-sh.de/ozgcloud-doc/dokumentation/src/branch/master/Anwender/Standardbenutzer.md)). + +Es gibt 2 Jenkinsfiles: +* E2E ("main") - Das derzeit benutzte Hauptprofil. Namespaces werden hier neu aufgebaut. +* Static - Profil, wenn eine bestehender Namespace (ggf. in ganz bestimmter Konfiguration) getestet werden soll. + +### Dynamisch deployed +* siehe: [Jenkinsfile.e2e](../../Jenkinsfile.e2e) +* Im Verzeichnis 'src/fixtures/argocd' liegen die Kubernetes Templates (ArgoCD-Namespace-Helm-Charts) +* Neue Umgebungen werden im Repo [gitops im Branch "e2e"](https://git.ozg-sh.de/ozgcloud-devops/gitops/src/branch/e2e) eingetragen. + +### Gegen ein bestehenden Namespace testen +Siehe: [Jenkinsfile.e2e](../../Jenkinsfile.e2e.static) Beispiel Namespace: sh-mastere2emain-dev @@ -20,10 +45,11 @@ Beispiel Namespace: sh-mastere2emain-dev 4. Cypress mit entsprechender config starten: `npm run cypress:open -- --config-file cypress-master-main.json` -## docker-compose +## Dev Hinweise ### -march Architektur In die `.env` Datei eintragen: - - USER_MANAGER_DOCKER_IMAGE=march-snapshot-latest \ No newline at end of file +``` +USER_MANAGER_DOCKER_IMAGE=march-snapshot-latest +``` \ No newline at end of file diff --git a/alfa-client/apps/alfa-e2e/cypress.config.json b/alfa-client/apps/alfa-e2e/cypress.config.json index 3a604c010deb694376105420fb38252bc1029efe..10160a6f1a1a224da71dcdc3671381d635fed8b9 100644 --- a/alfa-client/apps/alfa-e2e/cypress.config.json +++ b/alfa-client/apps/alfa-e2e/cypress.config.json @@ -34,7 +34,7 @@ "reporterOptions": { "html": false, "json": true, - "reportDir": "./reports/mochawesome-report", + "reportDir": "./reports/main-tests/mochawesome-report", "reportFilename": "report", "overwrite": true } diff --git a/alfa-client/apps/alfa-e2e/run-tests.sh b/alfa-client/apps/alfa-e2e/run-tests.sh deleted file mode 100755 index 6b7f5098a285a5417326b611f500c686fcd1f08f..0000000000000000000000000000000000000000 --- a/alfa-client/apps/alfa-e2e/run-tests.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash - -export NO_COLOR=1 - -REPORT_FOLDER=$1 -CONFIG_FILE="${2:-cypress.config.ts}" - -echo "Run E2E for $REPORT_FOLDER with configuration apps/alfa-e2e/$CONFIG_FILE..." - -rm -rf apps/alfa-e2e/reports/${REPORT_FOLDER} - -npx cypress run --project apps/alfa-e2e --spec apps/alfa-e2e/src/e2e/${REPORT_FOLDER} --config-file $CONFIG_FILE - -TEST_RESULT=$? - -if [ -d "apps/alfa-e2e/reports/${REPORT_FOLDER}/mochawesome-report/.jsons" ]; then - mv apps/alfa-e2e/reports/${REPORT_FOLDER}/mochawesome-report/.jsons apps/alfa-e2e/reports/${REPORT_FOLDER}/mochawesome-report/jsons - npx mochawesome-merge apps/alfa-e2e/reports/${REPORT_FOLDER}/mochawesome-report/**/*.json > apps/alfa-e2e/reports/${REPORT_FOLDER}/report.json - # Workaround: mochawesome's "screenshotsFolder" value is not added in the generated HTML file. Add "screenshots" to image paths. - sed --in-place --regexp-extended 's/"([^"]*\.png)/"screenshots\1/' apps/alfa-e2e/reports/${REPORT_FOLDER}/report.json - npx marge apps/alfa-e2e/reports/${REPORT_FOLDER}/report.json -f report -o apps/alfa-e2e/reports/${REPORT_FOLDER} -else - echo "ERROR: Reports do not exist at apps/alfa-e2e/reports/${REPORT_FOLDER}/mochawesome-report/.jsons" -fi - -exit $TEST_RESULT \ No newline at end of file diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/user-settings/user-settings.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/user-settings/user-settings.cy.ts index 2ba36a2468e8cf3c13653885f476e7d047da1d59..6062ca41eca131651c1b23683ea91ca7632dde54 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/user-settings/user-settings.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/user-settings/user-settings.cy.ts @@ -80,78 +80,78 @@ describe('User Settings', () => { }); describe('click on neuer Vorgang toggle', () => { - it('should have initial unchecked toggle', () => { + it('should have initial checked toggle', () => { isNotChecked(userSettings.getEmailBenachrichtigungForNewVorgang().getToggle()); }); it('should switch toggle status', () => { userSettings.getEmailBenachrichtigungForNewVorgang().getToggle().click(); - isChecked(userSettings.getEmailBenachrichtigungForNewVorgang().getToggle()); + isNotChecked(userSettings.getEmailBenachrichtigungForNewVorgang().getToggle()); }); it('should be loaded after page reload', () => { reload(); userSettings.getRoot().click(); - isChecked(userSettings.getEmailBenachrichtigungForNewVorgang().getToggle()); + isNotChecked(userSettings.getEmailBenachrichtigungForNewVorgang().getToggle()); }); }); describe('click on neue nachricht antragsteller toggle', () => { - it('should have initial unchecked toggle', () => { - isNotChecked(userSettings.getEmailBenachrichtigungForPostfachNachrichtFromAntragsteller().getToggle()); + it('should have initial checked toggle', () => { + isChecked(userSettings.getEmailBenachrichtigungForPostfachNachrichtFromAntragsteller().getToggle()); }); it('should switch toggle status', () => { userSettings.getEmailBenachrichtigungForPostfachNachrichtFromAntragsteller().getToggle().click(); - isChecked(userSettings.getEmailBenachrichtigungForPostfachNachrichtFromAntragsteller().getToggle()); + isNotChecked(userSettings.getEmailBenachrichtigungForPostfachNachrichtFromAntragsteller().getToggle()); }); it('should be loaded after page reload', () => { reload(); userSettings.getRoot().click(); - isChecked(userSettings.getEmailBenachrichtigungForPostfachNachrichtFromAntragsteller().getToggle()); + isNotChecked(userSettings.getEmailBenachrichtigungForPostfachNachrichtFromAntragsteller().getToggle()); }); }); describe('click on vorgang mir zugewiesen toggle', () => { - it('should have initial unchecked toggle', () => { - isNotChecked(userSettings.getEmailBenachrichtigungForVorgangAssignedToUser().getToggle()); + it('should have initial checked toggle', () => { + isChecked(userSettings.getEmailBenachrichtigungForVorgangAssignedToUser().getToggle()); }); it('should switch toggle status', () => { userSettings.getEmailBenachrichtigungForVorgangAssignedToUser().getToggle().click(); - isChecked(userSettings.getEmailBenachrichtigungForVorgangAssignedToUser().getToggle()); + isNotChecked(userSettings.getEmailBenachrichtigungForVorgangAssignedToUser().getToggle()); }); it('should be loaded after page reload', () => { reload(); userSettings.getRoot().click(); - isChecked(userSettings.getEmailBenachrichtigungForVorgangAssignedToUser().getToggle()); + isNotChecked(userSettings.getEmailBenachrichtigungForVorgangAssignedToUser().getToggle()); }); }); describe('click on faellige wiedervorlage toggle', () => { - it('should have initial unchecked toggle', () => { - isNotChecked(userSettings.getEmailBenachrichtigungForWiedervorlageDueToday().getToggle()); + it('should have initial checked toggle', () => { + isChecked(userSettings.getEmailBenachrichtigungForWiedervorlageDueToday().getToggle()); }); it('should switch toggle status', () => { userSettings.getEmailBenachrichtigungForWiedervorlageDueToday().getToggle().click(); - isChecked(userSettings.getEmailBenachrichtigungForWiedervorlageDueToday().getToggle()); + isNotChecked(userSettings.getEmailBenachrichtigungForWiedervorlageDueToday().getToggle()); }); it('should be loaded after page reload', () => { reload(); userSettings.getRoot().click(); - isChecked(userSettings.getEmailBenachrichtigungForWiedervorlageDueToday().getToggle()); + isNotChecked(userSettings.getEmailBenachrichtigungForWiedervorlageDueToday().getToggle()); }); }); diff --git a/alfa-client/apps/alfa-e2e/src/fixtures/argocd/by-ea-dev.yaml b/alfa-client/apps/alfa-e2e/src/fixtures/argocd/by-ea-dev.yaml index 58e0660e0f37cba42cc6ab8ed1b0c824d5e3902d..d045ee9c6f58b1df37fc04f1260c0b75178a4bb1 100644 --- a/alfa-client/apps/alfa-e2e/src/fixtures/argocd/by-ea-dev.yaml +++ b/alfa-client/apps/alfa-e2e/src/fixtures/argocd/by-ea-dev.yaml @@ -7,6 +7,14 @@ project: - namespace: '*' server: https://kubernetes.default.svc +administration: + enabled: true + +admin_client: + enabled: true + ingress: + use_staging_cert: true + alfa: env: overrideSpringProfiles: 'oc,ea,e2e,dev' diff --git a/alfa-client/apps/alfa-e2e/src/fixtures/argocd/by-main-dev.yaml b/alfa-client/apps/alfa-e2e/src/fixtures/argocd/by-main-dev.yaml index ed32236cd2d0a9b3c211c4c54b7a726e212cf500..1bcb0012c4aa771b977d6834c8d9825b20cb4f11 100644 --- a/alfa-client/apps/alfa-e2e/src/fixtures/argocd/by-main-dev.yaml +++ b/alfa-client/apps/alfa-e2e/src/fixtures/argocd/by-main-dev.yaml @@ -6,11 +6,10 @@ project: destinations: - namespace: "*" server: https://kubernetes.default.svc + alfa: env: overrideSpringProfiles: "oc,e2e,dev" - customList: - ozgcloud_feature_bescheid-wizard: "true" ingress: use_staging_cert: true ozgcloud: diff --git a/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_ariane.json b/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_ariane.json index 814e061ad715953b45342a9fde9a3dab6f7b17c3..7e02474fe5f97aaa5a7f7161d6476fc04462c046 100644 --- a/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_ariane.json +++ b/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_ariane.json @@ -10,7 +10,7 @@ "firstName": "Ariane", "fullName": "Ariane Admin", "lastName": "Admin", - "email": "ariane-admin@ozg-sh.de", + "email": "ariane-admin@e2e-ozg-sh.de", "lastSyncTimestamp": 1663585874687, "organisationsEinheitIds": [], "roles": ["ADMIN_ADMIN", "VERWALTUNG_USER"], diff --git a/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_dorothea.json b/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_dorothea.json index 8c8a317b75a24343340390cc1e8bd722e3948d93..2c87f7fdacacfdbde9da6c1283556a12e73add3e 100644 --- a/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_dorothea.json +++ b/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_dorothea.json @@ -10,7 +10,7 @@ "firstName": "Dorothea", "fullName": "Dorothea Doe", "lastName": "Doe", - "email": "dorothea.doe@ozg-sh.de", + "email": "dorothea.doe@e2e-ozg-sh.de", "lastSyncTimestamp": 1663585874687, "organisationsEinheitIds": ["9030229", "10363455", "248240886"], "roles": ["VERWALTUNG_USER"], diff --git a/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_emil.json b/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_emil.json index 2919f1b73675781d3f0b6b508a689f8587553216..f84b1f7bd73abde3e5a0eafe096e7e989f7f0f6f 100644 --- a/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_emil.json +++ b/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_emil.json @@ -10,7 +10,7 @@ "firstName": "Emil", "fullName": "Emil Ansprechpartner", "lastName": "Ansprechpartner", - "email": "emil.ansprechpartner@ozg-sh.de", + "email": "emil.ansprechpartner@e2e-ozg-sh.de", "lastSyncTimestamp": 1663585874687, "organisationsEinheitIds": [], "roles": ["EINHEITLICHER_ANSPRECHPARTNER"], diff --git a/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_peter.json b/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_peter.json index 9bc95422fb2c6d99c6ea408d684e73b13fde1e08..6c0d961bd99a0f997153343106a8ca82b473d82c 100644 --- a/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_peter.json +++ b/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_peter.json @@ -10,7 +10,7 @@ "firstName": "Peter", "fullName": "Peter von der Post", "lastName": "von der Post", - "email": "peter.von.der.post@ozg-sh.de", + "email": "peter.von.der.post@e2e-ozg-sh.de", "lastSyncTimestamp": 1663585874687, "organisationsEinheitIds": [], "roles": ["VERWALTUNG_POSTSTELLE"], diff --git a/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_sabine.json b/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_sabine.json index afc4c87496649073054973b8e9944a7740fe4d49..f6be06faa2fb4f03c6e7981399201d000f263dc9 100644 --- a/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_sabine.json +++ b/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_sabine.json @@ -10,7 +10,7 @@ "firstName": "Sabine", "fullName": "Sabine Sach", "lastName": "Sach", - "email": "sabine.sach@ozg-sh.de", + "email": "sabine.sach@e2e-ozg-sh.de", "lastSyncTimestamp": 1663585874687, "organisationsEinheitIds": ["248240886"], "roles": ["VERWALTUNG_USER"], diff --git a/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_zelda.json b/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_zelda.json index 013cd251b1f3d1e20c6b775c61c1f0a11471b50f..466f127e1c848d66409fc46da37b0482933d4eba 100644 --- a/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_zelda.json +++ b/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_zelda.json @@ -10,7 +10,7 @@ "firstName": "Zelda", "fullName": "Zelda Zusammen", "lastName": "Zusammen", - "email": "zelda-z@ozg-sh.de", + "email": "zelda-z@e2e-ozg-sh.de", "lastSyncTimestamp": 1663585874687, "organisationsEinheitIds": ["9797773", "9093371"], "roles": ["VERWALTUNG_USER"], diff --git a/alfa-client/apps/alfa-e2e/src/support/cypress-tasks.ts b/alfa-client/apps/alfa-e2e/src/support/cypress-tasks.ts index 827b7b3d31d21f7c991796b5256302ae28354466..a1926d26e2cd70c9e92fc9fc40271a782ac16859 100644 --- a/alfa-client/apps/alfa-e2e/src/support/cypress-tasks.ts +++ b/alfa-client/apps/alfa-e2e/src/support/cypress-tasks.ts @@ -1,5 +1,6 @@ import { readdir, remove } from 'fs-extra'; import { Db, Long, MongoClient, ObjectId } from 'mongodb'; + const fs = require('fs'); const decompress = require('decompress'); @@ -212,9 +213,7 @@ function createDate(field) { } function parseVorgangAttachedItemData(vorgangAttachedItems) { - vorgangAttachedItems.forEach((vorgangAttachedItem) => - parseVorgangAttachedItem(vorgangAttachedItem), - ); + vorgangAttachedItems.forEach((vorgangAttachedItem) => parseVorgangAttachedItem(vorgangAttachedItem)); return vorgangAttachedItems; } @@ -247,7 +246,21 @@ function insertIntoDatabase(config, collection, data) { } function insertIntoUserManagerDatabase(config, collection, data) { - insert(getUserManagerDatabaseUrl(config), getUserManagerDatabase(config), collection, data); + insertWithoutDrop(getUserManagerDatabaseUrl(config), getUserManagerDatabase(config), collection, data); +} + +function insertWithoutDrop(databaseUrl, databaseName, collection, data) { + MongoClient.connect(databaseUrl, (error, connection) => { + console.log(`connect to ${databaseName} database with ${databaseUrl}`); + if (!error) { + console.log('success'); + const db: Db = connection.db(databaseName); + + db.createCollection(collection, (error) => handleCreateCollection(db, connection, collection, data, error)); + } else { + console.error('Error: ', error); + } + }); } function insert(databaseUrl, databaseName, collection, data) { @@ -258,9 +271,7 @@ function insert(databaseUrl, databaseName, collection, data) { const db: Db = connection.db(databaseName); db.collection(collection).drop(() => { - db.createCollection(collection, (error) => - handleCreateCollection(db, connection, collection, data, error), - ); + db.createCollection(collection, (error) => handleCreateCollection(db, connection, collection, data, error)); }); } else { console.error('Error: ', error); diff --git a/alfa-client/apps/alfa/src/app/app.component.html b/alfa-client/apps/alfa/src/app/app.component.html index 089e9de91f369cb64da483eb2a4316543084ae53..b10af37299a6874ab18519ed496e0366d18cb0bc 100644 --- a/alfa-client/apps/alfa/src/app/app.component.html +++ b/alfa-client/apps/alfa/src/app/app.component.html @@ -31,11 +31,7 @@ <div class="mat-app-background relative grow"><router-outlet></router-outlet></div> <section class="mat-app-background right-nav"> - <alfa-build-info - *ngIf="apiRoot.resource" - [apiRoot]="apiRoot.resource" - data-test-id="build-info" - ></alfa-build-info> + <alfa-build-info *ngIf="apiRoot.resource" [apiRoot]="apiRoot.resource" data-test-id="build-info"></alfa-build-info> </section> </div> </ozgcloud-spinner> diff --git a/alfa-client/apps/alfa/src/app/app.component.spec.ts b/alfa-client/apps/alfa/src/app/app.component.spec.ts index 0ca6382a2e0987cdbc277b9d388a891049849563..8824da3647969782aab53105663e18e44105a01a 100644 --- a/alfa-client/apps/alfa/src/app/app.component.spec.ts +++ b/alfa-client/apps/alfa/src/app/app.component.spec.ts @@ -22,6 +22,7 @@ * unter der Lizenz sind dem Lizenztext zu entnehmen. */ import { ApiRootFacade } from '@alfa-client/api-root-shared'; +import { BuildInfoComponent } from '@alfa-client/common'; import { ENVIRONMENT_CONFIG } from '@alfa-client/environment-shared'; import { NavigationService } from '@alfa-client/navigation-shared'; import { createEmptyStateResource, createStateResource } from '@alfa-client/tech-shared'; @@ -30,20 +31,18 @@ import { IconService, SpinnerComponent } from '@alfa-client/ui'; import { registerLocaleData } from '@angular/common'; import localeDe from '@angular/common/locales/de'; import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { Params } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; import { AuthConfig, OAuthEvent, OAuthService } from 'angular-oauth2-oidc'; import { createApiRootResource } from 'libs/api-root-shared/test/api-root'; -import { BuildInfoComponent } from 'libs/navigation/src/lib/build-info/build-info.component'; import { HeaderContainerComponent } from 'libs/navigation/src/lib/header-container/header-container.component'; import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; import { setWindowLocationUrl } from 'libs/tech-shared/test/window'; +import * as VorgangNavigationUtil from 'libs/vorgang-shared/src/lib/vorgang-navigation.util'; import { MockComponent } from 'ng-mocks'; import { of } from 'rxjs'; import { AppComponent } from './app.component'; -import { Params } from '@angular/router'; -import * as VorgangNavigationUtil from 'libs/vorgang-shared/src/lib/vorgang-navigation.util'; - registerLocaleData(localeDe); describe('AppComponent', () => { diff --git a/alfa-client/apps/alfa/src/app/app.module.ts b/alfa-client/apps/alfa/src/app/app.module.ts index f7138d442ac5f3c8ff30f3864c4f2943bd5a4c9e..8e35a1cb4ea3831bccdbb142b68d8844cb53582d 100644 --- a/alfa-client/apps/alfa/src/app/app.module.ts +++ b/alfa-client/apps/alfa/src/app/app.module.ts @@ -23,6 +23,7 @@ */ import { ApiRootModule } from '@alfa-client/api-root-shared'; import { AppSharedModule } from '@alfa-client/app-shared'; +import { BuildInfoComponent } from '@alfa-client/common'; import { EnvironmentModule } from '@alfa-client/environment-shared'; import { HintSharedModule } from '@alfa-client/hint-shared'; import { NavigationModule } from '@alfa-client/navigation'; @@ -75,6 +76,7 @@ const routes: Routes = [ }), ApiRootModule, NavigationModule, + BuildInfoComponent, AppSharedModule, StoreModule.forRoot( {}, diff --git a/alfa-client/apps/run-tests.sh b/alfa-client/apps/run-tests.sh new file mode 100755 index 0000000000000000000000000000000000000000..eadee4428cd9620ad5c66da8d44a0459f1e42c58 --- /dev/null +++ b/alfa-client/apps/run-tests.sh @@ -0,0 +1,44 @@ +#!/bin/bash +export NO_COLOR=1 + +if [ $# -eq 0 ]; then + >&2 echo "This script is for Jenkins Execution of E2E-Tests" + >&2 echo "Example: ./run-tests.sh admin-e2e main-tests cypress.config.ts" + exit 1 +fi +APP_NAME="${1:-alfa-e2e}" +APP_VARIATION="${2:-main-tests}" +CONFIG_FILE="${3:-cypress.config.ts}" + +if [ -z $APP_NAME ]; then echo "App Folder not set" && exit 1; fi +if [ -z $APP_VARIATION ]; then echo "Variation Name not set" && exit 1; fi +if [ -z $CONFIG_FILE ]; then echo "Config File not set" && exit 1; fi + +SCRIPT_DIR="$(dirname "$0")" +BASE_PATH=${SCRIPT_DIR}/${APP_NAME} +SPEC_GROUP=${BASE_PATH}/src/e2e/${APP_VARIATION} +COMMAND="npx cypress run --project ${BASE_PATH} --spec ${SPEC_GROUP} --config-file ${CONFIG_FILE}" +REPORT_PATH=${BASE_PATH}/reports/${APP_VARIATION} + +echo "Run E2E for ${APP_NAME} with command: '$COMMAND'" + +rm -rf ${REPORT_PATH} + +eval $COMMAND +TEST_RESULT=$? + +if [ -d "${REPORT_PATH}" ]; then + MOCHA_REPORT_PATH=${REPORT_PATH}/mochawesome-report/ + MOCHA_REPORT_JSONS=${MOCHA_REPORT_PATH}.jsons + MOCHA_REPORT_FILE=${MOCHA_REPORT_PATH}report.json + + mv ${MOCHA_REPORT_JSONS} ${MOCHA_REPORT_PATH}/jsons + npx mochawesome-merge ${MOCHA_REPORT_PATH}**/*.json > ${MOCHA_REPORT_FILE} + # Workaround: mochawesome's "screenshotsFolder" value is not added in the generated HTML file. Add "screenshots" to image paths. + sed --in-place --regexp-extended 's/"([^"]*\.png)/"screenshots\1/' ${MOCHA_REPORT_FILE} + npx marge ${MOCHA_REPORT_FILE} -f report -o ${REPORT_PATH} +else + echo "ERROR: Reports do not exist at ${REPORT_PATH}" +fi + +exit $TEST_RESULT \ No newline at end of file diff --git a/alfa-client/libs/admin/settings/src/index.ts b/alfa-client/libs/admin/settings/src/index.ts index a13f84185d2480694cbb145fb300e553cc668381..b1a8f83f9738553500db49b8058e577390482e95 100644 --- a/alfa-client/libs/admin/settings/src/index.ts +++ b/alfa-client/libs/admin/settings/src/index.ts @@ -3,5 +3,5 @@ export * from './lib/organisationseinheit/organisations-einheit.model'; export * from './lib/organisationseinheit/organisationseinheit-container/organisationseinheit-container.component'; export * from './lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form-container.component'; export * from './lib/postfach/postfach-container/postfach-container.component'; -export * from './lib/shared/navigation-item/navigation-item.component'; +export * from './lib/users-roles/user-add-form/user-add-form.component'; export * from './lib/users-roles/users-roles.component'; diff --git a/alfa-client/libs/admin/settings/src/lib/admin-settings.module.ts b/alfa-client/libs/admin/settings/src/lib/admin-settings.module.ts index ad13c6426adbf09d39909c175b215c4e79f6c932..4e3f5c7bfe4c0a78873f7b92e3a6271a1668675f 100644 --- a/alfa-client/libs/admin/settings/src/lib/admin-settings.module.ts +++ b/alfa-client/libs/admin/settings/src/lib/admin-settings.module.ts @@ -8,7 +8,12 @@ import { NgModule } from '@angular/core'; import { ReactiveFormsModule } from '@angular/forms'; import { RouterModule } from '@angular/router'; import KcAdminClient from '@keycloak/keycloak-admin-client'; -import { ButtonWithSpinnerComponent, TextareaEditorComponent } from '@ods/component'; +import { + ButtonWithSpinnerComponent, + CheckboxEditorComponent, + TextareaEditorComponent, + TextEditorComponent, +} from '@ods/component'; import { ExclamationIconComponent, ListComponent, @@ -39,14 +44,8 @@ import { PostfachFormComponent } from './postfach/postfach-container/postfach-fo import { PostfachSignaturComponent } from './postfach/postfach-container/postfach-form/postfach-signatur/postfach-signatur.component'; import { createPostfachResourceService, PostfachResourceService } from './postfach/postfach-resource.service'; import { PostfachService } from './postfach/postfach.service'; -import { MoreItemButtonComponent } from './shared/more-menu/more-item-button/more-item-button.component'; -import { MoreMenuComponent } from './shared/more-menu/more-menu.component'; -import { NavigationItemComponent } from './shared/navigation-item/navigation-item.component'; -import { PrimaryButtonComponent } from './shared/primary-button/primary-button.component'; -import { SecondaryButtonComponent } from './shared/secondary-button/secondary-button.component'; -import { SpinnerComponent } from './shared/spinner/spinner.component'; -import { TextFieldComponent } from './shared/text-field/text-field.component'; import { ToUserNamePipe } from './user/to-user-name.pipe'; +import { UserAddFormComponent } from './users-roles/user-add-form/user-add-form.component'; import { UsersRolesComponent } from './users-roles/users-roles.component'; @NgModule({ @@ -54,19 +53,13 @@ import { UsersRolesComponent } from './users-roles/users-roles.component'; PostfachContainerComponent, PostfachFormComponent, PostfachSignaturComponent, - NavigationItemComponent, - TextFieldComponent, OrganisationsEinheitContainerComponent, OrganisationsEinheitListComponent, OrganisationsEinheitFormContainerComponent, OrganisationsEinheitFormComponent, OrganisationsEinheitSignaturComponent, - PrimaryButtonComponent, - SecondaryButtonComponent, - MoreMenuComponent, - MoreItemButtonComponent, - SpinnerComponent, UsersRolesComponent, + UserAddFormComponent, ], imports: [ CommonModule, @@ -74,6 +67,7 @@ import { UsersRolesComponent } from './users-roles/users-roles.component'; RouterModule, ReactiveFormsModule, TextInputComponent, + CheckboxEditorComponent, ButtonWithSpinnerComponent, TextareaEditorComponent, MailboxIconComponent, @@ -84,13 +78,14 @@ import { UsersRolesComponent } from './users-roles/users-roles.component'; ExclamationIconComponent, UiModule, NavigationSharedModule, + TextEditorComponent, ], exports: [ PostfachContainerComponent, OrganisationsEinheitContainerComponent, OrganisationsEinheitFormContainerComponent, - NavigationItemComponent, UsersRolesComponent, + UserAddFormComponent, ], providers: [ ConfigurationService, diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit-form.component.spec.ts b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit-form.component.spec.ts index ad4f7bd11d40c6444ba2fdbbc169cd0b81aff0f4..86d331e417dd25431571427af73a542672943420 100644 --- a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit-form.component.spec.ts +++ b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit-form.component.spec.ts @@ -9,7 +9,6 @@ import { MockComponent } from 'ng-mocks'; import { of } from 'rxjs'; import { createInvalidParam, createProblemDetail } from '../../../../../../../tech-shared/test/error'; import { createAdminOrganisationsEinheitResource } from '../../../../../test/organisations-einheit/organisations-einheit'; -import { TextFieldComponent } from '../../../shared/text-field/text-field.component'; import { OrganisationsEinheitService } from '../../organisationseinheit.service'; import { OrganisationsEinheitFormComponent } from './organisationseinheit-form.component'; import { OrganisationsEinheitSignaturComponent } from './organisationseinheit-signatur/organisationseinheit-signatur.component'; @@ -31,7 +30,6 @@ describe('OrganisationsEinheitFormComponent', () => { await TestBed.configureTestingModule({ declarations: [ OrganisationsEinheitFormComponent, - MockComponent(TextFieldComponent), MockComponent(OrganisationsEinheitSignaturComponent), MockComponent(ButtonWithSpinnerComponent), ], diff --git a/alfa-client/libs/admin/settings/src/lib/postfach/postfach-container/postfach-form/postfach-form.component.spec.ts b/alfa-client/libs/admin/settings/src/lib/postfach/postfach-container/postfach-form/postfach-form.component.spec.ts index 8c8096d7df647918130510a8ac0fad54499064f7..119bf30d3ed7cac949543b020412c62a50e079f5 100644 --- a/alfa-client/libs/admin/settings/src/lib/postfach/postfach-container/postfach-form/postfach-form.component.spec.ts +++ b/alfa-client/libs/admin/settings/src/lib/postfach/postfach-container/postfach-form/postfach-form.component.spec.ts @@ -9,7 +9,6 @@ import { singleCold } from 'libs/tech-shared/test/marbles'; import { MockComponent } from 'ng-mocks'; import { EMPTY } from 'rxjs'; import { createPostfachResource } from '../../../../../test/postfach/postfach'; -import { TextFieldComponent } from '../../../shared/text-field/text-field.component'; import { PostfachResource } from '../../postfach.model'; import { PostfachService } from '../../postfach.service'; import { PostfachFormComponent } from './postfach-form.component'; @@ -28,12 +27,7 @@ describe('PostfachFormComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ - PostfachFormComponent, - MockComponent(TextFieldComponent), - MockComponent(PostfachSignaturComponent), - MockComponent(ButtonWithSpinnerComponent), - ], + declarations: [PostfachFormComponent, MockComponent(PostfachSignaturComponent), MockComponent(ButtonWithSpinnerComponent)], imports: [ReactiveFormsModule, FormsModule], providers: [ { diff --git a/alfa-client/libs/admin/settings/src/lib/postfach/postfach-container/postfach-form/postfach-signatur/postfach-signatur.component.spec.ts b/alfa-client/libs/admin/settings/src/lib/postfach/postfach-container/postfach-form/postfach-signatur/postfach-signatur.component.spec.ts index 7ac55113ec028463983d6e823f2e7842fbf9e53a..9d8db826b2b839234c1a12ce65caa10e2480e2bb 100644 --- a/alfa-client/libs/admin/settings/src/lib/postfach/postfach-container/postfach-form/postfach-signatur/postfach-signatur.component.spec.ts +++ b/alfa-client/libs/admin/settings/src/lib/postfach/postfach-container/postfach-form/postfach-signatur/postfach-signatur.component.spec.ts @@ -1,6 +1,6 @@ -import { getElementFromFixture, mock, useFromMock } from '@alfa-client/test-utils'; +import { getElementFromFixture, mock, Mock } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { FormBuilder, ReactiveFormsModule } from '@angular/forms'; +import { ReactiveFormsModule } from '@angular/forms'; import { TextareaEditorComponent } from '@ods/component'; import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; import { MockComponent } from 'ng-mocks'; @@ -13,14 +13,13 @@ describe('PostfachSignaturComponent', () => { let component: PostfachSignaturComponent; let fixture: ComponentFixture<PostfachSignaturComponent>; - const formService: PostfachFormService = new PostfachFormService( - new FormBuilder(), - useFromMock(mock(PostfachService)), - ); - + let formService: Mock<PostfachFormService>; + let postfachService: Mock<PostfachService>; const signaturTextarea = getDataTestIdOf('signatur-text'); beforeEach(async () => { + formService = mock(PostfachFormService); + postfachService = mock(PostfachService); await TestBed.configureTestingModule({ imports: [ReactiveFormsModule], declarations: [PostfachFormComponent, MockComponent(TextareaEditorComponent)], @@ -29,9 +28,14 @@ describe('PostfachSignaturComponent', () => { provide: PostfachFormService, useValue: formService, }, + { + provide: PostfachService, + useValue: postfachService, + }, ], }).compileComponents(); fixture = TestBed.createComponent(PostfachSignaturComponent); + TestBed.inject(PostfachService); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/alfa-client/libs/admin/settings/src/lib/postfach/postfach-container/postfach-form/postfach.formservice.spec.ts b/alfa-client/libs/admin/settings/src/lib/postfach/postfach-container/postfach-form/postfach.formservice.spec.ts index bbc93c26a6744ea5ae695e9c4400bdeccfdb1f72..07b58e65ee3cc1b822146f3f5d671dd7192a81d2 100644 --- a/alfa-client/libs/admin/settings/src/lib/postfach/postfach-container/postfach-form/postfach.formservice.spec.ts +++ b/alfa-client/libs/admin/settings/src/lib/postfach/postfach-container/postfach-form/postfach.formservice.spec.ts @@ -1,6 +1,7 @@ import { createStateResource, StateResource } from '@alfa-client/tech-shared'; -import { mock, Mock, useFromMock } from '@alfa-client/test-utils'; -import { FormBuilder } from '@angular/forms'; +import { mock, Mock } from '@alfa-client/test-utils'; +import { TestBed } from '@angular/core/testing'; +import { UntypedFormBuilder } from '@angular/forms'; import { of } from 'rxjs'; import { createPostfach, createPostfachResource } from '../../../../../test/postfach/postfach'; import { Postfach, PostfachResource } from '../../postfach.model'; @@ -10,22 +11,27 @@ import { PostfachFormService } from './postfach.formservice'; describe('PostfachFormService', () => { let formService: PostfachFormService; let postfachService: Mock<PostfachService>; - const formBuilder: FormBuilder = new FormBuilder(); beforeEach(() => { postfachService = mock(PostfachService); - formService = new PostfachFormService(formBuilder, useFromMock(postfachService)); + + TestBed.configureTestingModule({ + providers: [PostfachFormService, UntypedFormBuilder, { provide: PostfachService, useValue: postfachService }], + }); + + formService = TestBed.inject(PostfachFormService); + TestBed.inject(PostfachService); }); it('should create', () => { expect(formService).toBeTruthy(); }); + describe('submit', () => { const postfach: Postfach = createPostfach(); beforeEach(() => { - const stateResource: StateResource<PostfachResource> = - createStateResource(createPostfachResource()); + const stateResource: StateResource<PostfachResource> = createStateResource(createPostfachResource()); postfachService.save.mockReturnValue(of(stateResource)); postfachService.get.mockReturnValue(of(stateResource)); formService.form.setValue({ @@ -69,8 +75,7 @@ describe('PostfachFormService', () => { }); it('should call save with absender if any present', () => { - formValueWithAbsender[PostfachFormService.ASBSENDER_GROUP][PostfachFormService.NAME_FIELD] = - 'something'; + formValueWithAbsender[PostfachFormService.ASBSENDER_GROUP][PostfachFormService.NAME_FIELD] = 'something'; formService.form.setValue(formValueWithAbsender); formService.submit(); diff --git a/alfa-client/libs/admin/settings/src/lib/postfach/postfach-container/postfach-form/postfach.formservice.ts b/alfa-client/libs/admin/settings/src/lib/postfach/postfach-container/postfach-form/postfach.formservice.ts index dd9bcc7a3732f8562aa596faa52b1b4b70407f26..63b83ffccaea662ec02004ff479f0f7a688b47db 100644 --- a/alfa-client/libs/admin/settings/src/lib/postfach/postfach-container/postfach-form/postfach.formservice.ts +++ b/alfa-client/libs/admin/settings/src/lib/postfach/postfach-container/postfach-form/postfach.formservice.ts @@ -1,6 +1,6 @@ import { AbstractFormService, EMPTY_STRING, StateResource } from '@alfa-client/tech-shared'; -import { Injectable } from '@angular/core'; -import { FormControl, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { inject, Injectable } from '@angular/core'; +import { FormControl, UntypedFormGroup } from '@angular/forms'; import { isNil } from 'lodash-es'; import { Observable } from 'rxjs'; import { Postfach, PostfachResource } from '../../postfach.model'; @@ -8,6 +8,8 @@ import { PostfachService } from '../../postfach.service'; @Injectable() export class PostfachFormService extends AbstractFormService { + private postfachService: PostfachService = inject(PostfachService); + public static readonly ASBSENDER_GROUP: string = 'absender'; public static readonly NAME_FIELD: string = 'name'; public static readonly ANSCHRIFT_FIELD: string = 'anschrift'; @@ -17,13 +19,6 @@ export class PostfachFormService extends AbstractFormService { public static readonly SIGNATUR_FIELD: string = 'signatur'; - constructor( - formBuilder: UntypedFormBuilder, - private postfachService: PostfachService, - ) { - super(formBuilder); - } - protected initForm(): UntypedFormGroup { return this.formBuilder.group({ [PostfachFormService.ASBSENDER_GROUP]: this.formBuilder.group({ diff --git a/alfa-client/libs/admin/settings/src/lib/shared/more-menu/more-item-button/more-item-button.component.html b/alfa-client/libs/admin/settings/src/lib/shared/more-menu/more-item-button/more-item-button.component.html deleted file mode 100644 index 26ff86713579d5505c52823e6dacb3e429b627cf..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/settings/src/lib/shared/more-menu/more-item-button/more-item-button.component.html +++ /dev/null @@ -1,7 +0,0 @@ -<button - (click)="clickEmitter.emit($event)" - [disabled]="disabled" - class="w-full bg-white px-3 py-2 text-sm font-semibold shadow-sm hover:bg-gray-50 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ozgblue-500 active:bg-ozgblue-200" -> - {{ label }} -</button> diff --git a/alfa-client/libs/admin/settings/src/lib/shared/more-menu/more-item-button/more-item-button.component.spec.ts b/alfa-client/libs/admin/settings/src/lib/shared/more-menu/more-item-button/more-item-button.component.spec.ts deleted file mode 100644 index 8d9b522ce93961b555b8c26e0621734e33af7237..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/settings/src/lib/shared/more-menu/more-item-button/more-item-button.component.spec.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { dispatchEventFromFixture, getElementFromFixture } from '@alfa-client/test-utils'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MoreItemButtonComponent } from './more-item-button.component'; - -describe('MoreItemButtonComponent', () => { - let component: MoreItemButtonComponent; - let fixture: ComponentFixture<MoreItemButtonComponent>; - - const buttonSelector: string = 'button'; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [MoreItemButtonComponent], - }).compileComponents(); - - fixture = TestBed.createComponent(MoreItemButtonComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - it('should show label', () => { - const text: string = 'test-text'; - component.label = text; - - fixture.detectChanges(); - - const buttonElement: HTMLButtonElement = getElementFromFixture(fixture, buttonSelector); - expect(buttonElement.textContent.trim()).toEqual(text); - }); - - it.each([false, true])('should use disabled "%s"', (disabled) => { - component.disabled = disabled; - - fixture.detectChanges(); - - const buttonElement: HTMLButtonElement = getElementFromFixture(fixture, buttonSelector); - expect(buttonElement.disabled).toBe(disabled); - }); - - it('should emit clickEmitter', () => { - component.clickEmitter.emit = jest.fn(); - - dispatchEventFromFixture(fixture, buttonSelector, 'click'); - - expect(component.clickEmitter.emit).toHaveBeenCalled(); - }); -}); diff --git a/alfa-client/libs/admin/settings/src/lib/shared/more-menu/more-item-button/more-item-button.component.ts b/alfa-client/libs/admin/settings/src/lib/shared/more-menu/more-item-button/more-item-button.component.ts deleted file mode 100644 index 843abd3d47661e76d184df6109f9c253095499ad..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/settings/src/lib/shared/more-menu/more-item-button/more-item-button.component.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Component, EventEmitter, Input, Output } from '@angular/core'; - -@Component({ - selector: 'admin-more-item-button', - templateUrl: './more-item-button.component.html', - styles: [], -}) -export class MoreItemButtonComponent { - @Output() - clickEmitter: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>(); - - @Input() - disabled: boolean; - - @Input() - label: string; -} diff --git a/alfa-client/libs/admin/settings/src/lib/shared/more-menu/more-menu.component.html b/alfa-client/libs/admin/settings/src/lib/shared/more-menu/more-menu.component.html deleted file mode 100644 index 08b802175695977a9b8c23d127932f4873b03ec2..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/settings/src/lib/shared/more-menu/more-menu.component.html +++ /dev/null @@ -1,23 +0,0 @@ -<div class="group relative inline-block text-[0px]"> - <button class="active:bg-ozgblue-`00 rounded-full bg-gray-50 text-base hover:bg-ozgblue-200"> - <svg - xmlns="http://www.w3.org/2000/svg" - fill="none" - viewBox="0 0 24 24" - stroke-width="1.5" - stroke="currentColor" - class="h-6 w-6 stroke-ozgblue-700" - > - <path - stroke-linecap="round" - stroke-linejoin="round" - d="M12 6.75a.75.75 0 1 1 0-1.5.75.75 0 0 1 0 1.5ZM12 12.75a.75.75 0 1 1 0-1.5.75.75 0 0 1 0 1.5ZM12 18.75a.75.75 0 1 1 0-1.5.75.75 0 0 1 0 1.5Z" - /> - </svg> - </button> - <div - class="absolute z-20 hidden flex-col items-stretch text-base drop-shadow-lg group-focus-within:flex" - > - <ng-content select="[more-menu-item]" /> - </div> -</div> diff --git a/alfa-client/libs/admin/settings/src/lib/shared/more-menu/more-menu.component.spec.ts b/alfa-client/libs/admin/settings/src/lib/shared/more-menu/more-menu.component.spec.ts deleted file mode 100644 index fd081be8ddb9eb66b376e68d7bdc2cba9139d8f2..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/settings/src/lib/shared/more-menu/more-menu.component.spec.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MoreMenuComponent } from './more-menu.component'; - -describe('MoreMenuComponent', () => { - let component: MoreMenuComponent; - let fixture: ComponentFixture<MoreMenuComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [MoreMenuComponent], - }).compileComponents(); - - fixture = TestBed.createComponent(MoreMenuComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/alfa-client/libs/admin/settings/src/lib/shared/more-menu/more-menu.component.ts b/alfa-client/libs/admin/settings/src/lib/shared/more-menu/more-menu.component.ts deleted file mode 100644 index 897af6c72e72bf7bfe679079e24fbdb4b46a2304..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/settings/src/lib/shared/more-menu/more-menu.component.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - selector: 'admin-more-menu', - templateUrl: './more-menu.component.html', - styles: [], -}) -export class MoreMenuComponent {} diff --git a/alfa-client/libs/admin/settings/src/lib/shared/navigation-item/navigation-item.component.html b/alfa-client/libs/admin/settings/src/lib/shared/navigation-item/navigation-item.component.html deleted file mode 100644 index 60776b3e9972546299317c813e0fd34c7b5d7be8..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/settings/src/lib/shared/navigation-item/navigation-item.component.html +++ /dev/null @@ -1,9 +0,0 @@ -<a - [routerLink]="link" - routerLinkActive="active-link" - data-test-id="anchor" - class="mb-1 flex items-center gap-4 rounded-full p-3 font-semibold hover:bg-ozgblue-200 active:bg-ozgblue-200/75" -> - <img [src]="imageSrc" [alt]="name" class="w-6" [attr.data-test-id]="'image-' + name" /> - <span [attr.data-test-id]="'navigation-label-' + name | convertForDataTest">{{ name }}</span> -</a> diff --git a/alfa-client/libs/admin/settings/src/lib/shared/navigation-item/navigation-item.component.scss b/alfa-client/libs/admin/settings/src/lib/shared/navigation-item/navigation-item.component.scss deleted file mode 100644 index 9214426c081848ac1a46efac41e715a120eeff02..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/settings/src/lib/shared/navigation-item/navigation-item.component.scss +++ /dev/null @@ -1,3 +0,0 @@ -.active-link:not(:hover):not(:active) { - @apply bg-ozgblue-100; -} diff --git a/alfa-client/libs/admin/settings/src/lib/shared/navigation-item/navigation-item.component.spec.ts b/alfa-client/libs/admin/settings/src/lib/shared/navigation-item/navigation-item.component.spec.ts deleted file mode 100644 index 21822ae354e1a6a11629a652220a62edc5d100a0..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/settings/src/lib/shared/navigation-item/navigation-item.component.spec.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { ConvertForDataTestPipe } from '@alfa-client/tech-shared'; -import { getElementFromFixture } from '@alfa-client/test-utils'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; -import { RouterTestingModule } from '@angular/router/testing'; -import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; -import { NavigationItemComponent } from './navigation-item.component'; - -describe('NavigationItemComponent', () => { - let component: NavigationItemComponent; - let fixture: ComponentFixture<NavigationItemComponent>; - - const anchorLink = getDataTestIdOf('anchor'); - const navigationLabelName = 'test'; - const image = getDataTestIdOf('image-' + navigationLabelName); - const label = getDataTestIdOf('navigation-label-' + navigationLabelName); - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [NavigationItemComponent, ConvertForDataTestPipe], - imports: [ReactiveFormsModule, RouterTestingModule], - }).compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(NavigationItemComponent); - component = fixture.componentInstance; - component.name = 'test'; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - it('should use imageSrc input', () => { - const imageSrc = 'imagesrc'; - component.imageSrc = imageSrc; - - fixture.detectChanges(); - - const imageElement: HTMLImageElement = getElementFromFixture(fixture, image); - expect(imageElement.getAttribute('src')).toBe(imageSrc); - }); - - it('should use router link', () => { - const link = '/testroute'; - component.link = link; - - fixture.detectChanges(); - - const anchorElement: HTMLAnchorElement = getElementFromFixture(fixture, anchorLink); - expect(anchorElement.getAttribute('ng-reflect-router-link')).toBe(link); - }); - - describe('image name', () => { - it('should be used for alt', () => { - const imageElement = getElementFromFixture(fixture, image); - expect(imageElement.alt).toBe(navigationLabelName); - }); - - it('should be used for navigation-label', () => { - const labelElement = getElementFromFixture(fixture, label); - expect(labelElement.textContent).toBe(navigationLabelName); - }); - }); -}); diff --git a/alfa-client/libs/admin/settings/src/lib/shared/navigation-item/navigation-item.component.ts b/alfa-client/libs/admin/settings/src/lib/shared/navigation-item/navigation-item.component.ts deleted file mode 100644 index a7adc2cb8268e576cf6cd38b74e832b6f0de0797..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/settings/src/lib/shared/navigation-item/navigation-item.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component, Input } from '@angular/core'; - -@Component({ - selector: 'admin-navigation-item', - templateUrl: './navigation-item.component.html', - styleUrls: ['./navigation-item.component.scss'], -}) -export class NavigationItemComponent { - @Input() - link: string; - @Input() - imageSrc: string; - @Input() - name = 'Navigations-Link'; -} diff --git a/alfa-client/libs/admin/settings/src/lib/shared/primary-button/primary-button.component.html b/alfa-client/libs/admin/settings/src/lib/shared/primary-button/primary-button.component.html deleted file mode 100644 index d5e7731728de024e1aeba9f9dbfaa4c86728fe0d..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/settings/src/lib/shared/primary-button/primary-button.component.html +++ /dev/null @@ -1,26 +0,0 @@ -<button - (click)="clickEmitter.emit($event)" - [disabled]="submitInProgress" - type="button" - class="me-2 inline-flex items-center rounded-lg bg-ozgblue-700 px-5 py-2.5 text-center text-sm font-medium text-white hover:bg-ozgblue-800 focus:ring-4 focus:ring-ozgblue-300 active:bg-ozgblue-600/90 disabled:bg-ozgblue-600/50 dark:bg-ozgblue-600 dark:hover:bg-ozgblue-700 dark:focus:ring-ozgblue-800" -> - <svg - *ngIf="submitInProgress" - aria-hidden="true" - role="status" - class="me-3 inline h-4 w-4 animate-spin text-white" - viewBox="0 0 100 101" - fill="none" - xmlns="http://www.w3.org/2000/svg" - > - <path - d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z" - fill="#E5E7EB" - /> - <path - d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z" - fill="currentColor" - /> - </svg> - {{ label }} -</button> diff --git a/alfa-client/libs/admin/settings/src/lib/shared/primary-button/primary-button.component.spec.ts b/alfa-client/libs/admin/settings/src/lib/shared/primary-button/primary-button.component.spec.ts deleted file mode 100644 index a48b945b7fabdc55f6c58b44c4cce238c11315de..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/settings/src/lib/shared/primary-button/primary-button.component.spec.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { PrimaryButtonComponent } from './primary-button.component'; - -describe('PrimaryButtonComponent', () => { - let component: PrimaryButtonComponent; - let fixture: ComponentFixture<PrimaryButtonComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [PrimaryButtonComponent], - }).compileComponents(); - - fixture = TestBed.createComponent(PrimaryButtonComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/alfa-client/libs/admin/settings/src/lib/shared/primary-button/primary-button.component.ts b/alfa-client/libs/admin/settings/src/lib/shared/primary-button/primary-button.component.ts deleted file mode 100644 index 365dd569dae6f5a1cf82c94eab2215c70249b815..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/settings/src/lib/shared/primary-button/primary-button.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Component, EventEmitter, Input, Output } from '@angular/core'; - -@Component({ - selector: 'admin-primary-button', - templateUrl: './primary-button.component.html', -}) -export class PrimaryButtonComponent { - @Output() - clickEmitter: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>(); - - @Input() - submitInProgress: boolean; - - @Input() - label: string; -} diff --git a/alfa-client/libs/admin/settings/src/lib/shared/secondary-button/secondary-button.component.html b/alfa-client/libs/admin/settings/src/lib/shared/secondary-button/secondary-button.component.html deleted file mode 100644 index 9129a6ce150aad72c0d6dbf2ee7c8ce7f0b36195..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/settings/src/lib/shared/secondary-button/secondary-button.component.html +++ /dev/null @@ -1,7 +0,0 @@ -<button - (click)="clickEmitter.emit($event)" - [disabled]="disabled" - class="rounded border border-ozgblue-500 bg-transparent px-4 py-2 font-semibold text-ozgblue-700 hover:border-transparent hover:bg-ozgblue-500 hover:text-white active:bg-ozgblue-500/70" -> - {{ label }} -</button> diff --git a/alfa-client/libs/admin/settings/src/lib/shared/secondary-button/secondary-button.component.spec.ts b/alfa-client/libs/admin/settings/src/lib/shared/secondary-button/secondary-button.component.spec.ts deleted file mode 100644 index c50d78977381f148ddf59e6fa27020a88d74e43c..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/settings/src/lib/shared/secondary-button/secondary-button.component.spec.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { SecondaryButtonComponent } from './secondary-button.component'; - -describe('SecondaryButtonComponent', () => { - let component: SecondaryButtonComponent; - let fixture: ComponentFixture<SecondaryButtonComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [SecondaryButtonComponent], - }).compileComponents(); - - fixture = TestBed.createComponent(SecondaryButtonComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/alfa-client/libs/admin/settings/src/lib/shared/secondary-button/secondary-button.component.ts b/alfa-client/libs/admin/settings/src/lib/shared/secondary-button/secondary-button.component.ts deleted file mode 100644 index 99bcd42bee927b79e8dda0cf39cfae5ac17d43f7..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/settings/src/lib/shared/secondary-button/secondary-button.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Component, EventEmitter, Input, Output } from '@angular/core'; - -@Component({ - selector: 'admin-secondary-button', - templateUrl: './secondary-button.component.html', -}) -export class SecondaryButtonComponent { - @Output() - clickEmitter: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>(); - - @Input() - disabled: boolean; - - @Input() - label: string; -} diff --git a/alfa-client/libs/admin/settings/src/lib/shared/spinner/spinner.component.html b/alfa-client/libs/admin/settings/src/lib/shared/spinner/spinner.component.html deleted file mode 100644 index 44ef993322a3dd799dfd5b807a11a8ed8d08fc3c..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/settings/src/lib/shared/spinner/spinner.component.html +++ /dev/null @@ -1,4 +0,0 @@ -<div - class="text-surface inline-block h-8 w-8 animate-spin rounded-full border-4 border-solid border-ozgblue-500 border-e-transparent align-[-0.125em] motion-reduce:animate-[spin_1.5s_linear_infinite] dark:text-white" - role="status" -></div> diff --git a/alfa-client/libs/admin/settings/src/lib/shared/spinner/spinner.component.spec.ts b/alfa-client/libs/admin/settings/src/lib/shared/spinner/spinner.component.spec.ts deleted file mode 100644 index 8c8fd9ebc126388ce720aaadbbfd46d6d29bcd84..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/settings/src/lib/shared/spinner/spinner.component.spec.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { SpinnerComponent } from './spinner.component'; - -describe('SpinnerComponent', () => { - let component: SpinnerComponent; - let fixture: ComponentFixture<SpinnerComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [SpinnerComponent], - }).compileComponents(); - - fixture = TestBed.createComponent(SpinnerComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/alfa-client/libs/admin/settings/src/lib/shared/spinner/spinner.component.ts b/alfa-client/libs/admin/settings/src/lib/shared/spinner/spinner.component.ts deleted file mode 100644 index ea1d1c44e703219a43d5a7ee25c4919e14ec8749..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/settings/src/lib/shared/spinner/spinner.component.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - selector: 'admin-spinner', - templateUrl: './spinner.component.html', - styles: [], -}) -export class SpinnerComponent {} diff --git a/alfa-client/libs/admin/settings/src/lib/shared/text-field/text-field.component.html b/alfa-client/libs/admin/settings/src/lib/shared/text-field/text-field.component.html deleted file mode 100644 index 303f8720da7e44c2cdcc5618f70a64d366e4c64e..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/settings/src/lib/shared/text-field/text-field.component.html +++ /dev/null @@ -1,23 +0,0 @@ -<div class="flex flex-col"> - <label class="grid grid-cols-2 items-center"> - <span - [attr.data-test-id]="'text-field-span-' + label | convertForDataTest" - [ngClass]="control?.invalid ? ['text-red-500', 'font-bold'] : []" - >{{ label }}</span - > - <input - class="m-[2px] p-[2px] outline outline-2 outline-gray-100 focus:outline-0 focus:outline-gray-500" - [attr.data-test-id]="'text-field-input-' + label | convertForDataTest" - type="text" - [formControl]="fieldControl" - /> - </label> - <div - *ngIf="invalidParams.length > 0" - [attr.data-test-id]="'text-field-errors-' + label | convertForDataTest" - > - <span class="mb-3 italic text-red-500" *ngFor="let invalidParam of invalidParams">{{ - getErrorMessage(invalidParam) - }}</span> - </div> -</div> diff --git a/alfa-client/libs/admin/settings/src/lib/shared/text-field/text-field.component.spec.ts b/alfa-client/libs/admin/settings/src/lib/shared/text-field/text-field.component.spec.ts deleted file mode 100644 index 9096bedd3ab98897a3adc9474b291c7703144572..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/settings/src/lib/shared/text-field/text-field.component.spec.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { ConvertForDataTestPipe, InvalidParam } from '@alfa-client/tech-shared'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; -import { createInvalidParam, createProblemDetail } from 'libs/tech-shared/test/error'; -import { TextFieldComponent } from './text-field.component'; - -import * as TechValidationUtil from 'libs/tech-shared/src/lib/validation/tech.validation.util'; - -describe('TextFieldComponent', () => { - let component: TextFieldComponent; - let fixture: ComponentFixture<TextFieldComponent>; - - const label = 'custom'; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [TextFieldComponent, ConvertForDataTestPipe], - imports: [ReactiveFormsModule], - }).compileComponents(); - - fixture = TestBed.createComponent(TextFieldComponent); - component = fixture.componentInstance; - component.label = label; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('getErrorMessage', () => { - it('should call getMessageForInvalidParam()', () => { - const getMessageForInvalidParam: jest.SpyInstance<string, [string, InvalidParam]> = - jest.spyOn(TechValidationUtil, 'getMessageForInvalidParam'); - const invalidParam: InvalidParam = createInvalidParam(); - - component.getErrorMessage(invalidParam); - - expect(getMessageForInvalidParam).toHaveBeenCalledWith(label, invalidParam); - }); - }); - - describe('show error messages', () => { - it('should not call getErrorMessage() if no error', () => { - component.getErrorMessage = jest.fn(); - component.fieldControl.setErrors({}); - - fixture.detectChanges(); - - expect(component.getErrorMessage).not.toHaveBeenCalled(); - }); - - it('should call getErrorMessage() if error', () => { - component.getErrorMessage = jest.fn(); - - component.fieldControl.setErrors({ - ...createProblemDetail(), - invalidParams: [{ ...createInvalidParam(), name: 'settingBody.absender.name' }], - }); - - fixture.detectChanges(); - - expect(component.getErrorMessage).toHaveBeenCalled(); - }); - }); -}); diff --git a/alfa-client/libs/admin/settings/src/lib/shared/text-field/text-field.component.ts b/alfa-client/libs/admin/settings/src/lib/shared/text-field/text-field.component.ts deleted file mode 100644 index 00037394425175ac3fcca9fe68b1ba286e3c6315..0000000000000000000000000000000000000000 --- a/alfa-client/libs/admin/settings/src/lib/shared/text-field/text-field.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { getMessageForInvalidParam, InvalidParam } from '@alfa-client/tech-shared'; -import { Component, Input } from '@angular/core'; -import { FormControlEditorAbstractComponent } from '@ods/component'; - -@Component({ - selector: 'text-field', - templateUrl: './text-field.component.html', -}) -export class TextFieldComponent extends FormControlEditorAbstractComponent { - @Input() - label: string; - - public getErrorMessage(invalidParam: InvalidParam): string { - return getMessageForInvalidParam(this.label, invalidParam); - } -} diff --git a/alfa-client/libs/admin/settings/src/lib/users-roles/user-add-form/user-add-form.component.html b/alfa-client/libs/admin/settings/src/lib/users-roles/user-add-form/user-add-form.component.html new file mode 100644 index 0000000000000000000000000000000000000000..1536bc42050127ed1f837d7a36de32b1ef513025 --- /dev/null +++ b/alfa-client/libs/admin/settings/src/lib/users-roles/user-add-form/user-add-form.component.html @@ -0,0 +1,28 @@ +<div class="max-w-[960px]" [formGroup]="formService.form"> + <h1 class="heading-1 mb-4">Benutzer anlegen</h1> + <div class="mb-4 grid gap-4 xl:grid-cols-2"> + <ods-text-editor [formControlName]="UserAddFormService.VORNAME" label="Vorname" required="true" /> + <ods-text-editor [formControlName]="UserAddFormService.NACHNAME" label="Nachname" required="true" /> + <ods-text-editor [formControlName]="UserAddFormService.BENUTZERNAME" label="Benutzername" required="true" /> + <ods-text-editor [formControlName]="UserAddFormService.EMAIL" label="E-Mail" required="true" /> + </div> + + <h3 class="text-md mb-4 block font-medium text-text">Organisationseinheiten</h3> + <ods-button-with-spinner text="Organisationseinheit hinzufügen" variant="outline" dataTestId="Add-organisationseinheit-button" /> + + <h2 class="heading-2 mt-4">Rollen für OZG-Cloud</h2> + <div [formGroupName]="UserAddFormService.ROLLEN_GROUP" class="mb-8 flex gap-56"> + <div [formGroupName]="UserAddFormService.ADMINISTRATION_GROUP" class="flex flex-col gap-2"> + <h3 class="text-md block font-medium text-text">Administration</h3> + <ods-checkbox-editor [formControlName]="UserAddFormService.ADMIN" label="Admin" inputId="admin" /> + </div> + <div [formGroupName]="UserAddFormService.ALFA_GROUP" class="flex flex-col gap-2"> + <h3 class="text-md block font-medium text-text">Alfa</h3> + <ods-checkbox-editor [formControlName]="UserAddFormService.LOESCHEN" label="Löschen" inputId="delete" /> + <ods-checkbox-editor [formControlName]="UserAddFormService.USER" label="User" inputId="user" /> + <ods-checkbox-editor [formControlName]="UserAddFormService.POSTSTELLE" label="Poststelle" inputId="post_office" /> + </div> + </div> + + <ods-button-with-spinner text="Speichern" dataTestId="save-button" /> +</div> diff --git a/alfa-client/libs/admin/settings/src/lib/users-roles/user-add-form/user-add-form.component.spec.ts b/alfa-client/libs/admin/settings/src/lib/users-roles/user-add-form/user-add-form.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..079e9ce8630f1e18fe93ba2d48d55997e9c6d378 --- /dev/null +++ b/alfa-client/libs/admin/settings/src/lib/users-roles/user-add-form/user-add-form.component.spec.ts @@ -0,0 +1,25 @@ +import { CommonModule } from '@angular/common'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ReactiveFormsModule } from '@angular/forms'; +import { ButtonWithSpinnerComponent, CheckboxEditorComponent, TextEditorComponent } from '@ods/component'; +import { UserAddFormComponent } from './user-add-form.component'; + +describe('UserAddFormComponent', () => { + let component: UserAddFormComponent; + let fixture: ComponentFixture<UserAddFormComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [UserAddFormComponent], + imports: [CommonModule, ButtonWithSpinnerComponent, ReactiveFormsModule, TextEditorComponent, CheckboxEditorComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(UserAddFormComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/alfa-client/libs/admin/settings/src/lib/users-roles/user-add-form/user-add-form.component.ts b/alfa-client/libs/admin/settings/src/lib/users-roles/user-add-form/user-add-form.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..ee7830b3127a701025620bc208c559b2c05eb6d4 --- /dev/null +++ b/alfa-client/libs/admin/settings/src/lib/users-roles/user-add-form/user-add-form.component.ts @@ -0,0 +1,13 @@ +import { Component, inject } from '@angular/core'; +import { UserAddFormService } from './user-add-form.service'; + +@Component({ + selector: 'admin-user-add-form', + providers: [UserAddFormService], + templateUrl: './user-add-form.component.html', +}) +export class UserAddFormComponent { + formService = inject(UserAddFormService); + + protected readonly UserAddFormService = UserAddFormService; +} diff --git a/alfa-client/libs/admin/settings/src/lib/users-roles/user-add-form/user-add-form.service.ts b/alfa-client/libs/admin/settings/src/lib/users-roles/user-add-form/user-add-form.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..f497893d00505e06c0170387a582f9d27fa35745 --- /dev/null +++ b/alfa-client/libs/admin/settings/src/lib/users-roles/user-add-form/user-add-form.service.ts @@ -0,0 +1,91 @@ +import { AbstractFormService, EMPTY_STRING, StateResource } from '@alfa-client/tech-shared'; +import { Injectable } from '@angular/core'; +import { AbstractControl, FormControl, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { Resource } from '@ngxp/rest'; +import { Observable } from 'rxjs'; + +@Injectable() +export class UserAddFormService extends AbstractFormService { + public static readonly VORNAME: string = 'vorname'; + public static readonly NACHNAME: string = 'nachname'; + public static readonly BENUTZERNAME: string = 'benutzername'; + public static readonly EMAIL: string = 'e-mail'; + + public static readonly ROLLEN_GROUP: string = 'rollen'; + public static readonly ADMINISTRATION_GROUP: string = 'administration'; + public static readonly ADMIN: string = 'admin'; + public static readonly ALFA_GROUP: string = 'alfa'; + public static readonly LOESCHEN: string = 'loeschen'; + public static readonly USER: string = 'user'; + public static readonly POSTSTELLE: string = 'poststelle'; + + public static readonly USER_ADD_PREFIX: string = 'userAdd'; + + constructor(public formBuilder: UntypedFormBuilder) { + super(formBuilder); + this.initAlfaGroupLogic(); + } + + protected initForm(): UntypedFormGroup { + return this.formBuilder.group({ + [UserAddFormService.VORNAME]: new FormControl(EMPTY_STRING), + [UserAddFormService.NACHNAME]: new FormControl(EMPTY_STRING), + [UserAddFormService.BENUTZERNAME]: new FormControl(EMPTY_STRING), + [UserAddFormService.EMAIL]: new FormControl(EMPTY_STRING), + [UserAddFormService.ROLLEN_GROUP]: this.formBuilder.group({ + [UserAddFormService.ADMINISTRATION_GROUP]: this.formBuilder.group({ + [UserAddFormService.ADMIN]: new FormControl(false), + }), + [UserAddFormService.ALFA_GROUP]: this.formBuilder.group({ + [UserAddFormService.LOESCHEN]: new FormControl(false), + [UserAddFormService.USER]: new FormControl(false), + [UserAddFormService.POSTSTELLE]: new FormControl(false), + }), + }), + }); + } + + protected initAlfaGroupLogic(): void { + const alfaGroup: UntypedFormGroup = this.getAlfaGroup(); + alfaGroup.valueChanges.subscribe(() => { + this.handleAlfaGroupChange(alfaGroup); + }); + } + + private getAlfaGroup(): UntypedFormGroup { + return <UntypedFormGroup>this.form.get(UserAddFormService.ROLLEN_GROUP).get(UserAddFormService.ALFA_GROUP); + } + + handleAlfaGroupChange(group: UntypedFormGroup): void { + const anyChecked: boolean = this.isAnyChecked(group); + if (anyChecked) { + this.disableUncheckedCheckboxes(group); + } else { + this.enableAllCheckboxes(group); + } + } + + isAnyChecked(group: UntypedFormGroup): boolean { + return Object.keys(group.controls).some((key) => group.controls[key].value); + } + + disableUncheckedCheckboxes(alfaGroup: UntypedFormGroup): void { + for (const control of Object.values<AbstractControl>(alfaGroup.controls)) { + if (control.value === false) control.disable({ emitEvent: false }); + } + } + + enableAllCheckboxes(group: UntypedFormGroup): void { + for (const control of Object.values<AbstractControl>(group.controls)) { + control.enable({ emitEvent: false }); + } + } + + protected doSubmit(): Observable<StateResource<Resource>> { + throw new Error('Method not implemented.'); + } + + protected getPathPrefix(): string { + return UserAddFormService.USER_ADD_PREFIX; + } +} diff --git a/alfa-client/libs/admin/settings/src/lib/users-roles/user-add-form/user-add-formservice.spec.ts b/alfa-client/libs/admin/settings/src/lib/users-roles/user-add-form/user-add-formservice.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..82048540fdf5cfbaa2da64004a03673670168f92 --- /dev/null +++ b/alfa-client/libs/admin/settings/src/lib/users-roles/user-add-form/user-add-formservice.spec.ts @@ -0,0 +1,112 @@ +import { fakeAsync, TestBed, tick } from '@angular/core/testing'; +import { AbstractControl, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { UserAddFormService } from './user-add-form.service'; +import SpyInstance = jest.SpyInstance; + +describe('UserAddFormService', () => { + let formService: UserAddFormService; + let alfaGroup: UntypedFormGroup; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [UserAddFormService, UntypedFormBuilder], + }); + + formService = TestBed.inject(UserAddFormService); + alfaGroup = <UntypedFormGroup>formService.form.get(UserAddFormService.ROLLEN_GROUP).get(UserAddFormService.ALFA_GROUP); + }); + + it('should create', () => { + expect(formService).toBeTruthy(); + }); + + describe('initAlfaGroupLogic', () => { + it('should call handleAlfaGroupChange when value of form element changes', fakeAsync(() => { + const handleAlfaGroupChangeSpy: SpyInstance = jest.spyOn(formService as any, 'handleAlfaGroupChange'); + + alfaGroup.get(UserAddFormService.LOESCHEN).setValue(true); + + tick(); + + expect(handleAlfaGroupChangeSpy).toHaveBeenCalled(); + })); + }); + + describe('handleAlfaGroupChange', () => { + it('should call disableUncheckedCheckboxes if any checkbox is checked', () => { + jest.spyOn(formService as any, 'isAnyChecked').mockReturnValue(true); + const disableUncheckedCheckboxesSpy: SpyInstance = jest.spyOn(formService as any, 'disableUncheckedCheckboxes'); + + formService.handleAlfaGroupChange(alfaGroup); + + expect(disableUncheckedCheckboxesSpy).toHaveBeenCalled(); + }); + + it('should call enableAllCheckboxes if not any checkbox is checked', () => { + jest.spyOn(formService as any, 'isAnyChecked').mockReturnValue(false); + const enableAllCheckboxesSpy: SpyInstance = jest.spyOn(formService as any, 'enableAllCheckboxes'); + + formService.handleAlfaGroupChange(alfaGroup); + + expect(enableAllCheckboxesSpy).toHaveBeenCalled(); + }); + }); + + describe('isAnyChecked', () => { + it('should return false if no checkbox is checked', () => { + const result = formService.isAnyChecked(alfaGroup); + + expect(result).toBe(false); + }); + + it('should return true if any checkbox is checked', () => { + alfaGroup.get(UserAddFormService.LOESCHEN).setValue(true); + + const result = formService.isAnyChecked(alfaGroup); + + expect(result).toBe(true); + }); + }); + + describe('disableUncheckedCheckboxes', () => { + it('if control value is false then control should be disabled', () => { + const control: AbstractControl = alfaGroup.get(UserAddFormService.LOESCHEN); + control.setValue(false); + + formService.disableUncheckedCheckboxes(alfaGroup); + + expect(control.disabled).toBe(true); + }); + + it('if control value is true then control should NOT be disabled', () => { + const control: AbstractControl = alfaGroup.get(UserAddFormService.LOESCHEN); + control.setValue(true); + + formService.disableUncheckedCheckboxes(alfaGroup); + + expect(control.disabled).toBe(false); + }); + }); + + describe('updateCheckboxStates', () => { + it('if control value is false then control should be disabled', () => { + const control: AbstractControl = alfaGroup.get(UserAddFormService.LOESCHEN); + control.setValue(false); + + formService.disableUncheckedCheckboxes(alfaGroup); + + expect(control.disabled).toBe(true); + }); + }); + + describe('enableAllCheckboxes', () => { + it('if control value is true then control should be enabled', () => { + const control: AbstractControl = alfaGroup.get(UserAddFormService.LOESCHEN); + const enableSpy = jest.spyOn(control, 'enable'); + + formService.enableAllCheckboxes(alfaGroup); + + expect(enableSpy).toHaveBeenCalled(); + }); + }); +}); diff --git a/alfa-client/libs/admin/settings/src/lib/users-roles/users-roles.component.html b/alfa-client/libs/admin/settings/src/lib/users-roles/users-roles.component.html index 09160afabe086d514782957cb31784a715e747f1..b9d08648462df8ef917ab8c201bd0f8948e68165 100644 --- a/alfa-client/libs/admin/settings/src/lib/users-roles/users-roles.component.html +++ b/alfa-client/libs/admin/settings/src/lib/users-roles/users-roles.component.html @@ -1,7 +1,12 @@ <h1 class="heading-1">Benutzer & Rollen</h1> -<ods-button-with-spinner text="Benutzer hinzufügen" class="py-8" dataTestId="add-user-button" /> +<ods-button-with-spinner + text="Benutzer hinzufügen" + class="py-8" + dataTestId="Add-user-button" + (clickEmitter)="navigateToAddUser()" +/> <ods-list *ngIf="users$ | async as users"> - <ods-list-item *ngFor="let user of users.resource" [path]="user.username"> + <ods-list-item *ngFor="let user of users.resource" [path]="user.username" [attr.data-test-id]="'User-entry-' + user.username"> <div class="flex-1 basis-1/2"> <div class="mb-2 flex flex-wrap items-center gap-3"> <h3 class="text-md font-semibold">{{ user | toUserName }}</h3> diff --git a/alfa-client/libs/admin/settings/src/lib/users-roles/users-roles.component.spec.ts b/alfa-client/libs/admin/settings/src/lib/users-roles/users-roles.component.spec.ts index 49182ee84673fa793f0cbe0ee14eb694ab6f2319..d7c6ca07647f7f99249ee4bf6bf1c0eb33634f58 100644 --- a/alfa-client/libs/admin/settings/src/lib/users-roles/users-roles.component.spec.ts +++ b/alfa-client/libs/admin/settings/src/lib/users-roles/users-roles.component.spec.ts @@ -1,8 +1,12 @@ +import { createStateResource } from '@alfa-client/tech-shared'; import { Mock, mock } from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { Router } from '@angular/router'; import { ButtonWithSpinnerComponent } from '@ods/component'; import { MailboxIconComponent, PersonIconComponent } from '@ods/system'; import { MockComponent, MockPipe } from 'ng-mocks'; +import { ROUTES } from '../../../../shared'; +import { createUser } from '../../../test/user/user'; import { ToUserNamePipe } from '../user/to-user-name.pipe'; import { UserService } from './user.service'; import { UsersRolesComponent } from './users-roles.component'; @@ -10,6 +14,7 @@ import { UsersRolesComponent } from './users-roles.component'; describe('UsersRolesComponent', () => { let component: UsersRolesComponent; let fixture: ComponentFixture<UsersRolesComponent>; + let router: Router; const userService: Mock<UserService> = { ...mock(UserService), @@ -28,11 +33,37 @@ describe('UsersRolesComponent', () => { ], }).compileComponents(); + TestBed.inject(UserService); + router = TestBed.inject(Router); + fixture = TestBed.createComponent(UsersRolesComponent); component = fixture.componentInstance; fixture.detectChanges(); }); + describe('component', () => { + describe('ngOnInit', () => { + it('should get users from userService', () => { + const userState = createStateResource([createUser()]); + userService.get.mockReturnValueOnce(userState); + + component.ngOnInit(); + + expect(component.users$).toBe(userState); + }); + }); + + describe('navigateToAddUser', () => { + it('should navigate to add user', () => { + const routerSpy = jest.spyOn(router as any, 'navigate'); + + component.navigateToAddUser(); + + expect(routerSpy).toHaveBeenCalledWith([ROUTES.BENUTZER_UND_ROLLEN_NEU]); + }); + }); + }); + describe('template', () => { it('should create', () => { expect(component).toBeTruthy(); diff --git a/alfa-client/libs/admin/settings/src/lib/users-roles/users-roles.component.ts b/alfa-client/libs/admin/settings/src/lib/users-roles/users-roles.component.ts index 46003c627d6c355241eba06d875e49d4d7df0f2b..b9fead2dca191c13c751519b63ba94c4c794b466 100644 --- a/alfa-client/libs/admin/settings/src/lib/users-roles/users-roles.component.ts +++ b/alfa-client/libs/admin/settings/src/lib/users-roles/users-roles.component.ts @@ -1,6 +1,8 @@ import { StateResource } from '@alfa-client/tech-shared'; -import { Component } from '@angular/core'; +import { Component, inject, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; import { Observable } from 'rxjs'; +import { ROUTES } from '../../../../shared/libs/routes'; import { User } from '../user/user.model'; import { UserService } from './user.service'; @@ -8,11 +10,18 @@ import { UserService } from './user.service'; selector: 'admin-users-roles', templateUrl: './users-roles.component.html', }) -export class UsersRolesComponent { +export class UsersRolesComponent implements OnInit { + private router = inject(Router); + private userService = inject(UserService); + public users$: Observable<StateResource<User[]>>; public readonly GROUPS_TO_DISPLAY = 3; - constructor(private userService: UserService) { + ngOnInit() { this.users$ = this.userService.get(); } + + navigateToAddUser(): void { + this.router.navigate([ROUTES.BENUTZER_UND_ROLLEN_NEU]); + } } diff --git a/alfa-client/libs/admin/shared/index.ts b/alfa-client/libs/admin/shared/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..e41b2f175f471052508f2cab70d1f33dae2a2d27 --- /dev/null +++ b/alfa-client/libs/admin/shared/index.ts @@ -0,0 +1 @@ +export * from './libs/routes'; diff --git a/alfa-client/libs/admin/shared/libs/routes.ts b/alfa-client/libs/admin/shared/libs/routes.ts new file mode 100644 index 0000000000000000000000000000000000000000..631028e873a7a4815b9bdefe0b7331b6fbca099c --- /dev/null +++ b/alfa-client/libs/admin/shared/libs/routes.ts @@ -0,0 +1,6 @@ +export const ROUTES = { + POSTFACH: 'postfach', + BENUTZER_UND_ROLLEN: 'benutzer_und_rollen', + BENUTZER_UND_ROLLEN_NEU: 'benutzer_und_rollen/neu', + ORGANISATIONSEINHEITEN: 'organisationseinheiten', +}; diff --git a/alfa-client/libs/common/.eslintrc.json b/alfa-client/libs/common/.eslintrc.json new file mode 100644 index 0000000000000000000000000000000000000000..6685b2e35bbf3f0d58387f6617c9bd749c0c55f2 --- /dev/null +++ b/alfa-client/libs/common/.eslintrc.json @@ -0,0 +1,45 @@ +{ + "extends": ["../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": ["plugin:@nx/angular", "plugin:@angular-eslint/template/process-inline-templates"], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "lib", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "lib", + "style": "kebab-case" + } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nx/angular-template"], + "rules": {} + }, + { + "files": ["*.json"], + "parser": "jsonc-eslint-parser", + "rules": { + "@nx/dependency-checks": [ + "error", + { + "ignoredFiles": ["{projectRoot}/eslint.config.{js,cjs,mjs}"] + } + ] + } + } + ] +} diff --git a/alfa-client/libs/common/README.md b/alfa-client/libs/common/README.md new file mode 100644 index 0000000000000000000000000000000000000000..dd1a64c606a0de52c0f174b2239362bd9ea5a717 --- /dev/null +++ b/alfa-client/libs/common/README.md @@ -0,0 +1,7 @@ +# common + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test common` to execute the unit tests. diff --git a/alfa-client/libs/common/jest.config.ts b/alfa-client/libs/common/jest.config.ts new file mode 100644 index 0000000000000000000000000000000000000000..cc270a9a40a45f60ca8b165405c609383b92ebc6 --- /dev/null +++ b/alfa-client/libs/common/jest.config.ts @@ -0,0 +1,21 @@ +export default { + displayName: 'common', + preset: '../../jest.preset.js', + setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'], + coverageDirectory: '../../coverage/libs/common', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '<rootDir>/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/alfa-client/libs/common/project.json b/alfa-client/libs/common/project.json new file mode 100644 index 0000000000000000000000000000000000000000..75ea075f15e55a052c0cc5e7f02564ae3748e547 --- /dev/null +++ b/alfa-client/libs/common/project.json @@ -0,0 +1,20 @@ +{ + "name": "common", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/common/src", + "prefix": "lib", + "projectType": "library", + "tags": [], + "targets": { + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "libs/common/jest.config.ts" + } + }, + "lint": { + "executor": "@nx/eslint:lint" + } + } +} diff --git a/alfa-client/libs/common/src/index.ts b/alfa-client/libs/common/src/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..f8f49f20b7993383fbce5faf8a3db0b1524766a0 --- /dev/null +++ b/alfa-client/libs/common/src/index.ts @@ -0,0 +1 @@ +export * from './lib/build-info/build-info.component'; diff --git a/alfa-client/libs/navigation/src/lib/build-info/build-info.component.html b/alfa-client/libs/common/src/lib/build-info/build-info.component.html similarity index 95% rename from alfa-client/libs/navigation/src/lib/build-info/build-info.component.html rename to alfa-client/libs/common/src/lib/build-info/build-info.component.html index 41cce668006927fdd81db4f1c49e8eaca49358cd..097debe503d2855dd2fed9cd631badf65e9f1836 100644 --- a/alfa-client/libs/navigation/src/lib/build-info/build-info.component.html +++ b/alfa-client/libs/common/src/lib/build-info/build-info.component.html @@ -30,6 +30,4 @@ <span data-test-id="build-time">{{ buildTime }}</span> </ng-container> </p> -<p *ngIf="isNotProduction" data-test-id="not-production-text" class="test-environment text-error"> - Achtung Testumgebung -</p> +<p *ngIf="isNotProduction" data-test-id="not-production-text" class="test-environment">Achtung Testumgebung</p> diff --git a/alfa-client/libs/navigation/src/lib/build-info/build-info.component.scss b/alfa-client/libs/common/src/lib/build-info/build-info.component.scss similarity index 95% rename from alfa-client/libs/navigation/src/lib/build-info/build-info.component.scss rename to alfa-client/libs/common/src/lib/build-info/build-info.component.scss index 73f433970c0765f31b0f88b78a30fad26513afdb..2764bb91702a4060dda18b98c81fae6ad74b90c7 100644 --- a/alfa-client/libs/navigation/src/lib/build-info/build-info.component.scss +++ b/alfa-client/libs/common/src/lib/build-info/build-info.component.scss @@ -36,10 +36,6 @@ transform-origin: right bottom; } -:host-context(.dark) { - color: #ccc; -} - p { margin: 0; line-height: 1; @@ -47,7 +43,7 @@ p { font-style: normal; font-weight: 400; font-size: 0.6875rem; - color: #999; + color: theme('colors.text/70'); &.version { span { @@ -61,4 +57,5 @@ p { margin-right: $navigation-height + $header-height; letter-spacing: 0.42em; text-transform: uppercase; + color: theme('colors.error'); } diff --git a/alfa-client/libs/navigation/src/lib/build-info/build-info.component.spec.ts b/alfa-client/libs/common/src/lib/build-info/build-info.component.spec.ts similarity index 97% rename from alfa-client/libs/navigation/src/lib/build-info/build-info.component.spec.ts rename to alfa-client/libs/common/src/lib/build-info/build-info.component.spec.ts index 663ad95f94a684c5b02cae60201ed823b66e4eab..ee6c655e9b27be5f653ac86eb2fbafbcb57400de 100644 --- a/alfa-client/libs/navigation/src/lib/build-info/build-info.component.spec.ts +++ b/alfa-client/libs/common/src/lib/build-info/build-info.component.spec.ts @@ -21,10 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ +import { FormatDateWithTimePipe } from '@alfa-client/tech-shared'; import { registerLocaleData } from '@angular/common'; import localeDe from '@angular/common/locales/de'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { FormatDateWithTimePipe } from '@alfa-client/tech-shared'; import { createApiRootResource } from 'libs/api-root-shared/test/api-root'; import { BuildInfoComponent } from './build-info.component'; @@ -47,7 +47,8 @@ describe('BuildInfoComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [BuildInfoComponent, FormatDateWithTimePipe], + imports: [BuildInfoComponent], + declarations: [FormatDateWithTimePipe], }).compileComponents(); }); diff --git a/alfa-client/libs/navigation/src/lib/build-info/build-info.component.ts b/alfa-client/libs/common/src/lib/build-info/build-info.component.ts similarity index 94% rename from alfa-client/libs/navigation/src/lib/build-info/build-info.component.ts rename to alfa-client/libs/common/src/lib/build-info/build-info.component.ts index be8f576c3288bfb1818b1976030e5f0894a10d8d..8d7182c2f837679916ebc9b91ee0dc7ed382ca63 100644 --- a/alfa-client/libs/navigation/src/lib/build-info/build-info.component.ts +++ b/alfa-client/libs/common/src/lib/build-info/build-info.component.ts @@ -21,13 +21,16 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { Component, Input } from '@angular/core'; import { ApiRootResource } from '@alfa-client/api-root-shared'; +import { Component, Input } from '@angular/core'; import * as DateUtil from '@alfa-client/tech-shared'; +import { CommonModule } from '@angular/common'; @Component({ selector: 'alfa-build-info', + imports: [CommonModule], + standalone: true, templateUrl: './build-info.component.html', styleUrls: ['./build-info.component.scss'], }) diff --git a/alfa-client/libs/common/src/test-setup.ts b/alfa-client/libs/common/src/test-setup.ts new file mode 100644 index 0000000000000000000000000000000000000000..f7fad5e59f9d4e62a097bbea63040551de396175 --- /dev/null +++ b/alfa-client/libs/common/src/test-setup.ts @@ -0,0 +1,11 @@ +import 'jest-preset-angular/setup-jest'; + +import { getTestBed } from '@angular/core/testing'; +import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; + +getTestBed().resetTestEnvironment(); +getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting(), { + teardown: { destroyAfterEach: false }, + errorOnUnknownProperties: true, + errorOnUnknownElements: true, +}); diff --git a/alfa-client/libs/common/tailwind.config.js b/alfa-client/libs/common/tailwind.config.js new file mode 100644 index 0000000000000000000000000000000000000000..d9b5f51f460d135ef0a5398164cf2a820caaa020 --- /dev/null +++ b/alfa-client/libs/common/tailwind.config.js @@ -0,0 +1,14 @@ +const { createGlobPatternsForDependencies } = require('@nx/angular/tailwind'); +const { join } = require('path'); + +const sharedTailwindConfig = require('../../libs/design-system/src/lib/tailwind-preset/tailwind.config.js'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + presets: [sharedTailwindConfig], + content: [join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'), ...createGlobPatternsForDependencies(__dirname)], + theme: { + extend: {}, + }, + plugins: [], +}; diff --git a/alfa-client/libs/common/tsconfig.json b/alfa-client/libs/common/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..7cc6baf2f58ed5ccfba098131996f579979e9f18 --- /dev/null +++ b/alfa-client/libs/common/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "compilerOptions": { + "target": "es2022" + } +} diff --git a/alfa-client/libs/common/tsconfig.lib.json b/alfa-client/libs/common/tsconfig.lib.json new file mode 100644 index 0000000000000000000000000000000000000000..4cab05d46338c6e9d4dfe6512fd7eb7f60340d3d --- /dev/null +++ b/alfa-client/libs/common/tsconfig.lib.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "declaration": true, + "declarationMap": true, + "inlineSources": true, + "types": [] + }, + "exclude": ["src/**/*.spec.ts", "src/test-setup.ts", "jest.config.ts", "src/**/*.test.ts"], + "include": ["src/**/*.ts"] +} diff --git a/alfa-client/libs/common/tsconfig.lib.prod.json b/alfa-client/libs/common/tsconfig.lib.prod.json new file mode 100644 index 0000000000000000000000000000000000000000..61b523783f299f511f27248a42f86e5f9c29512f --- /dev/null +++ b/alfa-client/libs/common/tsconfig.lib.prod.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.lib.json", + "compilerOptions": { + "declarationMap": false + }, + "angularCompilerOptions": {} +} diff --git a/alfa-client/libs/common/tsconfig.spec.json b/alfa-client/libs/common/tsconfig.spec.json new file mode 100644 index 0000000000000000000000000000000000000000..7870b7c011681fb77d6114001f44d3eeca69975b --- /dev/null +++ b/alfa-client/libs/common/tsconfig.spec.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "target": "es2016", + "types": ["jest", "node"] + }, + "files": ["src/test-setup.ts"], + "include": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"] +} diff --git a/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.html b/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.html index aecfd7e8dcaf39151ce1772d111f06068feb5c45..d099703c582741cc1044529cb41f5783cf472aec 100644 --- a/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.html +++ b/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.html @@ -1,9 +1,8 @@ <ods-checkbox [fieldControl]="fieldControl" - [value]="value" [inputId]="inputId" [label]="label" - [disabled]="disabled" + [disabled]="control.disabled" [hasError]="hasError" > <ods-validation-error diff --git a/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.spec.ts b/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.spec.ts index 9c80662fb8d43561499969f3931569d0cb542e29..53ecd61b001e6ecc4a41e9cfa3dd42b8e44b6ed8 100644 --- a/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.spec.ts +++ b/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.spec.ts @@ -3,6 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { faker } from '@faker-js/faker'; import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; import { createInvalidParam } from 'libs/tech-shared/test/error'; +import { MockNgControl } from '../../../../test/form/MockNgControl'; import { CheckboxEditorComponent } from './checkbox-editor.component'; describe('CheckboxEditorComponent', () => { @@ -20,6 +21,7 @@ describe('CheckboxEditorComponent', () => { fixture = TestBed.createComponent(CheckboxEditorComponent); component = fixture.componentInstance; component.label = labelText; + component.control = new MockNgControl(); fixture.detectChanges(); }); diff --git a/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.ts b/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.ts index 4ed5d7b07e60146f9a3dc471563c855466d888d7..50b10bd356bcd62bb6de90dddc399817704d7581 100644 --- a/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.ts +++ b/alfa-client/libs/design-component/src/lib/form/checkbox-editor/checkbox-editor.component.ts @@ -1,5 +1,6 @@ import { TechSharedModule } from '@alfa-client/tech-shared'; import { Component, Input } from '@angular/core'; +import { ReactiveFormsModule } from '@angular/forms'; import { CheckboxComponent } from '@ods/system'; import { FormControlEditorAbstractComponent } from '../formcontrol-editor.abstract.component'; import { ValidationErrorComponent } from '../validation-error/validation-error.component'; @@ -7,14 +8,12 @@ import { ValidationErrorComponent } from '../validation-error/validation-error.c @Component({ selector: 'ods-checkbox-editor', standalone: true, - imports: [CheckboxComponent, ValidationErrorComponent, TechSharedModule], + imports: [CheckboxComponent, ValidationErrorComponent, TechSharedModule, ReactiveFormsModule], templateUrl: './checkbox-editor.component.html', }) export class CheckboxEditorComponent extends FormControlEditorAbstractComponent { - @Input() value: string; @Input() inputId: string; @Input() label: string; - @Input() disabled: boolean = false; get hasError(): boolean { return this.invalidParams.length > 0; diff --git a/alfa-client/libs/design-component/src/lib/form/formcontrol-editor.abstract.component.ts b/alfa-client/libs/design-component/src/lib/form/formcontrol-editor.abstract.component.ts index cb0f3f5842b32a3ce76321d194097c9a2f64229a..3c1f8d9a1d19fd69416b0dab478500ea65867218 100644 --- a/alfa-client/libs/design-component/src/lib/form/formcontrol-editor.abstract.component.ts +++ b/alfa-client/libs/design-component/src/lib/form/formcontrol-editor.abstract.component.ts @@ -24,15 +24,12 @@ import { InvalidParam } from '@alfa-client/tech-shared'; import { Component, OnDestroy, OnInit, Optional, Self } from '@angular/core'; import { ControlValueAccessor, NgControl, UntypedFormControl } from '@angular/forms'; -import { isEmpty } from 'lodash-es'; import { Subscription } from 'rxjs'; @Component({ template: 'NO UI', }) -export abstract class FormControlEditorAbstractComponent - implements ControlValueAccessor, OnInit, OnDestroy -{ +export abstract class FormControlEditorAbstractComponent implements ControlValueAccessor, OnInit, OnDestroy { readonly fieldControl: UntypedFormControl = new UntypedFormControl(); public onChange = (text: string | Date) => undefined; public onTouched = () => undefined; @@ -46,7 +43,6 @@ export abstract class FormControlEditorAbstractComponent if (this.control) this.control.valueAccessor = this; this.changesSubscr = this.fieldControl.valueChanges.subscribe((val) => { - val = isEmpty(val) ? null : val; this.onChange(val); this.setErrors(); }); @@ -91,9 +87,7 @@ export abstract class FormControlEditorAbstractComponent get invalidParams(): InvalidParam[] { return this.fieldControl.errors ? - Object.keys(this.fieldControl.errors).map( - (key) => <InvalidParam>this.fieldControl.errors[key], - ) + Object.keys(this.fieldControl.errors).map((key) => <InvalidParam>this.fieldControl.errors[key]) : []; } } diff --git a/alfa-client/libs/design-component/test/form/MockNgControl.ts b/alfa-client/libs/design-component/test/form/MockNgControl.ts new file mode 100644 index 0000000000000000000000000000000000000000..80a3bc01a22b76cc868465ded2b84a0b057071ab --- /dev/null +++ b/alfa-client/libs/design-component/test/form/MockNgControl.ts @@ -0,0 +1,13 @@ +import { Injectable } from '@angular/core'; +import { AbstractControl, ControlValueAccessor, NgControl, UntypedFormControl } from '@angular/forms'; + +@Injectable() +export class MockNgControl extends NgControl { + valueAccessor: ControlValueAccessor | null = null; + + get control(): AbstractControl { + return new UntypedFormControl(null); + } + + viewToModelUpdate(newValue: any): void {} +} diff --git a/alfa-client/libs/design-system/src/lib/dropdown-menu/dropdown-menu/dropdown-menu.component.ts b/alfa-client/libs/design-system/src/lib/dropdown-menu/dropdown-menu/dropdown-menu.component.ts index 48e99e18034cb8ce18dfaf82b433b288d983b12c..02a78af00276c13f33a7874dc1781f4c325624b3 100644 --- a/alfa-client/libs/design-system/src/lib/dropdown-menu/dropdown-menu/dropdown-menu.component.ts +++ b/alfa-client/libs/design-system/src/lib/dropdown-menu/dropdown-menu/dropdown-menu.component.ts @@ -25,8 +25,7 @@ import { twMerge } from 'tailwind-merge'; </button> <div *ngIf="isPopupOpen" - class="bg-dropdownBg absolute max-h-120 min-w-44 max-w-80 - animate-fadeIn overflow-y-auto rounded shadow-md focus:outline-none" + class="absolute z-50 max-h-120 min-w-44 max-w-80 animate-fadeIn overflow-y-auto rounded bg-dropdownBg shadow-md focus:outline-none" [ngClass]="alignTo === 'left' ? 'right-0' : 'left-0'" role="menu" aria-modal="true" diff --git a/alfa-client/libs/design-system/src/lib/form/checkbox/checkbox.component.ts b/alfa-client/libs/design-system/src/lib/form/checkbox/checkbox.component.ts index 9cab0abad5aa6845f9a6f622fa7bfde8ca3d35ec..3fbc1b80bfb06f3aac9a6af622920803a313100b 100644 --- a/alfa-client/libs/design-system/src/lib/form/checkbox/checkbox.component.ts +++ b/alfa-client/libs/design-system/src/lib/form/checkbox/checkbox.component.ts @@ -1,3 +1,4 @@ +import { TechSharedModule } from '@alfa-client/tech-shared'; import { CommonModule } from '@angular/common'; import { Component, Input } from '@angular/core'; import { FormControl, ReactiveFormsModule } from '@angular/forms'; @@ -5,24 +6,22 @@ import { FormControl, ReactiveFormsModule } from '@angular/forms'; @Component({ selector: 'ods-checkbox', standalone: true, - imports: [CommonModule, ReactiveFormsModule], + imports: [CommonModule, ReactiveFormsModule, TechSharedModule], template: ` <div> - <div class="flex items-start gap-3 text-start"> + <div class="relative flex items-start gap-3 text-start"> <input type="checkbox" - class="disabled:border-disabled-dark disabled:bg-disabled peer relative box-border size-5 shrink-0 appearance-none rounded-sm - border bg-whitetext outline outline-2 outline-offset-2 outline-transparent - hover:border-2 focus-visible:border-background-200 disabled:hover:border" + class="peer box-border size-5 shrink-0 appearance-none rounded-sm border bg-whitetext outline outline-2 outline-offset-2 outline-transparent hover:border-2 focus-visible:border-background-200 disabled:border-disabled-dark disabled:bg-disabled disabled:hover:border" [ngClass]=" hasError ? 'border-error hover:border-error focus-visible:outline-error' : 'border-primary hover:border-primary-hover focus-visible:outline-focus' " - [value]="value" - [checked]="fieldControl.value" + [formControl]="fieldControl" [attr.id]="inputId" - [disabled]="disabled" + [attr.disabled]="disabled ? true : null" + [attr.data-test-id]="(label | convertForDataTest) + '-checkbox-editor'" /> <label class="leading-5 text-text" [attr.for]="inputId">{{ label }}</label> <svg @@ -43,7 +42,6 @@ import { FormControl, ReactiveFormsModule } from '@angular/forms'; }) export class CheckboxComponent { @Input() fieldControl: FormControl = new FormControl(false); - @Input() value: string; @Input() inputId: string; @Input() label: string; @Input() disabled: boolean = false; diff --git a/alfa-client/libs/design-system/src/lib/form/checkbox/checkbox.stories.ts b/alfa-client/libs/design-system/src/lib/form/checkbox/checkbox.stories.ts index ce8dd243e62d68c65d58f4298744e5ded9ebedf6..c7a56bc1fa4a36b16977718cc68b6ca445b25f30 100644 --- a/alfa-client/libs/design-system/src/lib/form/checkbox/checkbox.stories.ts +++ b/alfa-client/libs/design-system/src/lib/form/checkbox/checkbox.stories.ts @@ -22,7 +22,6 @@ type Story = StoryObj<CheckboxComponent>; export const Default: Story = { args: { - value: 'Checkbox value', label: 'Basic checkbox', inputId: '1', disabled: false, @@ -32,7 +31,6 @@ export const Default: Story = { label: { description: 'Checkbox label' }, disabled: { description: 'Disabled state of checkbox' }, inputId: { description: 'Id of checkbox input' }, - value: { description: 'Value of checkbox' }, hasError: { description: 'Has checkbox the error state' }, fieldControl: { description: 'Form control object', diff --git a/alfa-client/libs/design-system/src/lib/form/text-input/text-input.component.ts b/alfa-client/libs/design-system/src/lib/form/text-input/text-input.component.ts index a534a5276d34b072c1b8edee6e95e362a5296d77..58dcedb8b91762b9155936d039e9b383e12dcb8f 100644 --- a/alfa-client/libs/design-system/src/lib/form/text-input/text-input.component.ts +++ b/alfa-client/libs/design-system/src/lib/form/text-input/text-input.component.ts @@ -3,7 +3,6 @@ import { CommonModule } from '@angular/common'; import { Component, ElementRef, EventEmitter, Input, Output, ViewChild } from '@angular/core'; import { FormControl, ReactiveFormsModule } from '@angular/forms'; import { cva, VariantProps } from 'class-variance-authority'; -import { ErrorMessageComponent } from '../error-message/error-message.component'; const textInputVariants = cva( [ @@ -15,8 +14,7 @@ const textInputVariants = cva( variant: { default: 'border-primary-600/50 focus-visible:outline-focus focus-visible:border-background-200 hover:border-primary-hover', - error: - 'border-error/50 hover:border-error focus-visible:outline-error focus-visible:border-background-200', + error: 'border-error/50 hover:border-error focus-visible:outline-error focus-visible:border-background-200', }, }, defaultVariants: { @@ -29,28 +27,21 @@ type TextInputVariants = VariantProps<typeof textInputVariants>; @Component({ selector: 'ods-text-input', standalone: true, - imports: [CommonModule, ErrorMessageComponent, ReactiveFormsModule, TechSharedModule], + imports: [CommonModule, ReactiveFormsModule, TechSharedModule], template: ` <div class="relative"> <label *ngIf="showLabel" [for]="id" class="text-md mb-2 block font-medium text-text"> {{ inputLabel }}<ng-container *ngIf="required"><i aria-hidden="true">*</i></ng-container> </label> <div class="mt-2"> - <div - *ngIf="withPrefix" - class="pointer-events-none absolute bottom-2 left-2 flex size-6 items-center justify-center" - > + <div *ngIf="withPrefix" class="pointer-events-none absolute bottom-2 left-2 flex size-6 items-center justify-center"> <ng-content select="[prefix]" /> </div> <input type="text" [id]="id" [formControl]="fieldControl" - [ngClass]="[ - textInputVariants({ variant }), - withPrefix ? 'pl-10' : '', - withSuffix ? 'pr-10' : '', - ]" + [ngClass]="[textInputVariants({ variant }), withPrefix ? 'pl-10' : '', withSuffix ? 'pr-10' : '']" [placeholder]="placeholder" [autocomplete]="autocomplete" [attr.aria-required]="required" @@ -59,10 +50,7 @@ type TextInputVariants = VariantProps<typeof textInputVariants>; (click)="clickEmitter.emit()" #inputElement /> - <div - *ngIf="withSuffix" - class="absolute bottom-2 right-2 flex size-6 items-center justify-center" - > + <div *ngIf="withSuffix" class="absolute bottom-2 right-2 flex size-6 items-center justify-center"> <ng-content select="[suffix]" /> </div> </div> diff --git a/alfa-client/libs/design-system/src/lib/list/list-item/list-item.component.spec.ts b/alfa-client/libs/design-system/src/lib/list/list-item/list-item.component.spec.ts index 0aef13978f11b606c0be0d6e0dbb6c297e8149e0..04eeffba56f4a341b60d448202972da84925cf35 100644 --- a/alfa-client/libs/design-system/src/lib/list/list-item/list-item.component.spec.ts +++ b/alfa-client/libs/design-system/src/lib/list/list-item/list-item.component.spec.ts @@ -27,7 +27,7 @@ describe('ListItemComponent', () => { describe('input', () => { describe('routerLink', () => { it('should set href attribute', () => { - component.path = faker.system.filePath(); + component.path = encodeURI(faker.system.filePath()); const resultingLink: string = 'http://localhost' + component.path; const linkElement: HTMLLinkElement = getElementFromFixture(fixture, getDataTestClassOf('list-item-link')); diff --git a/alfa-client/libs/navigation/src/lib/navigation.module.ts b/alfa-client/libs/navigation/src/lib/navigation.module.ts index 0a98c2c4232b12ea4f7e1004d30f8828bdd0769f..1622cf215a88c546c52288e1ffdda3c1d28075b2 100644 --- a/alfa-client/libs/navigation/src/lib/navigation.module.ts +++ b/alfa-client/libs/navigation/src/lib/navigation.module.ts @@ -21,26 +21,20 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; import { UiModule } from '@alfa-client/ui'; import { UserAssistanceModule } from '@alfa-client/user-assistance'; import { UserProfileModule } from '@alfa-client/user-profile'; import { UserSettingsModule } from '@alfa-client/user-settings'; import { VorgangSharedUiModule } from '@alfa-client/vorgang-shared-ui'; -import { BuildInfoComponent } from './build-info/build-info.component'; +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; import { HeaderContainerComponent } from './header-container/header-container.component'; import { HeaderLogoComponent } from './header-container/header/header-logo/header-logo.component'; import { HeaderComponent } from './header-container/header/header.component'; @NgModule({ - declarations: [ - BuildInfoComponent, - HeaderComponent, - HeaderContainerComponent, - HeaderLogoComponent, - ], + declarations: [HeaderComponent, HeaderContainerComponent, HeaderLogoComponent], imports: [ CommonModule, UiModule, @@ -50,6 +44,6 @@ import { HeaderComponent } from './header-container/header/header.component'; UserSettingsModule, UserAssistanceModule, ], - exports: [BuildInfoComponent, HeaderContainerComponent], + exports: [HeaderContainerComponent], }) export class NavigationModule {} diff --git a/alfa-client/libs/tech-shared/src/lib/service/formservice.abstract.ts b/alfa-client/libs/tech-shared/src/lib/service/formservice.abstract.ts index e14057ca1213095531293412d81b4952f80e5e1d..c2a00e20b56393869eb2be605d6585d1a85564b4 100644 --- a/alfa-client/libs/tech-shared/src/lib/service/formservice.abstract.ts +++ b/alfa-client/libs/tech-shared/src/lib/service/formservice.abstract.ts @@ -23,6 +23,7 @@ */ import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { Injectable } from '@angular/core'; import { Resource } from '@ngxp/rest'; import { isNil } from 'lodash-es'; import { identity, Observable, OperatorFunction } from 'rxjs'; @@ -32,6 +33,7 @@ import { HttpError, InvalidParam, ProblemDetail } from '../tech.model'; import { isNotUndefined } from '../tech.util'; import { setInvalidParamValidationError } from '../validation/tech.validation.util'; +@Injectable() export abstract class AbstractFormService<T extends Resource = Resource> { form: UntypedFormGroup; pathPrefix: string; diff --git a/alfa-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.component.spec.ts b/alfa-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.component.spec.ts index ca73c782d282523f6ae32f0ef50fa9ec872d217f..6fa40dfad1eb725845134bfb68d2259d0e6ae6ea 100644 --- a/alfa-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.component.spec.ts +++ b/alfa-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.component.spec.ts @@ -30,21 +30,11 @@ import { createEmptyStateResource, createStateResource, } from '@alfa-client/tech-shared'; -import { - dispatchEventFromFixture, - getElementFromFixture, - mock, - useFromMock, -} from '@alfa-client/test-utils'; +import { dispatchEventFromFixture, getElementFromFixture, mock, useFromMock } from '@alfa-client/test-utils'; import { SpinnerComponent } from '@alfa-client/ui'; import { VorgangHeaderLinkRel, VorgangListService } from '@alfa-client/vorgang-shared'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { - ReactiveFormsModule, - UntypedFormBuilder, - UntypedFormControl, - UntypedFormGroup, -} from '@angular/forms'; +import { ReactiveFormsModule, UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms'; import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatButton } from '@angular/material/button'; import { MatFormFieldModule } from '@angular/material/form-field'; @@ -224,21 +214,15 @@ describe('VorgangSearchComponent', () => { const result = component.buildSearchResultPreviewLabel(vorgangList); - expect(result).toBe( - '10 Vorschläge werden angezeigt, nutze Pfeiltaste nach unten, um diese zu erreichen', - ); + expect(result).toBe('10 Vorschläge werden angezeigt, nutze Pfeiltaste nach unten, um diese zu erreichen'); }); it('should return label for one search result', () => { - const vorgangList = createStateResource( - createVorgangListResourceWithResource([createVorgangResource()]), - ); + const vorgangList = createStateResource(createVorgangListResourceWithResource([createVorgangResource()])); const result = component.buildSearchResultPreviewLabel(vorgangList); - expect(result).toBe( - 'Ein Vorschlag wird angezeigt, nutze Pfeiltaste nach unten, um den zu erreichen', - ); + expect(result).toBe('Ein Vorschlag wird angezeigt, nutze Pfeiltaste nach unten, um diesen zu erreichen'); }); it('should return empty string', () => { @@ -298,6 +282,17 @@ describe('VorgangSearchComponent', () => { }); }); + describe('onKeydownHandler', () => { + it('should call formService setLastKeyPressed with key', () => { + const setLastKeyPressedSpy = jest.spyOn(VorgangSearchFormService.prototype, 'setLastKeyPressed'); + const keyboardEvent: KeyboardEvent = new KeyboardEvent('keydown', { key: 'Enter' }); + + component.onKeydownHandler(keyboardEvent); + + expect(setLastKeyPressedSpy).toHaveBeenCalledWith('Enter'); + }); + }); + describe('submit', () => { it('should not navigate to search if search field is empty', () => { const submitSpy = jest.spyOn(NavigationService.prototype, 'search'); diff --git a/alfa-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.component.ts b/alfa-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.component.ts index 7857c502c95a7b38bed14c9a85ef50d8a748a68a..e0c72ccc0a96eb5fd90cd4d66d262ea0484dfeea 100644 --- a/alfa-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.component.ts +++ b/alfa-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.component.ts @@ -21,27 +21,9 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { - EMPTY_STRING, - StateResource, - getEmbeddedResources, - isNotNil, -} from '@alfa-client/tech-shared'; -import { - VorgangHeaderLinkRel, - VorgangListLinkRel, - VorgangListResource, -} from '@alfa-client/vorgang-shared'; -import { - Component, - ElementRef, - EventEmitter, - Input, - OnDestroy, - OnInit, - Output, - ViewChild, -} from '@angular/core'; +import { EMPTY_STRING, StateResource, getEmbeddedResources, isNotNil } from '@alfa-client/tech-shared'; +import { VorgangHeaderLinkRel, VorgangListLinkRel, VorgangListResource } from '@alfa-client/vorgang-shared'; +import { Component, ElementRef, EventEmitter, HostListener, Input, OnDestroy, OnInit, Output, ViewChild } from '@angular/core'; import { MatAutocomplete } from '@angular/material/autocomplete'; import { MatButton } from '@angular/material/button'; import { Event, NavigationEnd, Router } from '@angular/router'; @@ -56,9 +38,7 @@ import { VorgangSearchFormService } from './vorgang-search.formservice'; providers: [VorgangSearchFormService], }) export class VorgangSearchComponent implements OnInit, OnDestroy { - @Input() set vorgangSearchPreviewList( - vorgangListStateResource: StateResource<VorgangListResource>, - ) { + @Input() set vorgangSearchPreviewList(vorgangListStateResource: StateResource<VorgangListResource>) { this.vorgangListPreview = vorgangListStateResource; this.searchResultPreviewLabel = this.buildSearchResultPreviewLabel(vorgangListStateResource); } @@ -93,6 +73,11 @@ export class VorgangSearchComponent implements OnInit, OnDestroy { }); } + @HostListener('keydown', ['$event']) + onKeydownHandler(e: KeyboardEvent): void { + this.formService.setLastKeyPressed(e.key); + } + submit(): void { this.previouslyEnteredSearchValue = this.formService.getValue(); this.formService.submit(); @@ -113,15 +98,9 @@ export class VorgangSearchComponent implements OnInit, OnDestroy { } } - buildSearchResultPreviewLabel( - vorgangListStateResource: StateResource<VorgangListResource>, - ): string { - const previewListLength = getEmbeddedResources( - vorgangListStateResource, - this.vorgangListLinkRel.VORGANG_HEADER_LIST, - )?.length; - if (previewListLength === 1) - return 'Ein Vorschlag wird angezeigt, nutze Pfeiltaste nach unten, um den zu erreichen'; + buildSearchResultPreviewLabel(vorgangListStateResource: StateResource<VorgangListResource>): string { + const previewListLength = getEmbeddedResources(vorgangListStateResource, this.vorgangListLinkRel.VORGANG_HEADER_LIST)?.length; + if (previewListLength === 1) return 'Ein Vorschlag wird angezeigt, nutze Pfeiltaste nach unten, um diesen zu erreichen'; if (previewListLength > 1) return `${previewListLength} Vorschläge werden angezeigt, nutze Pfeiltaste nach unten, um diese zu erreichen`; return EMPTY_STRING; diff --git a/alfa-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.formservice.spec.ts b/alfa-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.formservice.spec.ts index 9e639e1a9c66bf31e06c51de51d176fffeb94321..45a888657048c0f222495b8fe905fe58b21ae3e6 100644 --- a/alfa-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.formservice.spec.ts +++ b/alfa-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.formservice.spec.ts @@ -24,11 +24,8 @@ import { NavigationService } from '@alfa-client/navigation-shared'; import { EMPTY_STRING, encodeUrlForEmbedding } from '@alfa-client/tech-shared'; import { Mock, mock, useFromMock } from '@alfa-client/test-utils'; -import { - VorgangHeaderLinkRel, - VorgangListService, - VorgangResource, -} from '@alfa-client/vorgang-shared'; +import { VorgangHeaderLinkRel, VorgangListService, VorgangResource } from '@alfa-client/vorgang-shared'; +import { fakeAsync, tick } from '@angular/core/testing'; import { FormControl, UntypedFormBuilder } from '@angular/forms'; import { Params } from '@angular/router'; import { faker } from '@faker-js/faker'; @@ -74,6 +71,40 @@ describe('VorgangSearchFormService', () => { }); }); + describe('subscribeToValueChanges', () => { + it('should call setHasSearchString after debounce time', fakeAsync(() => { + const value = faker.word.sample(); + const setHasSearchString = jest.spyOn(formService, 'setHasSearchString'); + + formService.subscribeToValueChanges(); + formService.form.controls[formService.SEARCH_FIELD].patchValue(value); + tick(300); + + expect(setHasSearchString).toHaveBeenCalledWith(value); + })); + + it('should call handleValueChange after debounce time', fakeAsync(() => { + const value = faker.word.sample(); + const handleValueChanges = jest.spyOn(formService, 'handleValueChanges'); + + formService.subscribeToValueChanges(); + formService.form.controls[formService.SEARCH_FIELD].patchValue(value); + tick(300); + + expect(handleValueChanges).toHaveBeenCalledWith(value); + })); + + it('should not call handleValueChange if lastKeyPressed is Enter', fakeAsync(() => { + const handleValueChanges = jest.spyOn(formService, 'handleValueChanges'); + formService.setLastKeyPressed('Enter'); + + formService.subscribeToValueChanges(); + tick(300); + + expect(handleValueChanges).not.toHaveBeenCalled(); + })); + }); + describe('handleValueChanges', () => { describe('on should search for preview', () => { beforeEach(() => { @@ -234,9 +265,7 @@ describe('VorgangSearchFormService', () => { }); describe('submitByPreviewList', () => { - const vorgang: VorgangResource = createVorgangResource([ - VorgangHeaderLinkRel.VORGANG_WITH_EINGANG, - ]); + const vorgang: VorgangResource = createVorgangResource([VorgangHeaderLinkRel.VORGANG_WITH_EINGANG]); const searchString: string = faker.person.firstName(); it('should clear searchString', () => { diff --git a/alfa-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.formservice.ts b/alfa-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.formservice.ts index bf88a1381c9a827c61a71dc204f5cbaf820ca63a..b8449f8efc8fff93dda751c99212eb4a67b3bc41 100644 --- a/alfa-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.formservice.ts +++ b/alfa-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.formservice.ts @@ -22,23 +22,13 @@ * unter der Lizenz sind dem Lizenztext zu entnehmen. */ import { NavigationService } from '@alfa-client/navigation-shared'; -import { - EMPTY_STRING, - hasMinLength, - isNotEmpty, - isNotNil, - toResourceUri, -} from '@alfa-client/tech-shared'; -import { - VorgangHeaderLinkRel, - VorgangListService, - VorgangResource, -} from '@alfa-client/vorgang-shared'; +import { EMPTY_STRING, hasMinLength, isNotEmpty, isNotNil, toResourceUri } from '@alfa-client/tech-shared'; +import { VorgangHeaderLinkRel, VorgangListService, VorgangResource } from '@alfa-client/vorgang-shared'; import { Injectable, OnDestroy } from '@angular/core'; import { FormGroup, UntypedFormBuilder, UntypedFormControl } from '@angular/forms'; import { Params } from '@angular/router'; import { isEmpty } from 'lodash-es'; -import { Observable, Subscription } from 'rxjs'; +import { filter, Observable, Subscription } from 'rxjs'; import { debounceTime, distinctUntilChanged, first, tap } from 'rxjs/operators'; @Injectable() @@ -54,6 +44,8 @@ export class VorgangSearchFormService implements OnDestroy { public lastSearchString: string; public hasSearchString: boolean = false; + private lastKeyPressed: string; + constructor( private formBuilder: UntypedFormBuilder, private navigationService: NavigationService, @@ -78,17 +70,24 @@ export class VorgangSearchFormService implements OnDestroy { subscribeToValueChanges(): void { this.fromControlSubscription = this.getSearchFormControl() .valueChanges.pipe( + distinctUntilChanged(), debounceTime(300), + filter(() => this.lastKeyPressedIsNotEnter()), tap((value) => this.setHasSearchString(value)), - distinctUntilChanged(), ) - .subscribe((value) => this.handleValueChanges(value)); + .subscribe((value) => { + this.handleValueChanges(value); + }); } setHasSearchString(value: string): void { this.hasSearchString = isNotEmpty(value); } + private lastKeyPressedIsNotEnter(): boolean { + return this.lastKeyPressed !== 'Enter'; + } + handleValueChanges(value: string): void { if (this.shouldSearchForPreview(value)) { this.vorgangListService.setSearchString(value); @@ -99,9 +98,7 @@ export class VorgangSearchFormService implements OnDestroy { } shouldSearchForPreview(value: string): boolean { - return ( - this.isSearchInputNotPristine() && hasMinLength(value, this.PREVIEW_SEARCH_STRING_MIN_LENGTH) - ); + return this.isSearchInputNotPristine() && hasMinLength(value, this.PREVIEW_SEARCH_STRING_MIN_LENGTH); } isSearchInputNotPristine(): boolean { @@ -150,9 +147,7 @@ export class VorgangSearchFormService implements OnDestroy { } private navigateToVorgang(resource: VorgangResource): void { - this.navigationService.navigateToVorgang( - toResourceUri(resource, VorgangHeaderLinkRel.VORGANG_WITH_EINGANG), - ); + this.navigationService.navigateToVorgang(toResourceUri(resource, VorgangHeaderLinkRel.VORGANG_WITH_EINGANG)); } navigateToVorgangListOnSearch(params: Params) { @@ -178,4 +173,8 @@ export class VorgangSearchFormService implements OnDestroy { public getValueChanges(): Observable<string> { return this.getSearchFormControl().valueChanges; } + + public setLastKeyPressed(key: string): void { + this.lastKeyPressed = key; + } } diff --git a/alfa-client/run_helm_test.sh b/alfa-client/run_helm_test.sh new file mode 100755 index 0000000000000000000000000000000000000000..3fe6199df068b9c8b31b1cb39a1cff113339d871 --- /dev/null +++ b/alfa-client/run_helm_test.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +set -e +set -x + +helm template ./src/main/helm/ -f ./src/test/helm-linter-values.yaml +helm lint -f src/test/helm-linter-values.yaml ./src/main/helm/ +cd src/main/helm && helm unittest -f '../../test/helm/*.yaml' . + diff --git a/alfa-client/src/main/helm/Chart.yaml b/alfa-client/src/main/helm/Chart.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5ab647efd68f962b707bae9e7fd04b72b0c77613 --- /dev/null +++ b/alfa-client/src/main/helm/Chart.yaml @@ -0,0 +1,30 @@ +# +# Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den +# Ministerpräsidenten des Landes Schleswig-Holstein +# Staatskanzlei +# Abteilung Digitalisierung und zentrales IT-Management der Landesregierung +# +# Lizenziert unter der EUPL, Version 1.2 oder - sobald +# diese von der Europäischen Kommission genehmigt wurden - +# Folgeversionen der EUPL ("Lizenz"); +# Sie dürfen dieses Werk ausschließlich gemäß +# dieser Lizenz nutzen. +# Eine Kopie der Lizenz finden Sie hier: +# +# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 +# +# Sofern nicht durch anwendbare Rechtsvorschriften +# gefordert oder in schriftlicher Form vereinbart, wird +# die unter der Lizenz verbreitete Software "so wie sie +# ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - +# ausdrücklich oder stillschweigend - verbreitet. +# Die sprachspezifischen Genehmigungen und Beschränkungen +# unter der Lizenz sind dem Lizenztext zu entnehmen. +# + +apiVersion: v1 +appVersion: '1.0' +description: A Helm chart for Alfa Client +name: alfa-client +version: 0.0.0-MANAGED-BY-JENKINS +icon: https://simpleicons.org/icons/helm.svg diff --git a/alfa-client/src/main/helm/templates/_helpers.tpl b/alfa-client/src/main/helm/templates/_helpers.tpl new file mode 100644 index 0000000000000000000000000000000000000000..300ff51779a0f4679bbc8f31a990f406078947da --- /dev/null +++ b/alfa-client/src/main/helm/templates/_helpers.tpl @@ -0,0 +1,80 @@ + +{{/* error check 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec) */}} +{{/* Namespace */}} +{{- define "app.namespace" -}} +{{- if gt (len (.Release.Namespace)) 63 -}} +{{- fail (printf ".Release.Namespace %s ist zu lang (max. 63 Zeichen)" .Release.Namespace) -}} +{{- end -}} +{{ printf "%s" .Release.Namespace }} +{{- end -}} + +{{/* Chart: Name + Version */}} +{{- define "app.chart" -}} +{{- if gt (len (printf "%s-%s" .Chart.Name .Chart.Version)) 63 -}} +{{- fail (printf ".Chart.Name-.Chart.Version %s-%s ist zu lang (max. 63 Zeichen)" .Chart.Name .Chart.Version) -}} +{{- end -}} +{{ printf "%s-%s" .Chart.Name .Chart.Version }} +{{- end -}} + +{{/* Managed-by -> On Helm, this value is always Helm */}} +{{- define "app.managedBy" -}} +{{- if gt (len (.Release.Service)) 63 -}} +{{- fail (printf ".Release.Service %s ist zu lang (max. 63 Zeichen)" .Release.Service) -}} +{{- end -}} +{{ printf "%s" .Release.Service }} +{{- end -}} + + +{{/* Default Labels: Helm recommended best-practice labels https://helm.sh/docs/chart_best_practices/labels/ */}} +{{- define "app.defaultLabels" }} +app.kubernetes.io/instance: alfa-client +app.kubernetes.io/managed-by: {{ include "app.managedBy" . }} +app.kubernetes.io/name: {{ .Release.Name }} +app.kubernetes.io/namespace: {{ include "app.namespace" . }} +app.kubernetes.io/part-of: ozgcloud +app.kubernetes.io/version: {{ .Chart.Version }} +helm.sh/chart: {{ include "app.chart" . }} +{{- end -}} + +{{- define "app.matchLabels" }} +app.kubernetes.io/name: {{ .Release.Name }} +app.kubernetes.io/namespace: {{ include "app.namespace" . }} +{{- end -}} + +{{- define "app.serviceAccountName" -}} +{{ printf "%s" ( (.Values.serviceAccount).name | default "alfa-client-service-account" ) }} +{{- end -}} + + +{{- define "app.baseDomain" -}} +{{- printf "%s.%s" (include "app.ozgcloudBezeichner" .) (include "app.baseUrl" .) }} +{{- end -}} + +{{- define "app.ozgcloudBezeichner" -}} +{{- required "ozgcloud.bezeichner muss angegeben sein" (.Values.ozgcloud).bezeichner -}} +{{- if lt 46 (len (.Values.ozgcloud).bezeichner) -}} +{{ fail (printf "ozgcloud.bezeichner %s ist zu lang (max. 46 Zeichen)" (.Values.ozgcloud).bezeichner) }} +{{- end -}} +{{- end -}} + +{{- define "app.baseUrl" -}} +{{- required "baseUrl muss angegeben sein" .Values.baseUrl }} +{{- end -}} + +{{- define "app.getCustomList" -}} +{{- with (.Values.env).customList -}} +{{- if kindIs "map" . -}} +{{ include "app.dictToList" . }} +{{- else if kindIs "slice" . -}} +{{ . | toYaml }} +{{- end -}} +{{- end -}} +{{- end -}} + +{{- define "app.dictToList" -}} +{{- $customList := list -}} +{{- range $key, $value := . -}} +{{- $customList = append $customList (dict "name" $key "value" $value) }} +{{- end -}} +{{- $customList | toYaml -}} +{{- end -}} \ No newline at end of file diff --git a/alfa-client/src/main/helm/templates/deployment.yaml b/alfa-client/src/main/helm/templates/deployment.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2f2e951bb88e2e8ef5597021e838f6875e98ff7b --- /dev/null +++ b/alfa-client/src/main/helm/templates/deployment.yaml @@ -0,0 +1,122 @@ +# +# Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den +# Ministerpräsidenten des Landes Schleswig-Holstein +# Staatskanzlei +# Abteilung Digitalisierung und zentrales IT-Management der Landesregierung +# +# Lizenziert unter der EUPL, Version 1.2 oder - sobald +# diese von der Europäischen Kommission genehmigt wurden - +# Folgeversionen der EUPL ("Lizenz"); +# Sie dürfen dieses Werk ausschließlich gemäß +# dieser Lizenz nutzen. +# Eine Kopie der Lizenz finden Sie hier: +# +# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 +# +# Sofern nicht durch anwendbare Rechtsvorschriften +# gefordert oder in schriftlicher Form vereinbart, wird +# die unter der Lizenz verbreitete Software "so wie sie +# ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - +# ausdrücklich oder stillschweigend - verbreitet. +# Die sprachspezifischen Genehmigungen und Beschränkungen +# unter der Lizenz sind dem Lizenztext zu entnehmen. +# + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }} + namespace: {{ include "app.namespace" . }} + labels: + {{- include "app.defaultLabels" . | indent 4 }} +spec: + progressDeadlineSeconds: 600 + replicas: {{ .Values.replicaCount }} + revisionHistoryLimit: 10 + selector: + matchLabels: + {{- include "app.matchLabels" . | indent 6 }} + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + type: RollingUpdate + template: + metadata: + labels: + {{- include "app.defaultLabels" . | indent 8 }} + component: alfa-client + spec: + {{- if (.Values.serviceAccount).create }} + serviceAccountName: {{ include "app.serviceAccountName" . }} + {{- end }} + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + app.kubernetes.io/name: {{ .Release.Name }} + + containers: + - env: + {{- with include "app.getCustomList" . }} +{{ . | indent 8 }} + {{- end }} + + image: "{{ .Values.image.repo }}/{{ .Values.image.name }}:{{ coalesce (.Values.image).tag "latest" }}" + imagePullPolicy: Always + name: alfa-client + + startupProbe: + httpGet: + path: / + port: 8080 + scheme: HTTP + timeoutSeconds: 1 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + readinessProbe: + httpGet: + path: / + port: 8080 + scheme: HTTP + timeoutSeconds: 1 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + + resources: + {{- with .Values.resources }} +{{ toYaml . | indent 10 }} + {{- end }} + securityContext: + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: false + runAsNonRoot: true + {{- with (.Values.securityContext).runAsUser }} + runAsUser: {{ . }} + {{- end }} + {{- with (.Values.securityContext).runAsGroup }} + runAsGroup: {{ . }} + {{- end }} + stdin: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + tty: true + + + dnsConfig: {} + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: {{ required "imagePullSecret must be set" .Values.imagePullSecret }} + restartPolicy: Always + {{- with .Values.hostAliases }} + hostAliases: +{{ toYaml . | indent 8 }} + {{- end }} + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 diff --git a/alfa-client/src/main/helm/templates/ingress.yaml b/alfa-client/src/main/helm/templates/ingress.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9b132c168e1d2b889ace828273b9a2f4be9f97f0 --- /dev/null +++ b/alfa-client/src/main/helm/templates/ingress.yaml @@ -0,0 +1,40 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ .Release.Name }} + namespace: {{ include "app.namespace" . }} + annotations: + {{- if (.Values.ingress).certManagerAnnotations -}} + {{- range (.Values.ingress).certManagerAnnotations }} +{{ . | indent 4 }} + {{- end }} + {{- else if (.Values.ingress).use_staging_cert }} + cert-manager.io/cluster-issuer: letsencrypt-staging + {{- else }} + cert-manager.io/cluster-issuer: letsencrypt-prod + {{- end }} +spec: + {{- if (.Values.ingress).className }} + ingressClassName: {{ .Values.ingress.className }} + {{- end }} + rules: + - http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: {{ .Release.Name }} + port: + number: 8080 + + + host: {{ include "app.baseDomain" . }} + tls: + - hosts: + - {{ include "app.baseDomain" . }} + {{- if (.Values.ingress).tlsSecretName }} + secretName: {{ (.Values.ingress).tlsSecretName }} + {{- else }} + secretName: {{ .Values.ozgcloud.bezeichner }}-{{ .Release.Name }}-tls + {{- end }} \ No newline at end of file diff --git a/alfa-client/src/main/helm/templates/network_policy.yaml b/alfa-client/src/main/helm/templates/network_policy.yaml new file mode 100644 index 0000000000000000000000000000000000000000..be4beaee8f68051efd4fe81f5b951026b23f2d95 --- /dev/null +++ b/alfa-client/src/main/helm/templates/network_policy.yaml @@ -0,0 +1,31 @@ +{{- if not (.Values.networkPolicy).disabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: network-policy-alfa-client + namespace: {{ .Release.Namespace }} +spec: + podSelector: + matchLabels: + {{- include "app.matchLabels" . | indent 6 }} + policyTypes: + - Ingress + - Egress + ingress: + - ports: + - port: 8080 +{{- with (.Values.networkPolicy).additionalIngressConfigLocal }} +{{ toYaml . | indent 2 }} +{{- end }} +{{- with (.Values.networkPolicy).additionalIngressConfigGlobal }} +{{ toYaml . | indent 2 }} +{{- end }} + egress: +{{- with (.Values.networkPolicy).additionalEgressConfigLocal }} +{{ toYaml . | indent 2 }} +{{- end }} +{{- with (.Values.networkPolicy).additionalEgressConfigGlobal }} +{{ toYaml . | indent 2 }} +{{- end }} + +{{- end }} \ No newline at end of file diff --git a/alfa-client/src/main/helm/templates/service.yaml b/alfa-client/src/main/helm/templates/service.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f880d0a8b0ad3d20a1a6171e748dd9ddc8332eb6 --- /dev/null +++ b/alfa-client/src/main/helm/templates/service.yaml @@ -0,0 +1,43 @@ +# +# Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den +# Ministerpräsidenten des Landes Schleswig-Holstein +# Staatskanzlei +# Abteilung Digitalisierung und zentrales IT-Management der Landesregierung +# +# Lizenziert unter der EUPL, Version 1.2 oder - sobald +# diese von der Europäischen Kommission genehmigt wurden - +# Folgeversionen der EUPL ("Lizenz"); +# Sie dürfen dieses Werk ausschließlich gemäß +# dieser Lizenz nutzen. +# Eine Kopie der Lizenz finden Sie hier: +# +# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 +# +# Sofern nicht durch anwendbare Rechtsvorschriften +# gefordert oder in schriftlicher Form vereinbart, wird +# die unter der Lizenz verbreitete Software "so wie sie +# ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - +# ausdrücklich oder stillschweigend - verbreitet. +# Die sprachspezifischen Genehmigungen und Beschränkungen +# unter der Lizenz sind dem Lizenztext zu entnehmen. +# + +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }} + namespace: {{ include "app.namespace" . }} + labels: + {{- include "app.defaultLabels" . | indent 4 }} + component: alfa-client-service +spec: + type: ClusterIP + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 8080 + + selector: + {{- include "app.matchLabels" . | indent 4 }} + component: alfa-client \ No newline at end of file diff --git a/alfa-client/src/main/helm/values.yaml b/alfa-client/src/main/helm/values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..01563f82eb895a00dd6a35619b38c5a7bb717d27 --- /dev/null +++ b/alfa-client/src/main/helm/values.yaml @@ -0,0 +1,6 @@ +image: + repo: docker.ozg-sh.de + name: alfa-client + tag: 0.1.0 # [default: latest] +replicaCount: 1 + diff --git a/alfa-client/src/test/helm-linter-values.yaml b/alfa-client/src/test/helm-linter-values.yaml new file mode 100644 index 0000000000000000000000000000000000000000..243fca6113fc6e4e0f69479e0178e775f2d0c21f --- /dev/null +++ b/alfa-client/src/test/helm-linter-values.yaml @@ -0,0 +1,34 @@ +# +# Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den +# Ministerpräsidenten des Landes Schleswig-Holstein +# Staatskanzlei +# Abteilung Digitalisierung und zentrales IT-Management der Landesregierung +# +# Lizenziert unter der EUPL, Version 1.2 oder - sobald +# diese von der Europäischen Kommission genehmigt wurden - +# Folgeversionen der EUPL ("Lizenz"); +# Sie dürfen dieses Werk ausschließlich gemäß +# dieser Lizenz nutzen. +# Eine Kopie der Lizenz finden Sie hier: +# +# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 +# +# Sofern nicht durch anwendbare Rechtsvorschriften +# gefordert oder in schriftlicher Form vereinbart, wird +# die unter der Lizenz verbreitete Software "so wie sie +# ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - +# ausdrücklich oder stillschweigend - verbreitet. +# Die sprachspezifischen Genehmigungen und Beschränkungen +# unter der Lizenz sind dem Lizenztext zu entnehmen. +# + +baseUrl: test.sh.ozg-cloud.de + +ozgcloud: + bezeichner: helm + +imagePullSecret: test-image-secret + +networkPolicy: + dnsServerNamespace: dummy-dns + diff --git a/alfa-client/src/test/helm/deployment_63_char_test.yaml b/alfa-client/src/test/helm/deployment_63_char_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9aa0a8de91f7f17a01ff1120fa8be31e5aa2fa3d --- /dev/null +++ b/alfa-client/src/test/helm/deployment_63_char_test.yaml @@ -0,0 +1,53 @@ +# +# Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den +# Ministerpräsidenten des Landes Schleswig-Holstein +# Staatskanzlei +# Abteilung Digitalisierung und zentrales IT-Management der Landesregierung +# +# Lizenziert unter der EUPL, Version 1.2 oder - sobald +# diese von der Europäischen Kommission genehmigt wurden - +# Folgeversionen der EUPL ("Lizenz"); +# Sie dürfen dieses Werk ausschließlich gemäß +# dieser Lizenz nutzen. +# Eine Kopie der Lizenz finden Sie hier: +# +# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 +# +# Sofern nicht durch anwendbare Rechtsvorschriften +# gefordert oder in schriftlicher Form vereinbart, wird +# die unter der Lizenz verbreitete Software "so wie sie +# ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - +# ausdrücklich oder stillschweigend - verbreitet. +# Die sprachspezifischen Genehmigungen und Beschränkungen +# unter der Lizenz sind dem Lizenztext zu entnehmen. +# + +suite: test deyploment less than 63 chars +release: + name: alfa-client + namespace: sh-helm-test + +templates: + - templates/deployment.yaml +set: + imagePullSecret: test-image-secret + +tests: + - it: should fail on .Release.Namespace length longer than 63 characters + release: + namespace: test1234567890123123456789012345678901234567890123456789012345678901234567890123456789012345678904567890 + asserts: + - failedTemplate: + errorMessage: .Release.Namespace test1234567890123123456789012345678901234567890123456789012345678901234567890123456789012345678904567890 ist zu lang (max. 63 Zeichen) + - it: should not fail on .Release.Namespace length less than 63 characters + asserts: + - notFailedTemplate: {} + - it: should fail on .Chart.Name-.Chart.Version length longer than 63 characters + chart: + version: 1.0-test1234567890123123456789012345678901234567890123456789012345678901234567890123456789012345678904567890 + asserts: + - failedTemplate: + errorMessage: .Chart.Name-.Chart.Version alfa-client-1.0-test1234567890123123456789012345678901234567890123456789012345678901234567890123456789012345678904567890 ist zu lang (max. 63 Zeichen) + - it: should not fail on .Chart.Name-.Chart.Version length less than 63 characters + asserts: + - notFailedTemplate: {} \ No newline at end of file diff --git a/alfa-client/src/test/helm/deployment_container_basic_test.yaml b/alfa-client/src/test/helm/deployment_container_basic_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..98f94de514785c7cd5401ca79e7abe053e868d6a --- /dev/null +++ b/alfa-client/src/test/helm/deployment_container_basic_test.yaml @@ -0,0 +1,47 @@ +# +# Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den +# Ministerpräsidenten des Landes Schleswig-Holstein +# Staatskanzlei +# Abteilung Digitalisierung und zentrales IT-Management der Landesregierung +# +# Lizenziert unter der EUPL, Version 1.2 oder - sobald +# diese von der Europäischen Kommission genehmigt wurden - +# Folgeversionen der EUPL ("Lizenz"); +# Sie dürfen dieses Werk ausschließlich gemäß +# dieser Lizenz nutzen. +# Eine Kopie der Lizenz finden Sie hier: +# +# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 +# +# Sofern nicht durch anwendbare Rechtsvorschriften +# gefordert oder in schriftlicher Form vereinbart, wird +# die unter der Lizenz verbreitete Software "so wie sie +# ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - +# ausdrücklich oder stillschweigend - verbreitet. +# Die sprachspezifischen Genehmigungen und Beschränkungen +# unter der Lizenz sind dem Lizenztext zu entnehmen. +# + +suite: test deployment container basics +release: + name: alfa-client + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + imagePullSecret: test-image-secret + +tests: + - it: should have correct values for container image, name, imagePullPolicy + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: docker.ozg-sh.de/alfa-client:0.1.0 + - equal: + path: spec.template.spec.containers[0].name + value: alfa-client + - equal: + path: spec.template.spec.containers[0].imagePullPolicy + value: Always + + diff --git a/alfa-client/src/test/helm/deployment_container_other_values_test.yaml b/alfa-client/src/test/helm/deployment_container_other_values_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f8f356b2e2cb81c04ac7664a9e3c1b70958e0363 --- /dev/null +++ b/alfa-client/src/test/helm/deployment_container_other_values_test.yaml @@ -0,0 +1,49 @@ + + # +# Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den +# Ministerpräsidenten des Landes Schleswig-Holstein +# Staatskanzlei +# Abteilung Digitalisierung und zentrales IT-Management der Landesregierung +# +# Lizenziert unter der EUPL, Version 1.2 oder - sobald +# diese von der Europäischen Kommission genehmigt wurden - +# Folgeversionen der EUPL ("Lizenz"); +# Sie dürfen dieses Werk ausschließlich gemäß +# dieser Lizenz nutzen. +# Eine Kopie der Lizenz finden Sie hier: +# +# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 +# +# Sofern nicht durch anwendbare Rechtsvorschriften +# gefordert oder in schriftlicher Form vereinbart, wird +# die unter der Lizenz verbreitete Software "so wie sie +# ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - +# ausdrücklich oder stillschweigend - verbreitet. +# Die sprachspezifischen Genehmigungen und Beschränkungen +# unter der Lizenz sind dem Lizenztext zu entnehmen. +# + +suite: test deployment container other values +release: + name: alfa-client + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + imagePullSecret: test-image-secret + +tests: + - it: should have correct values for container terminationMessagePolicy, terminationMessagePath, stdin, tty + asserts: + - equal: + path: spec.template.spec.containers[0].terminationMessagePolicy + value: File + - equal: + path: spec.template.spec.containers[0].terminationMessagePath + value: /dev/termination-log + - equal: + path: spec.template.spec.containers[0].stdin + value: true + - equal: + path: spec.template.spec.containers[0].tty + value: true \ No newline at end of file diff --git a/alfa-client/src/test/helm/deployment_container_security_context_test.yaml b/alfa-client/src/test/helm/deployment_container_security_context_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..063aac4ae72c7c885a472a2c76b9e10aa3592a0b --- /dev/null +++ b/alfa-client/src/test/helm/deployment_container_security_context_test.yaml @@ -0,0 +1,66 @@ +# +# Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den +# Ministerpräsidenten des Landes Schleswig-Holstein +# Staatskanzlei +# Abteilung Digitalisierung und zentrales IT-Management der Landesregierung +# +# Lizenziert unter der EUPL, Version 1.2 oder - sobald +# diese von der Europäischen Kommission genehmigt wurden - +# Folgeversionen der EUPL ("Lizenz"); +# Sie dürfen dieses Werk ausschließlich gemäß +# dieser Lizenz nutzen. +# Eine Kopie der Lizenz finden Sie hier: +# +# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 +# +# Sofern nicht durch anwendbare Rechtsvorschriften +# gefordert oder in schriftlicher Form vereinbart, wird +# die unter der Lizenz verbreitete Software "so wie sie +# ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - +# ausdrücklich oder stillschweigend - verbreitet. +# Die sprachspezifischen Genehmigungen und Beschränkungen +# unter der Lizenz sind dem Lizenztext zu entnehmen. +# + +suite: test deployment container security context +release: + name: alfa-client + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + imagePullSecret: test-image-secret + +tests: + - it: check default values of spec.containers[0].securityContext + asserts: + - equal: + path: spec.template.spec.containers[0].securityContext.allowPrivilegeEscalation + value: false + - equal: + path: spec.template.spec.containers[0].securityContext.privileged + value: false + - equal: + path: spec.template.spec.containers[0].securityContext.readOnlyRootFilesystem + value: false + - equal: + path: spec.template.spec.containers[0].securityContext.runAsNonRoot + value: true + - isNull: + path: spec.template.spec.containers[0].securityContext.runAsUser + - isNull: + path: spec.template.spec.containers[0].securityContext.runAsGroup + - it: check containers runAsUser + set: + securityContext.runAsUser: 1000 + asserts: + - equal: + path: spec.template.spec.containers[0].securityContext.runAsUser + value: 1000 + - it: check runAsGroup + set: + securityContext.runAsGroup: 1000 + asserts: + - equal: + path: spec.template.spec.containers[0].securityContext.runAsGroup + value: 1000 \ No newline at end of file diff --git a/alfa-client/src/test/helm/deployment_defaults_labels_test.yaml b/alfa-client/src/test/helm/deployment_defaults_labels_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d1ff0f164c2da7abff8098487ba39fb834ceba38 --- /dev/null +++ b/alfa-client/src/test/helm/deployment_defaults_labels_test.yaml @@ -0,0 +1,69 @@ +# +# Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den +# Ministerpräsidenten des Landes Schleswig-Holstein +# Staatskanzlei +# Abteilung Digitalisierung und zentrales IT-Management der Landesregierung +# +# Lizenziert unter der EUPL, Version 1.2 oder - sobald +# diese von der Europäischen Kommission genehmigt wurden - +# Folgeversionen der EUPL ("Lizenz"); +# Sie dürfen dieses Werk ausschließlich gemäß +# dieser Lizenz nutzen. +# Eine Kopie der Lizenz finden Sie hier: +# +# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 +# +# Sofern nicht durch anwendbare Rechtsvorschriften +# gefordert oder in schriftlicher Form vereinbart, wird +# die unter der Lizenz verbreitete Software "so wie sie +# ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - +# ausdrücklich oder stillschweigend - verbreitet. +# Die sprachspezifischen Genehmigungen und Beschränkungen +# unter der Lizenz sind dem Lizenztext zu entnehmen. +# + +suite: test deployment default labels +release: + name: alfa-client + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + imagePullSecret: test-image-secret + +tests: + - it: check metadata.labels + asserts: + - equal: + path: metadata.labels + value: + app.kubernetes.io/instance: alfa-client + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: alfa-client + app.kubernetes.io/namespace: sh-helm-test + app.kubernetes.io/part-of: ozgcloud + app.kubernetes.io/version: 0.0.0-MANAGED-BY-JENKINS + helm.sh/chart: alfa-client-0.0.0-MANAGED-BY-JENKINS + + - it: should set spec.selector.matchLabels + asserts: + - equal: + path: spec.selector.matchLabels + value: + app.kubernetes.io/name: alfa-client + app.kubernetes.io/namespace: sh-helm-test + + + - it: should have correct deyploment spec.template.metadata.labels + asserts: + - equal: + path: spec.template.metadata.labels + value: + app.kubernetes.io/instance: alfa-client + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: alfa-client + app.kubernetes.io/namespace: sh-helm-test + app.kubernetes.io/part-of: ozgcloud + app.kubernetes.io/version: 0.0.0-MANAGED-BY-JENKINS + component: alfa-client + helm.sh/chart: alfa-client-0.0.0-MANAGED-BY-JENKINS \ No newline at end of file diff --git a/alfa-client/src/test/helm/deployment_defaults_topologySpreadConstraints_test.yaml b/alfa-client/src/test/helm/deployment_defaults_topologySpreadConstraints_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1f50b122dcdacdecb722422553e2158907a09971 --- /dev/null +++ b/alfa-client/src/test/helm/deployment_defaults_topologySpreadConstraints_test.yaml @@ -0,0 +1,50 @@ +# +# Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den +# Ministerpräsidenten des Landes Schleswig-Holstein +# Staatskanzlei +# Abteilung Digitalisierung und zentrales IT-Management der Landesregierung +# +# Lizenziert unter der EUPL, Version 1.2 oder - sobald +# diese von der Europäischen Kommission genehmigt wurden - +# Folgeversionen der EUPL ("Lizenz"); +# Sie dürfen dieses Werk ausschließlich gemäß +# dieser Lizenz nutzen. +# Eine Kopie der Lizenz finden Sie hier: +# +# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 +# +# Sofern nicht durch anwendbare Rechtsvorschriften +# gefordert oder in schriftlicher Form vereinbart, wird +# die unter der Lizenz verbreitete Software "so wie sie +# ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - +# ausdrücklich oder stillschweigend - verbreitet. +# Die sprachspezifischen Genehmigungen und Beschränkungen +# unter der Lizenz sind dem Lizenztext zu entnehmen. +# + +suite: test deployment topology spread constrains +release: + name: alfa-client + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + imagePullSecret: test-image-secret + +tests: + - it: check default values of spec.template.spec.topologySpreadConstraints + asserts: + - isKind: + of: Deployment + - equal: + path: spec.template.spec.topologySpreadConstraints[0].maxSkew + value: 1 + - equal: + path: spec.template.spec.topologySpreadConstraints[0].topologyKey + value: kubernetes.io/hostname + - equal: + path: spec.template.spec.topologySpreadConstraints[0].whenUnsatisfiable + value: ScheduleAnyway + - equal: + path: spec.template.spec.topologySpreadConstraints[0].labelSelector.matchLabels["app.kubernetes.io/name"] + value: alfa-client \ No newline at end of file diff --git a/alfa-client/src/test/helm/deployment_env_test.yaml b/alfa-client/src/test/helm/deployment_env_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..802602a558241461dbc490613146e339aee00802 --- /dev/null +++ b/alfa-client/src/test/helm/deployment_env_test.yaml @@ -0,0 +1,72 @@ +# +# Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den +# Ministerpräsidenten des Landes Schleswig-Holstein +# Staatskanzlei +# Abteilung Digitalisierung und zentrales IT-Management der Landesregierung +# +# Lizenziert unter der EUPL, Version 1.2 oder - sobald +# diese von der Europäischen Kommission genehmigt wurden - +# Folgeversionen der EUPL ("Lizenz"); +# Sie dürfen dieses Werk ausschließlich gemäß +# dieser Lizenz nutzen. +# Eine Kopie der Lizenz finden Sie hier: +# +# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 +# +# Sofern nicht durch anwendbare Rechtsvorschriften +# gefordert oder in schriftlicher Form vereinbart, wird +# die unter der Lizenz verbreitete Software "so wie sie +# ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - +# ausdrücklich oder stillschweigend - verbreitet. +# Die sprachspezifischen Genehmigungen und Beschränkungen +# unter der Lizenz sind dem Lizenztext zu entnehmen. +# + +suite: test deployment container environments +templates: + - templates/deployment.yaml +set: + imagePullSecret: test-image-secret + +tests: + - it: check customList as list + set: + env.customList: + - name: my_test_environment_name + value: "A test value" + - name: test_environment + value: "B test value" + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: my_test_environment_name + value: "A test value" + - contains: + path: spec.template.spec.containers[0].env + content: + name: test_environment + value: "B test value" + - it: check customList as dict + set: + env.customList: + my_test_environment_name: "A test value" + test_environment: "B test value" + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: my_test_environment_name + value: "A test value" + - contains: + path: spec.template.spec.containers[0].env + content: + name: test_environment + value: "B test value" + + - it: check customList test value is not set by default + asserts: + - isEmpty: + path: spec.template.spec.containers[0].env + + diff --git a/src/test/helm/deployment_archive_manager_address_env_test.yaml b/alfa-client/src/test/helm/deployment_host_aliases_test.yaml similarity index 63% rename from src/test/helm/deployment_archive_manager_address_env_test.yaml rename to alfa-client/src/test/helm/deployment_host_aliases_test.yaml index 148184f0fae94370660e8f49ba6caa74b9182653..ad5d1f8f66a03d2e87fc591fb3b06ae84f0d0077 100644 --- a/src/test/helm/deployment_archive_manager_address_env_test.yaml +++ b/alfa-client/src/test/helm/deployment_host_aliases_test.yaml @@ -1,5 +1,5 @@ # -# Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den +# Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den # Ministerpräsidenten des Landes Schleswig-Holstein # Staatskanzlei # Abteilung Digitalisierung und zentrales IT-Management der Landesregierung @@ -22,28 +22,31 @@ # unter der Lizenz sind dem Lizenztext zu entnehmen. # -suite: test deployment archive-manager address +suite: deployment host aliases release: - name: alfa + name: alfa-client namespace: sh-helm-test templates: - templates/deployment.yaml -set: - baseUrl: test.company.local - ozgcloud: - environment: test - bundesland: sh - bezeichner: helm - sso: - serverUrl: https://sso.company.local - imagePullSecret: image-pull-secret +set: + imagePullSecret: test-image-secret tests: - - it: should set the archive-manager name + - it: should not set spec.template.spec.hostAliases + asserts: + - isNull: + path: spec.template.spec.hostAliases + - it: should set spec.template.spec.hostAliases set: - archiveManagerName: my-test-archive-manager-name + hostAliases: + - ip: "127.0.0.1" + hostname: + - "eins" + - "zwei" asserts: - contains: - path: spec.template.spec.containers[0].env + path: spec.template.spec.hostAliases content: - name: grpc_client_archive-manager_address - value: dns:///my-test-archive-manager-name.sh-helm-test:9090 + ip: "127.0.0.1" + hostname: + - "eins" + - "zwei" diff --git a/alfa-client/src/test/helm/deployment_imagepull_secret_test.yaml b/alfa-client/src/test/helm/deployment_imagepull_secret_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..96e8e2b6e5bf8d735102854d8a1cc4195c5710de --- /dev/null +++ b/alfa-client/src/test/helm/deployment_imagepull_secret_test.yaml @@ -0,0 +1,44 @@ +# +# Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den +# Ministerpräsidenten des Landes Schleswig-Holstein +# Staatskanzlei +# Abteilung Digitalisierung und zentrales IT-Management der Landesregierung +# +# Lizenziert unter der EUPL, Version 1.2 oder - sobald +# diese von der Europäischen Kommission genehmigt wurden - +# Folgeversionen der EUPL ("Lizenz"); +# Sie dürfen dieses Werk ausschließlich gemäß +# dieser Lizenz nutzen. +# Eine Kopie der Lizenz finden Sie hier: +# +# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 +# +# Sofern nicht durch anwendbare Rechtsvorschriften +# gefordert oder in schriftlicher Form vereinbart, wird +# die unter der Lizenz verbreitete Software "so wie sie +# ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - +# ausdrücklich oder stillschweigend - verbreitet. +# Die sprachspezifischen Genehmigungen und Beschränkungen +# unter der Lizenz sind dem Lizenztext zu entnehmen. +# + +suite: test deployment image pull secret +release: + name: alfa-client + namespace: sh-helm-test +templates: + - templates/deployment.yaml + + +tests: + - it: should use correct imagePull secret + set: + imagePullSecret: test-image-secret + asserts: + - equal: + path: spec.template.spec.imagePullSecrets[0].name + value: test-image-secret + - it: should fail template when image pull secret not set + asserts: + - failedTemplate: + errormessage: imagePullSecret must be set \ No newline at end of file diff --git a/alfa-client/src/test/helm/deployment_resources_test.yaml b/alfa-client/src/test/helm/deployment_resources_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c053aeb0639d0c495699aa85667f1fddb6c6a82e --- /dev/null +++ b/alfa-client/src/test/helm/deployment_resources_test.yaml @@ -0,0 +1,60 @@ +# +# Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den +# Ministerpräsidenten des Landes Schleswig-Holstein +# Staatskanzlei +# Abteilung Digitalisierung und zentrales IT-Management der Landesregierung +# +# Lizenziert unter der EUPL, Version 1.2 oder - sobald +# diese von der Europäischen Kommission genehmigt wurden - +# Folgeversionen der EUPL ("Lizenz"); +# Sie dürfen dieses Werk ausschließlich gemäß +# dieser Lizenz nutzen. +# Eine Kopie der Lizenz finden Sie hier: +# +# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 +# +# Sofern nicht durch anwendbare Rechtsvorschriften +# gefordert oder in schriftlicher Form vereinbart, wird +# die unter der Lizenz verbreitete Software "so wie sie +# ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - +# ausdrücklich oder stillschweigend - verbreitet. +# Die sprachspezifischen Genehmigungen und Beschränkungen +# unter der Lizenz sind dem Lizenztext zu entnehmen. +# + +suite: test deployment container resources +release: + name: alfa-client +templates: + - templates/deployment.yaml +set: + imagePullSecret: test-image-secret + +tests: + - it: should generate resources when values set + set: + resources: + limits: + cpu: 11m + memory: 22Mi + requests: + cpu: 33m + memory: 44Mi + asserts: + - equal: + path: spec.template.spec.containers[0].resources.limits.cpu + value: 11m + - equal: + path: spec.template.spec.containers[0].resources.limits.memory + value: 22Mi + - equal: + path: spec.template.spec.containers[0].resources.requests.cpu + value: 33m + - equal: + path: spec.template.spec.containers[0].resources.requests.memory + value: 44Mi + - it: should not generate resources when values not set + asserts: + - isEmpty: + path: spec.template.spec.containers[0].resources + diff --git a/alfa-client/src/test/helm/deyploment_general_value_test.yaml b/alfa-client/src/test/helm/deyploment_general_value_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..081ae623bd6c0db6b518a0eb7753fc0632b03fe1 --- /dev/null +++ b/alfa-client/src/test/helm/deyploment_general_value_test.yaml @@ -0,0 +1,74 @@ +# +# Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den +# Ministerpräsidenten des Landes Schleswig-Holstein +# Staatskanzlei +# Abteilung Digitalisierung und zentrales IT-Management der Landesregierung +# +# Lizenziert unter der EUPL, Version 1.2 oder - sobald +# diese von der Europäischen Kommission genehmigt wurden - +# Folgeversionen der EUPL ("Lizenz"); +# Sie dürfen dieses Werk ausschließlich gemäß +# dieser Lizenz nutzen. +# Eine Kopie der Lizenz finden Sie hier: +# +# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 +# +# Sofern nicht durch anwendbare Rechtsvorschriften +# gefordert oder in schriftlicher Form vereinbart, wird +# die unter der Lizenz verbreitete Software "so wie sie +# ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - +# ausdrücklich oder stillschweigend - verbreitet. +# Die sprachspezifischen Genehmigungen und Beschränkungen +# unter der Lizenz sind dem Lizenztext zu entnehmen. +# + +suite: test deployment general values +release: + name: alfa-client + namespace: sh-helm-test +templates: + - templates/deployment.yaml +set: + imagePullSecret: test-image-secret + + +tests: + - it: should have correct apiVersion + asserts: + - isKind: + of: Deployment + - isAPIVersion: + of: "apps/v1" + + - it: should have correct deployment metadata + asserts: + - equal: + path: metadata.name + value: alfa-client + - equal: + path: metadata.namespace + value: sh-helm-test + + + - it: should have correct deyployment general spec values + asserts: + - equal: + path: spec.progressDeadlineSeconds + value: 600 + - equal: + path: spec.replicas + value: 1 + - equal: + path: spec.revisionHistoryLimit + value: 10 + - it: should have correct deployment spec strategy values + asserts: + - equal: + path: spec.strategy + value: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + type: RollingUpdate + + diff --git a/alfa-client/src/test/helm/ingress_tests.yaml b/alfa-client/src/test/helm/ingress_tests.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1f1fa4729a117bfc02ccb9e5afc442b87f92d39b --- /dev/null +++ b/alfa-client/src/test/helm/ingress_tests.yaml @@ -0,0 +1,168 @@ +# +# Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den +# Ministerpräsidenten des Landes Schleswig-Holstein +# Staatskanzlei +# Abteilung Digitalisierung und zentrales IT-Management der Landesregierung +# +# Lizenziert unter der EUPL, Version 1.2 oder - sobald +# diese von der Europäischen Kommission genehmigt wurden - +# Folgeversionen der EUPL ("Lizenz"); +# Sie dürfen dieses Werk ausschließlich gemäß +# dieser Lizenz nutzen. +# Eine Kopie der Lizenz finden Sie hier: +# +# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 +# +# Sofern nicht durch anwendbare Rechtsvorschriften +# gefordert oder in schriftlicher Form vereinbart, wird +# die unter der Lizenz verbreitete Software "so wie sie +# ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - +# ausdrücklich oder stillschweigend - verbreitet. +# Die sprachspezifischen Genehmigungen und Beschränkungen +# unter der Lizenz sind dem Lizenztext zu entnehmen. +# + +suite: test ingress.yaml +release: + name: alfa-client + namespace: sh-helm-test +templates: + - templates/ingress.yaml + +tests: + - it: check ingress kind + set: + ozgcloud: + bezeichner: helm + baseUrl: test.by.ozg-cloud.de + asserts: + - isKind: + of: Ingress + - it: should create default ingress tls + set: + ozgcloud: + bezeichner: helm + baseUrl: test.by.ozg-cloud.de + asserts: + - equal: + path: spec.tls[0].secretName + value: helm-alfa-client-tls + - it: should set ingress tls + set: + ingress: + tlsSecretName: client-tls + ozgcloud: + bezeichner: helm + baseUrl: test.by.ozg-cloud.de + asserts: + - equal: + path: spec.tls[0].secretName + value: client-tls + + - it: should not create ingress tls/ingressClass by default + set: + ozgcloud: + bezeichner: helm + baseUrl: test.by.ozg-cloud.de + asserts: + - isNull: + path: spec.ingressClassName + - it: should set ingress tls/ingressClass + set: + ingress: + className: ingress + ozgcloud: + bezeichner: helm + baseUrl: test.by.ozg-cloud.de + asserts: + - equal: + path: spec.ingressClassName + value: ingress + + + - it: should use default letsencrypt-prod cluster-issuer + set: + ozgcloud: + bezeichner: helm + baseUrl: test.by.ozg-cloud.de + asserts: + - equal: + path: metadata.annotations["cert-manager.io/cluster-issuer"] + value: letsencrypt-prod + + - it: should use letsencrypt-staging cluster-issuer + set: + ingress.use_staging_cert: true + ozgcloud: + bezeichner: helm + baseUrl: test.by.ozg-cloud.de + asserts: + - equal: + path: metadata.annotations["cert-manager.io/cluster-issuer"] + value: letsencrypt-staging + + - it: should use letsencrypt-prod cluster-issuer + set: + ingress.use_staging_cert: false + ozgcloud: + bezeichner: helm + baseUrl: test.by.ozg-cloud.de + asserts: + - equal: + path: metadata.annotations["cert-manager.io/cluster-issuer"] + value: letsencrypt-prod + + - it: should create tls hosts name correctly + set: + ozgcloud: + bezeichner: helm + baseUrl: test.by.ozg-cloud.de + asserts: + - equal: + path: spec.tls[0].hosts[0] + value: helm.test.by.ozg-cloud.de + + - it: should create rules correctly + set: + ozgcloud: + bezeichner: helm + baseUrl: test.by.ozg-cloud.de + asserts: + - equal: + path: spec.rules[0].http.paths[0] + value: + path: / + pathType: Prefix + backend: + service: + name: alfa-client + port: + number: 8080 + + + - it: should set hostname + set: + ozgcloud: + bezeichner: helm + baseUrl: test.by.ozg-cloud.de + asserts: + - equal: + path: spec.rules[0].host + value: helm.test.by.ozg-cloud.de + - it: should fail template when baseUrl not set + set: + ozgcloud: + bezeichner: helm + asserts: + - failedTemplate: + errormessage: baseUrl muss angegeben sein + + - it: should fail template when bezeichner not set + set: + ozgcloud: + baseUrl: test.by.ozg-cloud.de + asserts: + - failedTemplate: + errormessage: ozgcloud.bezeichner muss angegeben sein + + \ No newline at end of file diff --git a/alfa-client/src/test/helm/network_policy_test.yaml b/alfa-client/src/test/helm/network_policy_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..55468aaf0a2032297a684f32e0c8fa06248f8766 --- /dev/null +++ b/alfa-client/src/test/helm/network_policy_test.yaml @@ -0,0 +1,132 @@ +# +# Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den +# Ministerpräsidenten des Landes Schleswig-Holstein +# Staatskanzlei +# Abteilung Digitalisierung und zentrales IT-Management der Landesregierung +# +# Lizenziert unter der EUPL, Version 1.2 oder - sobald +# diese von der Europäischen Kommission genehmigt wurden - +# Folgeversionen der EUPL ("Lizenz"); +# Sie dürfen dieses Werk ausschließlich gemäß +# dieser Lizenz nutzen. +# Eine Kopie der Lizenz finden Sie hier: +# +# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 +# +# Sofern nicht durch anwendbare Rechtsvorschriften +# gefordert oder in schriftlicher Form vereinbart, wird +# die unter der Lizenz verbreitete Software "so wie sie +# ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - +# ausdrücklich oder stillschweigend - verbreitet. +# Die sprachspezifischen Genehmigungen und Beschränkungen +# unter der Lizenz sind dem Lizenztext zu entnehmen. +# + +suite: network policy alfa-client test +release: + name: alfa-client + namespace: by-helm-test +templates: + - templates/network_policy.yaml + +tests: + - it: should match apiVersion + asserts: + - isAPIVersion: + of: networking.k8s.io/v1 + - it: should match kind + asserts: + - isKind: + of: NetworkPolicy + - it: validate metadata + asserts: + - equal: + path: metadata + value: + name: network-policy-alfa-client + namespace: by-helm-test + + - it: should add additionalIngressConfig local + set: + networkPolicy: + additionalIngressConfigLocal: + - from: + - podSelector: + matchLabels: + component: client2 + asserts: + - contains: + path: spec.ingress + content: + from: + - podSelector: + matchLabels: + component: client2 + - it: should add additionalIngressConfig global + set: + networkPolicy: + additionalIngressConfigGlobal: + - from: + - podSelector: + matchLabels: + component: client2 + asserts: + - contains: + path: spec.ingress + content: + from: + - podSelector: + matchLabels: + component: client2 + + - it: should add additionalEgressConfig local + set: + networkPolicy: + additionalEgressConfigLocal: + - to: + - ipBlock: + cidr: 1.2.3.4/32 + asserts: + - contains: + path: spec.egress + content: + to: + - ipBlock: + cidr: 1.2.3.4/32 + + - it: should add additionalEgressConfig global + set: + networkPolicy: + additionalEgressConfigGlobal: + - to: + - ipBlock: + cidr: 1.2.3.4/32 + asserts: + - contains: + path: spec.egress + content: + to: + - ipBlock: + cidr: 1.2.3.4/32 + + + - it: test network policy disabled + set: + networkPolicy: + disabled: true + asserts: + - hasDocuments: + count: 0 + + - it: test network policy unset should be disabled + set: + networkPolicy: + disabled: false + asserts: + - hasDocuments: + count: 1 + + - it: test network policy should be enabled by default + asserts: + - hasDocuments: + count: 1 \ No newline at end of file diff --git a/alfa-client/src/test/helm/service_test.yaml b/alfa-client/src/test/helm/service_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c5ac4691125d01fe6a9ec94c336bbda918b48e33 --- /dev/null +++ b/alfa-client/src/test/helm/service_test.yaml @@ -0,0 +1,66 @@ +# +# Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den +# Ministerpräsidenten des Landes Schleswig-Holstein +# Staatskanzlei +# Abteilung Digitalisierung und zentrales IT-Management der Landesregierung +# +# Lizenziert unter der EUPL, Version 1.2 oder - sobald +# diese von der Europäischen Kommission genehmigt wurden - +# Folgeversionen der EUPL ("Lizenz"); +# Sie dürfen dieses Werk ausschließlich gemäß +# dieser Lizenz nutzen. +# Eine Kopie der Lizenz finden Sie hier: +# +# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 +# +# Sofern nicht durch anwendbare Rechtsvorschriften +# gefordert oder in schriftlicher Form vereinbart, wird +# die unter der Lizenz verbreitete Software "so wie sie +# ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - +# ausdrücklich oder stillschweigend - verbreitet. +# Die sprachspezifischen Genehmigungen und Beschränkungen +# unter der Lizenz sind dem Lizenztext zu entnehmen. +# + +suite: test service +release: + name: alfa-client + namespace: sh-helm-test +templates: + - templates/service.yaml +tests: + - it: should have the label component with correct value + asserts: + - isKind: + of: Service + - isAPIVersion: + of: v1 + - equal: + path: metadata.labels.component + value: alfa-client-service + - it: should be of type ClusterIP + asserts: + - equal: + path: spec.type + value: ClusterIP + + - it: selector should contain the component label with correct value + asserts: + - equal: + path: spec.selector.component + value: alfa-client + + - it: selector should contain helm recommended labels name and namespace + asserts: + - equal: + path: spec.selector + value: + app.kubernetes.io/name: alfa-client + app.kubernetes.io/namespace: sh-helm-test + component: alfa-client + + - it: check component label for service + asserts: + - equal: + path: metadata.labels["component"] + value: alfa-client-service \ No newline at end of file diff --git a/alfa-client/tsconfig.base.json b/alfa-client/tsconfig.base.json index 074d37046bc7c1d420bba5c631c72ec945d9b276..5fa256e28ccf0dd8ac93135af48e7e0180ed359d 100644 --- a/alfa-client/tsconfig.base.json +++ b/alfa-client/tsconfig.base.json @@ -61,7 +61,8 @@ "@alfa-client/zustaendige-stelle-shared": ["libs/zustaendige-stelle-shared/src/index.ts"], "@ods/component": ["libs/design-component/src/index.ts"], "@ods/system": ["libs/design-system/src/index.ts"], - "authentication": ["libs/authentication/src/index.ts"] + "authentication": ["libs/authentication/src/index.ts"], + "@alfa-client/common": ["libs/common/src/index.ts"] } }, "exclude": ["node_modules", "tmp"] diff --git a/alfa-server/pom.xml b/alfa-server/pom.xml index 395a93395a2c9011c8e0c5f17ce437fced4d31a8..5e51365a7d41f0fcd9ef379a087e14e8dfc61a90 100644 --- a/alfa-server/pom.xml +++ b/alfa-server/pom.xml @@ -24,6 +24,11 @@ <artifactId>alfa-service</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>de.ozgcloud.alfa</groupId> + <artifactId>alfa-xdomea</artifactId> + <version>${project.version}</version> + </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> diff --git a/alfa-server/src/main/resources/application-local.yml b/alfa-server/src/main/resources/application-local.yml index 55772b0d1f753624c45b82c5f343f689cdf96eb7..1dd7f05bdf4e5d54519327679cc70546b1ec6edb 100644 --- a/alfa-server/src/main/resources/application-local.yml +++ b/alfa-server/src/main/resources/application-local.yml @@ -16,8 +16,6 @@ grpc: negotiationType: PLAINTEXT zufi-manager: negotiationType: PLAINTEXT - archive-manager: - negotiationType: PLAINTEXT ozgcloud: feature: diff --git a/alfa-server/src/main/resources/application.yml b/alfa-server/src/main/resources/application.yml index aaf3f0290c0eb6de18d5e6e208c4b7886e463486..f5642fefecceda5c3f88a333ad14c835c5394bc1 100644 --- a/alfa-server/src/main/resources/application.yml +++ b/alfa-server/src/main/resources/application.yml @@ -66,9 +66,6 @@ grpc: zufi-manager: address: static://127.0.0.1:9190 negotiationType: TLS - archive-manager: - address: static://127.0.0.1:9090 - negotiationType: TLS ozgcloud: auth: diff --git a/alfa-service/pom.xml b/alfa-service/pom.xml index 544b215e4e6c71ebf477ae61bdccbed75fa89f4b..1065a01112aada11a850d06625ae570b63e78207 100644 --- a/alfa-service/pom.xml +++ b/alfa-service/pom.xml @@ -135,10 +135,6 @@ <groupId>de.ozgcloud.zufi</groupId> <artifactId>zufi-manager-interface</artifactId> </dependency> - <dependency> - <groupId>de.ozgcloud.archive</groupId> - <artifactId>archive-manager-interface</artifactId> - </dependency> <!-- tools --> <dependency> diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/common/GrpcUtil.java b/alfa-service/src/main/java/de/ozgcloud/alfa/common/GrpcUtil.java index 610a0cc4324df0ed3d3a7bd110b4a13b2b7ebfe3..fc033f658d18ce1a5726b631e32ab7b591c5817f 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/common/GrpcUtil.java +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/common/GrpcUtil.java @@ -40,8 +40,6 @@ public class GrpcUtil { public static final String ZUFI_MANAGER_GRPC_CLIENT = "zufi-manager"; - public static final String ARCHIVE_MANAGER_GRPC_CLIENT = "archive-manager"; - public static final String SERVICE_KEY = "GRPC_SERVICE"; public static Key<String> keyOfString(String key) { diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/export/ExportRemoteService.java b/alfa-service/src/main/java/de/ozgcloud/alfa/export/ExportRemoteService.java deleted file mode 100644 index a4c82201787069c1c46f7f8d265181feef7230de..0000000000000000000000000000000000000000 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/export/ExportRemoteService.java +++ /dev/null @@ -1,20 +0,0 @@ -package de.ozgcloud.alfa.export; - -import org.springframework.stereotype.Service; - -import de.ozgcloud.alfa.common.GrpcUtil; -import de.ozgcloud.archive.grpc.export.ExportServiceGrpc.ExportServiceBlockingStub; -import de.ozgcloud.archive.grpc.export.GrpcExportVorgangRequest; -import net.devh.boot.grpc.client.inject.GrpcClient; - -@Service -class ExportRemoteService { - - @GrpcClient(GrpcUtil.ARCHIVE_MANAGER_GRPC_CLIENT) - private ExportServiceBlockingStub exportServiceStub; - - public ExportedVorgangFile exportVorgang(String vorgangId) { - var responseIterator = exportServiceStub.exportVorgang(GrpcExportVorgangRequest.newBuilder().setVorgangId(vorgangId).build()); - return new StreamedExportedVorgangFile(responseIterator); - } -} diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/export/ExportedVorgangFile.java b/alfa-service/src/main/java/de/ozgcloud/alfa/export/ExportedVorgangFile.java deleted file mode 100644 index e778a5a905885776809922c99ca8c27a5f595f92..0000000000000000000000000000000000000000 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/export/ExportedVorgangFile.java +++ /dev/null @@ -1,11 +0,0 @@ -package de.ozgcloud.alfa.export; - -import java.io.IOException; -import java.io.OutputStream; - -interface ExportedVorgangFile { - - String getFileName(); - - void writeToOutputStream(OutputStream outputStream) throws IOException; -} diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/export/StreamedExportedVorgangFile.java b/alfa-service/src/main/java/de/ozgcloud/alfa/export/StreamedExportedVorgangFile.java deleted file mode 100644 index 4e87099e63b8e3c896b37f8ddf3728b3f2a1dbda..0000000000000000000000000000000000000000 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/export/StreamedExportedVorgangFile.java +++ /dev/null @@ -1,35 +0,0 @@ -package de.ozgcloud.alfa.export; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.Iterator; - -import de.ozgcloud.archive.grpc.export.GrpcExportVorgangResponse; -import de.ozgcloud.common.errorhandling.TechnicalException; -import lombok.Getter; - -class StreamedExportedVorgangFile implements ExportedVorgangFile { - - @Getter - private final String fileName; - private final Iterator<GrpcExportVorgangResponse> responseIterator; - - public StreamedExportedVorgangFile(Iterator<GrpcExportVorgangResponse> responseIterator) { - this.fileName = getFileNameFrom(responseIterator); - this.responseIterator = responseIterator; - } - - static String getFileNameFrom(Iterator<GrpcExportVorgangResponse> responseIterator) { - if (!responseIterator.hasNext()) { - throw new TechnicalException("Response is empty"); - } - return responseIterator.next().getVorgangFile().getFileName(); - } - - @Override - public void writeToOutputStream(OutputStream outputStream) throws IOException { - while (responseIterator.hasNext()) { - outputStream.write(responseIterator.next().getVorgangFile().getFileContent().toByteArray()); - } - } -} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/export/ExportRemoteServiceTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/export/ExportRemoteServiceTest.java deleted file mode 100644 index e2d36e6134f13ed1a8377584aaf555daeb23bc20..0000000000000000000000000000000000000000 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/export/ExportRemoteServiceTest.java +++ /dev/null @@ -1,68 +0,0 @@ -package de.ozgcloud.alfa.export; - -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; - -import java.util.Iterator; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentMatcher; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockedStatic; -import org.mockito.Spy; - -import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; -import de.ozgcloud.archive.grpc.export.ExportServiceGrpc.ExportServiceBlockingStub; -import de.ozgcloud.archive.grpc.export.GrpcExportVorgangRequest; -import de.ozgcloud.archive.grpc.export.GrpcExportVorgangResponse; - -class ExportRemoteServiceTest { - - @Spy - @InjectMocks - private ExportRemoteService service; - @Mock - private ExportServiceBlockingStub exportServiceStub; - - @Nested - class TestExportVorgang { - - public static final String VORGANG_ID = VorgangHeaderTestFactory.ID; - - private static final ArgumentMatcher<GrpcExportVorgangRequest> HAS_VORGANG_ID = request -> request.getVorgangId().equals(VorgangHeaderTestFactory.ID); - - @Mock - private Iterator<GrpcExportVorgangResponse> responseIterator; - private MockedStatic<StreamedExportedVorgangFile> mockedStaticExportedFile; - - @BeforeEach - void init() { - mockedStaticExportedFile = mockStatic(StreamedExportedVorgangFile.class); - mockedStaticExportedFile.when(() -> StreamedExportedVorgangFile.getFileNameFrom(responseIterator)).thenReturn(GrpcFileTestFactory.FILE_NAME); - when(exportServiceStub.exportVorgang(any(GrpcExportVorgangRequest.class))).thenReturn(responseIterator); - } - - @AfterEach - void cleanup() { - mockedStaticExportedFile.close(); - } - - @Test - void shouldExportVorgang() { - service.exportVorgang(VORGANG_ID); - - verify(exportServiceStub).exportVorgang(argThat(HAS_VORGANG_ID)); - } - - @Test - void shouldReturnExportedVorgangFile() { - var exportedVorgangFile = service.exportVorgang(VORGANG_ID); - - assertThat(exportedVorgangFile).isInstanceOf(StreamedExportedVorgangFile.class).extracting("responseIterator").isEqualTo(responseIterator); - } - } -} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/export/GrpcExportVorgangResponseTestFactory.java b/alfa-service/src/test/java/de/ozgcloud/alfa/export/GrpcExportVorgangResponseTestFactory.java deleted file mode 100644 index 6fb86287921347fa6d9eaecdb12e20ca5450a3bb..0000000000000000000000000000000000000000 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/export/GrpcExportVorgangResponseTestFactory.java +++ /dev/null @@ -1,22 +0,0 @@ -package de.ozgcloud.alfa.export; - -import de.ozgcloud.archive.grpc.export.GrpcExportVorgangResponse; -import de.ozgcloud.archive.grpc.export.GrpcFile; - -class GrpcExportVorgangResponseTestFactory { - - public static final GrpcFile VORGANG_FILE_WITH_NAME = GrpcFileTestFactory.createWithName(); - public static final GrpcFile VORGANG_FILE_WITH_CONTENT = GrpcFileTestFactory.createWithContent(); - - public static GrpcExportVorgangResponse createWithName() { - return createBuilder().setVorgangFile(VORGANG_FILE_WITH_NAME).build(); - } - - public static GrpcExportVorgangResponse createWithContent() { - return createBuilder().setVorgangFile(VORGANG_FILE_WITH_CONTENT).build(); - } - - public static GrpcExportVorgangResponse.Builder createBuilder() { - return GrpcExportVorgangResponse.newBuilder(); - } -} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/export/GrpcFileTestFactory.java b/alfa-service/src/test/java/de/ozgcloud/alfa/export/GrpcFileTestFactory.java deleted file mode 100644 index 2d07f97a0e54a5d6484ecd24c6a872037124b517..0000000000000000000000000000000000000000 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/export/GrpcFileTestFactory.java +++ /dev/null @@ -1,24 +0,0 @@ -package de.ozgcloud.alfa.export; - -import com.google.protobuf.ByteString; -import com.thedeanda.lorem.LoremIpsum; - -import de.ozgcloud.archive.grpc.export.GrpcFile; - -class GrpcFileTestFactory { - - public static final String FILE_NAME = LoremIpsum.getInstance().getName(); - public static final ByteString FILE_CONTENT = ByteString.copyFromUtf8(LoremIpsum.getInstance().getWords(10)); - - public static GrpcFile createWithName() { - return createBuilder().setFileName(FILE_NAME).build(); - } - - public static GrpcFile createWithContent() { - return createBuilder().setFileContent(FILE_CONTENT).build(); - } - - public static GrpcFile.Builder createBuilder() { - return GrpcFile.newBuilder(); - } -} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/export/StreamedExportedVorgangFileTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/export/StreamedExportedVorgangFileTest.java deleted file mode 100644 index 293aa49bce8008b40bd9f52e38ad0335bdf5e735..0000000000000000000000000000000000000000 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/export/StreamedExportedVorgangFileTest.java +++ /dev/null @@ -1,153 +0,0 @@ -package de.ozgcloud.alfa.export; - -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.Iterator; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.mockito.Mock; -import org.mockito.MockedStatic; - -import com.google.protobuf.ByteString; -import com.thedeanda.lorem.LoremIpsum; - -import de.ozgcloud.archive.grpc.export.GrpcExportVorgangResponse; -import de.ozgcloud.common.errorhandling.TechnicalException; - -class StreamedExportedVorgangFileTest { - - @Mock - private Iterator<GrpcExportVorgangResponse> responseIterator; - - @Nested - class TestContructor { - - private MockedStatic<StreamedExportedVorgangFile> mockedStatic; - - @BeforeEach - void init() { - mockedStatic = mockStatic(StreamedExportedVorgangFile.class); - mockedStatic.when(() -> StreamedExportedVorgangFile.getFileNameFrom(responseIterator)).thenReturn(GrpcFileTestFactory.FILE_NAME); - } - - @AfterEach - void cleanup() { - mockedStatic.close(); - } - - @Test - void shouldGetFileNameFromResponseIterator() { - new StreamedExportedVorgangFile(responseIterator); - - mockedStatic.verify(() -> StreamedExportedVorgangFile.getFileNameFrom(responseIterator)); - } - - @Test - void shouldSetFileName() { - var exportedVorgangFile = new StreamedExportedVorgangFile(responseIterator); - - assertThat(exportedVorgangFile.getFileName()).isEqualTo(GrpcFileTestFactory.FILE_NAME); - } - } - - @Nested - class TestGetFileNameFrom { - - @Nested - class OnEmptyResponse { - - @BeforeEach - void init() { - when(responseIterator.hasNext()).thenReturn(false); - } - - @Test - void shouldThrowException() { - assertThatExceptionOfType(TechnicalException.class).isThrownBy(TestGetFileNameFrom.this::callTestedMethod); - } - } - - @Nested - class OnNotEmptyResponse { - - @BeforeEach - void init() { - when(responseIterator.hasNext()).thenReturn(true); - when(responseIterator.next()).thenReturn(GrpcExportVorgangResponseTestFactory.createWithName()); - } - - @Test - void shouldCallHasNext() { - callTestedMethod(); - - verify(responseIterator).hasNext(); - } - - @Test - void shouldCallNextOnce() { - callTestedMethod(); - - verify(responseIterator, times(1)).next(); - } - - @Test - void shouldReturnFileName() { - var fileName = callTestedMethod(); - - assertThat(fileName).isEqualTo(GrpcFileTestFactory.FILE_NAME); - } - } - - private String callTestedMethod() { - return StreamedExportedVorgangFile.getFileNameFrom(responseIterator); - } - } - - @Nested - class TestWriteToOutputStream { - - public static final ByteString FILE_CONTENT_1 = GrpcFileTestFactory.FILE_CONTENT; - public static final ByteString FILE_CONTENT_2 = ByteString.copyFromUtf8(LoremIpsum.getInstance().getWords(8)); - - @Mock - private OutputStream outputStream; - - private MockedStatic<StreamedExportedVorgangFile> mockedStatic; - - @BeforeEach - void init() { - mockedStatic = mockStatic(StreamedExportedVorgangFile.class); - mockedStatic.when(() -> StreamedExportedVorgangFile.getFileNameFrom(responseIterator)).thenReturn(GrpcFileTestFactory.FILE_NAME); - when(responseIterator.hasNext()) - .thenReturn(true) - .thenReturn(true) - .thenReturn(false); - when(responseIterator.next()) - .thenReturn(GrpcExportVorgangResponseTestFactory.createWithContent()) - .thenReturn(GrpcExportVorgangResponseTestFactory.createBuilder().setVorgangFile( - GrpcFileTestFactory.createBuilder().setFileContent(FILE_CONTENT_2).build() - ).build()); - } - - @AfterEach - void cleanup() { - mockedStatic.close(); - } - - @Test - void shouldWriteFileContentInOrder() throws IOException { - var orderVerifier = inOrder(outputStream); - - new StreamedExportedVorgangFile(responseIterator).writeToOutputStream(outputStream); - - orderVerifier.verify(outputStream).write(FILE_CONTENT_1.toByteArray()); - orderVerifier.verify(outputStream).write(FILE_CONTENT_2.toByteArray()); - } - } -} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/forwarding/ForwardingLandesnetzInfoServiceTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/forwarding/ForwardingLandesnetzInfoServiceTest.java index f314dbef0bf2c48ccfb35d1f974ce9e6edaa91cc..19bea4224f26612e6447965cc090ab8eb52efbec 100644 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/forwarding/ForwardingLandesnetzInfoServiceTest.java +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/forwarding/ForwardingLandesnetzInfoServiceTest.java @@ -33,9 +33,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; -import org.mockito.Mock; import org.mockito.Spy; -import org.springframework.core.io.ResourceLoader; import org.springframework.test.util.ReflectionTestUtils; class ForwardingLandesnetzInfoServiceTest { @@ -43,8 +41,6 @@ class ForwardingLandesnetzInfoServiceTest { @Spy @InjectMocks private ForwardingLandesnetzInfoService service; - @Mock - private ResourceLoader resourceLoader; @DisplayName("Is email in landesnetz") @Nested diff --git a/alfa-xdomea/pom.xml b/alfa-xdomea/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..d263dd38d2a153faa29682be9c8031a3423c79b6 --- /dev/null +++ b/alfa-xdomea/pom.xml @@ -0,0 +1,133 @@ +<?xml version="1.0"?> +<!-- + + Copyright (C) 2023 Das Land Schleswig-Holstein vertreten durch den + Ministerpräsidenten des Landes Schleswig-Holstein + Staatskanzlei + Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + + Lizenziert unter der EUPL, Version 1.2 oder - sobald + diese von der Europäischen Kommission genehmigt wurden - + Folgeversionen der EUPL ("Lizenz"); + Sie dürfen dieses Werk ausschließlich gemäß + dieser Lizenz nutzen. + Eine Kopie der Lizenz finden Sie hier: + + https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + + Sofern nicht durch anwendbare Rechtsvorschriften + gefordert oder in schriftlicher Form vereinbart, wird + die unter der Lizenz verbreitete Software "so wie sie + ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + ausdrücklich oder stillschweigend - verbreitet. + Die sprachspezifischen Genehmigungen und Beschränkungen + unter der Lizenz sind dem Lizenztext zu entnehmen. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>de.ozgcloud.alfa</groupId> + <artifactId>alfa</artifactId> + <version>2.16.0-SNAPSHOT</version> + </parent> + + <artifactId>alfa-xdomea</artifactId> + <name>Alfa xdomea</name> + <description>Alfa xdomea implementation</description> + <packaging>jar</packaging> + + <properties> + <maven.compiler.source>${java.version}</maven.compiler.source> + <maven.compiler.target>${java.version}</maven.compiler.target> + <jaxb2-maven-plugin.version>3.1.0</jaxb2-maven-plugin.version> + </properties> + + <dependencies> + <dependency> + <groupId>de.ozgcloud.alfa</groupId> + <artifactId>alfa-service</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>jakarta.xml.bind</groupId> + <artifactId>jakarta.xml.bind-api</artifactId> + </dependency> + <dependency> + <groupId>org.glassfish.jaxb</groupId> + <artifactId>jaxb-runtime</artifactId> + </dependency> + <dependency> + <groupId>org.mapstruct</groupId> + <artifactId>mapstruct</artifactId> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-oxm</artifactId> + </dependency> + <dependency> + <groupId>de.ozgcloud.alfa</groupId> + <artifactId>alfa-service</artifactId> + <version>${project.version}</version> + <type>test-jar</type> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>jaxb2-maven-plugin</artifactId> + <version>${jaxb2-maven-plugin.version}</version> + <executions> + <execution> + <id>xjc</id> + <goals> + <goal>xjc</goal> + </goals> + </execution> + </executions> + <configuration> + <sources> + <source>src/main/resources/ozgcloud_XML-Schemata</source> + </sources> + <packageName>de.xoev.xdomea</packageName> + </configuration> + </plugin> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + <configuration> + <skip>true</skip> + </configuration> + </plugin> + <plugin> + <groupId>org.jacoco</groupId> + <artifactId>jacoco-maven-plugin</artifactId> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-failsafe-plugin</artifactId> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + </plugin> + </plugins> + <resources> + <resource> + <directory>${project.build.directory}/generated-resources/jaxb</directory> + </resource> + </resources> + </build> +</project> diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/bescheid/BescheidExportData.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/bescheid/BescheidExportData.java new file mode 100644 index 0000000000000000000000000000000000000000..ece5ee2c105749cdd5dbf2059d6ae969e8abfb35 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/bescheid/BescheidExportData.java @@ -0,0 +1,19 @@ +package de.ozgcloud.alfa.bescheid; + +import java.util.List; + +import de.ozgcloud.alfa.common.file.OzgFile; +import de.xoev.xdomea.DokumentType; +import lombok.Builder; +import lombok.Getter; +import lombok.Singular; + +@Builder +@Getter +public class BescheidExportData { + + @Singular + private List<DokumentType> dokumentTypes; + @Singular + private List<OzgFile> files; +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/bescheid/BescheidExportInput.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/bescheid/BescheidExportInput.java new file mode 100644 index 0000000000000000000000000000000000000000..aa25d85adf81618ded8e2c62097275c011c90313 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/bescheid/BescheidExportInput.java @@ -0,0 +1,10 @@ +package de.ozgcloud.alfa.bescheid; + +import java.util.List; + +import de.ozgcloud.alfa.common.file.OzgFile; +import lombok.Builder; + +@Builder +record BescheidExportInput(Bescheid bescheid, String organisationseinheitenId, List<OzgFile> files) { +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/bescheid/DokumentTypeBuilder.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/bescheid/DokumentTypeBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..4a049e49cd45a920d3f64a456ace9351348bc4a3 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/bescheid/DokumentTypeBuilder.java @@ -0,0 +1,83 @@ +package de.ozgcloud.alfa.bescheid; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.apache.commons.lang3.StringUtils; + +import de.ozgcloud.alfa.common.AnlageDokumentTypeBuilder; +import de.ozgcloud.alfa.common.DateConverter; +import de.ozgcloud.alfa.common.IdentifikationObjektTypeBuilder; +import de.ozgcloud.alfa.common.file.OzgFile; +import de.xoev.xdomea.AllgemeineMetadatenType; +import de.xoev.xdomea.AnlageDokumentType; +import de.xoev.xdomea.DokumentType; +import de.xoev.xdomea.HistorienProtokollInformationType; + +class DokumentTypeBuilder { + private static final String TYP = "Bescheid"; + private static final Map<Boolean, String> BEMERKUNG = Map.of(true, "Bescheid wurde genehmigt.", false, "Bescheid wurde abgelehnt."); + private static final Map<SendBy, String> AKTION = Map.of(SendBy.MANUAL, "Bescheid gespeichert", SendBy.NACHRICHT, + "Bescheid an Antragsteller gesendet"); + + private Bescheid bescheid; + private String organisationsEinheitenId; + private String fullName; + private List<OzgFile> files; + + public static DokumentTypeBuilder builder() { + return new DokumentTypeBuilder(); + } + + public DokumentTypeBuilder withBescheid(Bescheid bescheid) { + this.bescheid = bescheid; + return this; + } + + public DokumentTypeBuilder withOrganisationseinheitenId(String organisationsEinheitenId) { + this.organisationsEinheitenId = organisationsEinheitenId; + return this; + } + + public DokumentTypeBuilder withFullName(String fullName) { + this.fullName = fullName; + return this; + } + + public DokumentTypeBuilder withFiles(List<OzgFile> files) { + this.files = files; + return this; + } + + public DokumentType build() { + var dokumentType = new DokumentType(); + dokumentType.setIdentifikation(IdentifikationObjektTypeBuilder.builder().withObjectID(bescheid.getId()).build()); + dokumentType.setTyp(TYP); + dokumentType.setBezug(StringUtils.defaultString(bescheid.getNachrichtSubject())); + dokumentType.setAllgemeineMetadaten(createAllgemeineMetadaten()); + dokumentType.getHistorienProtokollInformation().add(createHistorienProtokollInformation()); + Optional.ofNullable(files).orElseGet(Collections::emptyList).stream().map(this::createAnlage).forEach(dokumentType.getAnlage()::add); + return dokumentType; + } + + AllgemeineMetadatenType createAllgemeineMetadaten() { + var metadaten = new AllgemeineMetadatenType(); + metadaten.setBemerkung(BEMERKUNG.get(bescheid.getBewilligt())); + return metadaten; + } + + HistorienProtokollInformationType createHistorienProtokollInformation() { + var protokollInfo = new HistorienProtokollInformationType(); + protokollInfo.setMetadatumName(StringUtils.defaultString(bescheid.getNachrichtText())); + protokollInfo.setAkteur(fullName + "; " + organisationsEinheitenId); + protokollInfo.setDatumUhrzeit(DateConverter.toXmlGregorianCalendar(bescheid.getSentInfo().getSentAt())); + protokollInfo.setAktion(AKTION.get(bescheid.getSendBy())); + return protokollInfo; + } + + AnlageDokumentType createAnlage(OzgFile ozgFile) { + return AnlageDokumentTypeBuilder.builder().withOzgFile(ozgFile).build(); + } +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/bescheid/ExportBescheidService.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/bescheid/ExportBescheidService.java new file mode 100644 index 0000000000000000000000000000000000000000..7c34e61f09d3074a2ff398de69ea7ee338c3b8cb --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/bescheid/ExportBescheidService.java @@ -0,0 +1,67 @@ +package de.ozgcloud.alfa.bescheid; + +import java.util.stream.Stream; + +import org.springframework.stereotype.Service; + +import de.ozgcloud.alfa.common.binaryfile.BinaryFileService; +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.user.UserService; +import de.ozgcloud.alfa.vorgang.VorgangWithEingang; +import de.xoev.xdomea.DokumentType; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class ExportBescheidService { + private final BescheidService bescheidService; + private final BinaryFileService binaryFileService; + private final DocumentService documentService; + private final UserService userService; + + public BescheidExportData createExportData(VorgangWithEingang vorgang) { + var builder = BescheidExportData.builder(); + getBescheids(vorgang.getId()) + .forEach(bescheid -> addBescheidExportData(createBescheidExportInput(bescheid, vorgang), builder)); + return builder.build(); + } + + Stream<Bescheid> getBescheids(String vorgangId) { + return bescheidService.findByVorgangIdSorted(vorgangId).filter(bescheid -> BescheidStatus.SENT == bescheid.getStatus()); + } + + BescheidExportInput createBescheidExportInput(Bescheid bescheid, VorgangWithEingang vorgang) { + return BescheidExportInput.builder() + .bescheid(bescheid) + .organisationseinheitenId(vorgang.getOrganisationseinheitenID()) + .files(Stream.concat(Stream.of(getDocument(bescheid)), getAttachments(bescheid)).toList()).build(); + } + + Stream<OzgFile> getAttachments(Bescheid bescheid) { + return binaryFileService.getFiles(bescheid.getAttachments()); + } + + void addBescheidExportData(BescheidExportInput input, BescheidExportData.BescheidExportDataBuilder builder) { + builder.dokumentType(buildDokumentType(input)) + .files(input.files()); + } + + OzgFile getDocument(Bescheid bescheid) { + var document = documentService.getDocument(bescheid.getBescheidDocument()); + return binaryFileService.getFile(document.getFileId()); + } + + DokumentType buildDokumentType(BescheidExportInput input) { + var builder = DokumentTypeBuilder.builder(); + builder.withBescheid(input.bescheid()) + .withFiles(input.files()) + .withFullName(getFullName(input.bescheid())) + .withOrganisationseinheitenId(input.organisationseinheitenId()); + return builder.build(); + } + + String getFullName(Bescheid bescheid) { + return userService.getById(bescheid.getSentInfo().getSentBy()).getFullName(); + } + +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/AnlageDokumentTypeBuilder.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/AnlageDokumentTypeBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..593a6057fb57b48524006a1929bbadfff7e10fd6 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/AnlageDokumentTypeBuilder.java @@ -0,0 +1,37 @@ +package de.ozgcloud.alfa.common; + +import java.time.ZonedDateTime; + +import de.ozgcloud.alfa.common.file.OzgFile; +import de.xoev.xdomea.AnlageDokumentType; + +public class AnlageDokumentTypeBuilder { + private OzgFile ozgFile; + private ZonedDateTime createdAt; + + public static AnlageDokumentTypeBuilder builder() { + return new AnlageDokumentTypeBuilder(); + } + + public AnlageDokumentTypeBuilder withOzgFile(OzgFile ozgFile) { + this.ozgFile = ozgFile; + return this; + } + + public AnlageDokumentTypeBuilder withCreatedAt(ZonedDateTime createdAt) { + this.createdAt = createdAt; + return this; + } + + public AnlageDokumentType build() { + var anlage = new AnlageDokumentType(); + anlage.setIdentifikation(IdentifikationObjektTypeBuilder.builder() + .withObjectID(ozgFile.getId().toString()) + .build()); + anlage.getVersion().add(VersionTypeBuilder.builder() + .withCreatedAt(createdAt) + .withOzgFile(ozgFile).build()); + return anlage; + } + +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/DateConverter.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/DateConverter.java new file mode 100644 index 0000000000000000000000000000000000000000..bce094fc04399c0c5202ada3250837afdaf7b38e --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/DateConverter.java @@ -0,0 +1,60 @@ +package de.ozgcloud.alfa.common; + +import static java.util.Objects.*; + +import java.time.LocalDate; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.GregorianCalendar; +import java.util.Locale; +import java.util.Optional; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; + +import de.ozgcloud.common.errorhandling.TechnicalException; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import lombok.extern.log4j.Log4j2; + +@Log4j2 +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class DateConverter { + + private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("dd.MM.yyyy", Locale.GERMAN); + + public static Optional<XMLGregorianCalendar> convertGermanFormatToISO(String dateStr) { + try { + if (nonNull(dateStr)) { + return Optional.of(createDatatypeFactory().newXMLGregorianCalendar(LocalDate.parse(dateStr, DATE_TIME_FORMATTER).toString())); + } + } catch (Exception e) { + LOG.warn("Date '{}' cannot be converted to ISO format.", dateStr, e); + } + return Optional.empty(); + } + + public static XMLGregorianCalendar toXmlGregorianCalendar(ZonedDateTime date) { + try { + if (nonNull(date)) { + return createDatatypeFactory().newXMLGregorianCalendar(GregorianCalendar.from(date)); + } + } catch (Exception e) { + LOG.warn("Date '{}' cannot be converted to ISO format.", date, e); + } + return null; + } + + public static XMLGregorianCalendar createEmpty() { + return DateConverter.createDatatypeFactory().newXMLGregorianCalendar(); + } + + static DatatypeFactory createDatatypeFactory() { + try { + return DatatypeFactory.newInstance(); + } catch (DatatypeConfigurationException e) { + throw new TechnicalException("Error creating datatype factory.", e); + } + } +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/DateiformatCode.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/DateiformatCode.java new file mode 100644 index 0000000000000000000000000000000000000000..d91a9e7f9e406ce57e3c5c2b8e12e0307136603d --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/DateiformatCode.java @@ -0,0 +1,85 @@ +package de.ozgcloud.alfa.common; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +import org.apache.commons.lang3.StringUtils; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class DateiformatCode { + + static final String SONSTIGES_CODE = "100"; + + // MIME type -> file extension -> xdomea code + private static final Map<String, Map<String, String>> mimeTypesMapping = new HashMap<>(); + + static { + mimeTypesMapping.put("image/bmp", Map.of("bmp", "001")); + mimeTypesMapping.put("text/csv", Map.of("csv", "002")); + mimeTypesMapping.put("application/msword", Map.of("doc", "003", "dot", "032")); + mimeTypesMapping.put("message/rfc822", Map.of("eml", "006")); + mimeTypesMapping.put("text/html", Map.of("htm", "007", "html", "008")); + mimeTypesMapping.put("image/jpeg", Map.of("jpe", "009", "jpeg", "010", "jpg", "011")); + mimeTypesMapping.put("application/vnd.ms-outlook", Map.of("msg", "012")); + mimeTypesMapping.put("application/vnd.oasis.opendocument.presentation", Map.of("odp", "013")); + mimeTypesMapping.put("application/vnd.oasis.opendocument.spreadsheet", Map.of("ods", "014")); + mimeTypesMapping.put("application/vnd.oasis.opendocument.text", Map.of("odt", "015")); + mimeTypesMapping.put("application/vnd.oasis.opendocument.presentation-template", Map.of("otp", "016")); + mimeTypesMapping.put("application/vnd.oasis.opendocument.spreadsheet-template", Map.of("ots", "017")); + mimeTypesMapping.put("application/pdf", Map.of("pdf", "018")); + mimeTypesMapping.put("image/png", Map.of("png", "019")); + mimeTypesMapping.put("application/vnd.ms-powerpoint", Map.of("ppt", "020", "pot", "033")); + mimeTypesMapping.put("application/postscript", Map.of("ps", "021")); + mimeTypesMapping.put("application/rtf", Map.of("rtf", "022")); + mimeTypesMapping.put("image/tiff", Map.of("tif", "023", "tiff", "024")); + mimeTypesMapping.put("application/vnd.ms-works", Map.of("wps", "025")); + mimeTypesMapping.put("application/vnd.ms-excel", Map.of("xlc", "026", "xlm", "027", "xls", "028", "xlw", "029", "xlt", "034")); + mimeTypesMapping.put("application/xml", Map.of("xml", "030", "xsd", "031")); + mimeTypesMapping.put("text/xml", Map.of("xml", "030", "xsd", "031")); + mimeTypesMapping.put("application/vnd.openxmlformats-officedocument.wordprocessingml.document", Map.of("docx", "035")); + mimeTypesMapping.put("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", Map.of("xlsx", "036")); + mimeTypesMapping.put("application/vnd.openxmlformats-officedocument.presentationml.presentation", Map.of("pptx", "037")); + mimeTypesMapping.put("application/vnd.openxmlformats-officedocument.wordprocessingml.template", Map.of("dotx", "038")); + mimeTypesMapping.put("application/vnd.openxmlformats-officedocument.spreadsheetml.template", Map.of("xltx", "039")); + mimeTypesMapping.put("application/vnd.openxmlformats-officedocument.presentationml.template", Map.of("potx", "040")); + mimeTypesMapping.put("application/xml-dtd", Map.of("dtd", "041")); + mimeTypesMapping.put("application/vnd.ms-project", Map.of("mpp", "042")); + mimeTypesMapping.put("application/vnd.oasis.opendocument.text-template", Map.of("ott", "043")); + mimeTypesMapping.put("text/plain", Map.of("txt", "045")); + mimeTypesMapping.put("application/x-pkcs7-certificates", Map.of("p7b", "046")); + mimeTypesMapping.put("application/pkcs7-mime", Map.of("p7c", "047", "p7m", "048")); + mimeTypesMapping.put("application/pkcs7-signature", Map.of("p7s", "049")); + mimeTypesMapping.put("application/vnd.etsi.asic-s+zip", Map.of("asics", "050")); + mimeTypesMapping.put("application/scvp-cv-response", Map.of("scs", "051")); + } + + public static String getXdomeaCode(String mimeType, String extension) { + var fileExtensionToCodeMapping = getFileExtensionToCodeMapping(mimeType); + if (hasSingleExtensionMapping(fileExtensionToCodeMapping)) { + return getCodeOrDefault(fileExtensionToCodeMapping); + } + return getCodeForExtensionOrDefault(extension, fileExtensionToCodeMapping); + } + + private static Map<String, String> getFileExtensionToCodeMapping(String mimeType) { + return mimeTypesMapping.getOrDefault(Objects.requireNonNullElse(mimeType, StringUtils.EMPTY), Collections.emptyMap()); + } + + private static boolean hasSingleExtensionMapping(Map<String, String> fileExtensionToCodeMapping) { + return fileExtensionToCodeMapping.entrySet().size() == 1; + } + + private static String getCodeOrDefault(Map<String, String> fileExtensionToCodeMapping) { + return fileExtensionToCodeMapping.values().stream().findFirst().orElse(SONSTIGES_CODE); + } + + private static String getCodeForExtensionOrDefault(String extension, Map<String, String> fileExtensionToCodeMapping) { + return fileExtensionToCodeMapping.getOrDefault(Objects.requireNonNullElse(extension, StringUtils.EMPTY), SONSTIGES_CODE); + } + +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/DatentypCode.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/DatentypCode.java new file mode 100644 index 0000000000000000000000000000000000000000..3ba6ce26689cb4351cfadb74573181ff22d73846 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/DatentypCode.java @@ -0,0 +1,15 @@ +package de.ozgcloud.alfa.common; + +public enum DatentypCode { + STRING("038"), DATE("005"); + + private String code; + + DatentypCode(String code) { + this.code = code; + } + + public String getCode() { + return code; + } +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/ExportFilenameGenerator.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/ExportFilenameGenerator.java new file mode 100644 index 0000000000000000000000000000000000000000..069f37f3027879d431531ef82ed09efec33a473d --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/ExportFilenameGenerator.java @@ -0,0 +1,13 @@ +package de.ozgcloud.alfa.common; + +import de.ozgcloud.alfa.common.file.OzgFile; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class ExportFilenameGenerator { + + public static String generateExportFilename(OzgFile ozgFile) { + return String.format("%s_%s", UUIDConverter.fromObjectId(ozgFile.getId().toString()), ozgFile.getName()); + } +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/IdentifikationObjektTypeBuilder.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/IdentifikationObjektTypeBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..7eceb19c8d3d952a79d179f0ef6c9e1edb515860 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/IdentifikationObjektTypeBuilder.java @@ -0,0 +1,29 @@ +package de.ozgcloud.alfa.common; + +import de.xoev.xdomea.IdentifikationObjektType; + +public class IdentifikationObjektTypeBuilder { + private String objectID; + private Long ordinalNumber; + + public static IdentifikationObjektTypeBuilder builder() { + return new IdentifikationObjektTypeBuilder(); + } + + public IdentifikationObjektTypeBuilder withObjectID(String objectID) { + this.objectID = objectID; + return this; + } + + public IdentifikationObjektTypeBuilder withOrdinalNumber(Long ordinalNumber) { + this.ordinalNumber = ordinalNumber; + return this; + } + + public IdentifikationObjektType build() { + var identifikation = new IdentifikationObjektType(); + identifikation.setID(UUIDConverter.fromObjectId(objectID)); + identifikation.setNummerImUebergeordnetenContainer(ordinalNumber); + return identifikation; + } +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/PrimaerdokumentTypeBuilder.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/PrimaerdokumentTypeBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..17fc5d419308757c806d8a615e9b8ab2479b8c74 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/PrimaerdokumentTypeBuilder.java @@ -0,0 +1,45 @@ +package de.ozgcloud.alfa.common; + +import java.time.ZonedDateTime; + +import de.ozgcloud.alfa.common.file.OzgFile; +import de.xoev.xdomea.PrimaerdokumentType; + +public class PrimaerdokumentTypeBuilder { + + private OzgFile ozgFile; + private String ersteller; + private ZonedDateTime createdAt; + + public static PrimaerdokumentTypeBuilder builder() { + return new PrimaerdokumentTypeBuilder(); + } + + public PrimaerdokumentTypeBuilder withOzgFile(OzgFile ozgFile) { + this.ozgFile = ozgFile; + return this; + } + + public PrimaerdokumentTypeBuilder withErsteller(String ersteller) { + this.ersteller = ersteller; + return this; + } + + public PrimaerdokumentTypeBuilder withCreatedAt(ZonedDateTime createdAt) { + this.createdAt = createdAt; + return this; + } + + public PrimaerdokumentType build() { + if (ozgFile == null) { + throw new IllegalStateException("Can not build Primaerdokument when ozg file is null"); + } + + var primaerdokument = new PrimaerdokumentType(); + primaerdokument.setDateiname(ExportFilenameGenerator.generateExportFilename(ozgFile)); + primaerdokument.setDateinameOriginal(ozgFile.getName()); + primaerdokument.setErsteller(ersteller); + primaerdokument.setDatumUhrzeit(DateConverter.toXmlGregorianCalendar(createdAt)); + return primaerdokument; + } +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/UUIDConverter.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/UUIDConverter.java new file mode 100644 index 0000000000000000000000000000000000000000..85c84b421c0cf3d916e3ba2c70a372abd268d5d5 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/UUIDConverter.java @@ -0,0 +1,25 @@ +package de.ozgcloud.alfa.common; + +import java.util.regex.Pattern; + +import org.apache.commons.lang3.StringUtils; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class UUIDConverter { + + private static final Pattern UUID_SPLIT_PATTERN = Pattern.compile( + "^([a-fA-F0-9]{8})([a-fA-F0-9]{4})([a-fA-F0-9]{4})([a-fA-F0-9]{4})([a-fA-F0-9]+)$"); + + public static String fromObjectId(String objectId) { + var matcher = UUID_SPLIT_PATTERN.matcher(objectId); + if (matcher.find()) { + var lastGroup = StringUtils.leftPad(matcher.group(5), 12, "0"); + return String.format("%s-%s-%s-%s-%s", matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(4), lastGroup); + } + throw new IllegalArgumentException(String.format("Invalid object id %s", objectId)); + } + +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/VersionTypeBuilder.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/VersionTypeBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..3937b36d4eb85deb773eac2dcd0d1cad63a098c7 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/common/VersionTypeBuilder.java @@ -0,0 +1,73 @@ +package de.ozgcloud.alfa.common; + +import java.time.ZonedDateTime; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.StringUtils; + +import de.ozgcloud.alfa.common.file.OzgFile; +import de.xoev.xdomea.DateiformatCodeType; +import de.xoev.xdomea.FormatType; +import de.xoev.xdomea.VersionType; + +public class VersionTypeBuilder { + public static final String VERSION_NUMMER = "1"; + public static final String DATEI_FORMAT_LIST_URI = "urn:xoev-de:xdomea:codeliste:dateiformat"; + public static final String LIST_VERSION_ID = "2.0"; + private OzgFile ozgFile; + private ZonedDateTime createdAt; + private String ersteller; + private String sonstigerName; + + public static VersionTypeBuilder builder() { + return new VersionTypeBuilder(); + } + + public VersionTypeBuilder withOzgFile(OzgFile ozgFile) { + this.ozgFile = ozgFile; + return this; + } + + public VersionTypeBuilder withCreatedAt(ZonedDateTime createdAt) { + this.createdAt = createdAt; + return this; + } + + public VersionTypeBuilder withErsteller(String ersteller) { + this.ersteller = ersteller; + return this; + } + + public VersionTypeBuilder withSonstigerName(String sonstigerName) { + this.sonstigerName = sonstigerName; + return this; + } + + public VersionType build() { + var versionType = new VersionType(); + versionType.setNummer(VERSION_NUMMER); + versionType.getFormat().add(createFormatType()); + return versionType; + } + + FormatType createFormatType() { + var formatType = new FormatType(); + formatType.setName(createDateiformatCodeType()); + formatType.setVersion(StringUtils.EMPTY); + formatType.setSonstigerName(sonstigerName); + formatType.setPrimaerdokument(PrimaerdokumentTypeBuilder.builder() + .withCreatedAt(createdAt) + .withErsteller(ersteller) + .withOzgFile(ozgFile) + .build()); + return formatType; + } + + DateiformatCodeType createDateiformatCodeType() { + var dateiformatCode = new DateiformatCodeType(); + dateiformatCode.setCode(DateiformatCode.getXdomeaCode(ozgFile.getContentType(), FilenameUtils.getExtension(ozgFile.getName()).toLowerCase())); + dateiformatCode.setListURI(DATEI_FORMAT_LIST_URI); + dateiformatCode.setListVersionID(LIST_VERSION_ID); + return dateiformatCode; + } +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/ExportConfiguration.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/ExportConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..1ad1ea37461edf34756e2f478e3b56cc74e2bd88 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/ExportConfiguration.java @@ -0,0 +1,43 @@ +package de.ozgcloud.alfa.export; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.oxm.jaxb.Jaxb2Marshaller; +import org.springframework.validation.Validator; + +import jakarta.xml.bind.Marshaller; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Configuration +class ExportConfiguration { + + static final boolean JAXB_FORMATTED_OUTPUT = true; + static final String PROPERTY_NAMESPACE_PREFIX_MAPPER = "org.glassfish.jaxb.namespacePrefixMapper"; + static final String CONTEXT_PATH = "de.xoev.xdomea"; + + private final XdomeaNamespacePrefixMapper prefixMapper; + + @Bean + static Validator configurationPropertiesValidator() { + return new XdomeaPropertiesValidator(); + } + + @Bean + Jaxb2Marshaller marshaller() { + var marshaller = new Jaxb2Marshaller(); + marshaller.setContextPaths(CONTEXT_PATH); + marshaller.setMarshallerProperties(createMarshallerProperties()); + return marshaller; + } + + Map<String, Object> createMarshallerProperties() { + var props = new HashMap<String, Object>(); + props.put(Marshaller.JAXB_FORMATTED_OUTPUT, JAXB_FORMATTED_OUTPUT); + props.put(PROPERTY_NAMESPACE_PREFIX_MAPPER, prefixMapper); + return props; + } +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/ExportData.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/ExportData.java new file mode 100644 index 0000000000000000000000000000000000000000..bea5d003d18ce25769862c1f57f22e92584e469e --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/ExportData.java @@ -0,0 +1,21 @@ +package de.ozgcloud.alfa.export; + +import java.util.Set; + +import de.ozgcloud.alfa.common.file.OzgFile; +import de.xoev.xdomea.AbgabeAbgabe0401; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +@Builder +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@Getter +class ExportData { + + private String exportFilename; + private AbgabeAbgabe0401 abgabe; + private Set<OzgFile> exportFiles; + +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/ExportService.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/ExportService.java new file mode 100644 index 0000000000000000000000000000000000000000..65de7b375a079150afa974bd1dfc23ea0607b598 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/ExportService.java @@ -0,0 +1,140 @@ +package de.ozgcloud.alfa.export; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import de.ozgcloud.alfa.bescheid.ExportBescheidService; +import de.ozgcloud.alfa.common.ExportFilenameGenerator; +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.file.ExportFileService; +import de.ozgcloud.alfa.historie.ExportHistorieService; +import de.ozgcloud.alfa.kommentar.ExportKommentarService; +import de.ozgcloud.alfa.postfach.ExportNachrichtService; +import de.ozgcloud.alfa.vorgang.Eingang; +import de.ozgcloud.alfa.vorgang.EingangHeader; +import de.ozgcloud.alfa.vorgang.ExportVorgangService; +import de.ozgcloud.alfa.vorgang.VorgangWithEingang; +import de.ozgcloud.common.binaryfile.TempFileUtils; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.xoev.xdomea.AbgabeAbgabe0401; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Service +class ExportService { + + static final String EXPORT_FILENAME_SUFFIX = "_Abgabe.Abgabe.0401.xml"; + private static final String EXPORT_FILENAME_TEMPLATE = "%s" + EXPORT_FILENAME_SUFFIX; + + private final XdomeaXmlMarshaller xDomeaXmlMarshaller; + + private final ExportFileService exportFileService; + private final ExportVorgangService exportVorgangService; + private final ExportHistorieService exportHistorieService; + private final ExportKommentarService exportKommentarService; + private final ExportNachrichtService exportNachrichtService; + private final ExportBescheidService exportBescheidService; + + public void writeExport(String vorgangId, String filenameId, OutputStream out) { + var exportData = collectExportData(vorgangId, filenameId); + var zipFile = createZipFile(exportData); + writeZipFileContent(zipFile, out); + } + + ExportData collectExportData(String vorgangId, String filenameId) { + var vorgang = exportVorgangService.getVorgang(vorgangId); + var kommentarsData = exportKommentarService.createExportData(vorgang); + var postfachMailData = exportNachrichtService.createExportData(vorgang); + var bescheidData = exportBescheidService.createExportData(vorgang); + var representations = exportFileService.getRepresentations(vorgang).toList(); + var attachments = exportFileService.getAttachments(vorgang).toList(); + var formEngineName = getFormEngineName(vorgang); + var abgabe = XdomeaNachrichtBuilder.builder() + .withKopf(exportVorgangService.createKopf(vorgang)) + .withVorgang(exportVorgangService.createVorgangType(vorgang)) + .withAktenzeichen(exportVorgangService.createAkteType(vorgang)) + .withRepresentations(exportFileService.createDokumentTypes(representations, formEngineName).toList()) + .withAttachments(exportFileService.createDokumentTypes(attachments, formEngineName).toList()) + .withHistorie(exportHistorieService.createHistorienProtokollInformationTypes(vorgang).toList()) + .withKommentare(kommentarsData.getDokumentTypes()) + .withPostfachMails(postfachMailData.getDokumentTypes()) + .withBescheids(bescheidData.getDokumentTypes()) + .build(); + var exportFiles = Stream + .of(representations.stream(), attachments.stream(), + kommentarsData.getAttachments().stream(), + postfachMailData.getAttachments().stream(), + bescheidData.getFiles().stream()) + .flatMap(s -> s) + .collect(Collectors.toSet()); + return ExportData.builder().abgabe(abgabe).exportFilename(buildXmlFilename(filenameId)).exportFiles(exportFiles).build(); + } + + String getFormEngineName(VorgangWithEingang vorgang) { + return Optional.ofNullable(vorgang.getEingang()) + .map(Eingang::getHeader) + .map(EingangHeader::getFormEngineName).orElse(StringUtils.EMPTY); + } + + String buildXmlFilename(String filenameId) { + return String.format(EXPORT_FILENAME_TEMPLATE, filenameId); + } + + String createXmlContent(AbgabeAbgabe0401 abgabe) { + return xDomeaXmlMarshaller.marshal(abgabe); + } + + File createZipFile(ExportData exportData) { + var file = TempFileUtils.createTmpFile().toFile(); + try (var zipOutputStream = new ZipOutputStream(new FileOutputStream(file))) { + putZipEntry(exportData.getExportFilename(), createXmlContent(exportData.getAbgabe()), zipOutputStream); + putFilesIntoZip(exportData.getExportFiles(), zipOutputStream); + return file; + } catch (Exception e) { + throw new TechnicalException("Error creating xdomea zip file", e); + } + } + + void putZipEntry(String fileName, String fileData, ZipOutputStream zipOutputStream) throws IOException { + var entry = new ZipEntry(fileName); + zipOutputStream.putNextEntry(entry); + zipOutputStream.write(fileData.getBytes(StandardCharsets.UTF_8)); + zipOutputStream.closeEntry(); + } + + private void putFilesIntoZip(Set<OzgFile> ozgFiles, ZipOutputStream zipOutputStream) { + ozgFiles.forEach(ozgFile -> putOzgFileIntoZip(ozgFile, zipOutputStream)); + } + + void putOzgFileIntoZip(OzgFile ozgFile, ZipOutputStream zipOutputStream) { + try { + var entry = new ZipEntry(ExportFilenameGenerator.generateExportFilename(ozgFile)); + zipOutputStream.putNextEntry(entry); + exportFileService.writeOzgFile(ozgFile.getId(), zipOutputStream); + zipOutputStream.closeEntry(); + } catch (IOException e) { + throw new TechnicalException("Cannot add file to ZIP.", e); + } + } + + void writeZipFileContent(File file, OutputStream outputStream) { + try (var fileInputStream = new FileInputStream(file)) { + fileInputStream.transferTo(outputStream); + } catch (Exception e) { + throw new TechnicalException("Error writing xdomea zip file to output stream", e); + } + } +} diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/export/ExportVorgangController.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/ExportVorgangController.java similarity index 64% rename from alfa-service/src/main/java/de/ozgcloud/alfa/export/ExportVorgangController.java rename to alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/ExportVorgangController.java index abd43c474649b916f33e8992f21d44784bb332ff..052b36cd92c182aad9838aefe8f108b358af4e65 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/export/ExportVorgangController.java +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/ExportVorgangController.java @@ -1,5 +1,7 @@ package de.ozgcloud.alfa.export; +import java.util.UUID; + import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -11,21 +13,27 @@ import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBo import lombok.RequiredArgsConstructor; +@RequiredArgsConstructor @RestController @RequestMapping(ExportVorgangController.PATH) -@RequiredArgsConstructor public class ExportVorgangController { static final String PATH = "/api/vorgangs"; // NOSONAR - private final ExportRemoteService exportRemoteService; + private static final String EXPORT_FILENAME_TEMPLATE = "%s_Abgabe.Abgabe.0401.xdomea"; + + private final ExportService xDomeaService; @GetMapping(value = "{vorgangId}", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) - public ResponseEntity<StreamingResponseBody> exportVorgang(@PathVariable String vorgangId) { - var exportedVorgangFile = exportRemoteService.exportVorgang(vorgangId); + public ResponseEntity<StreamingResponseBody> exportToXdomea(@PathVariable String vorgangId) { + var filenameId = UUID.randomUUID().toString(); return ResponseEntity.ok() - .header(HttpHeaders.CONTENT_DISPOSITION, String.format("attachment; filename=%s", exportedVorgangFile.getFileName())) + .header(HttpHeaders.CONTENT_DISPOSITION, String.format("attachment; filename=%s", buildZipFilename(filenameId))) .contentType(MediaType.APPLICATION_OCTET_STREAM) - .body(exportedVorgangFile::writeToOutputStream); + .body(out -> xDomeaService.writeExport(vorgangId, filenameId, out)); + } + + String buildZipFilename(String filenameId) { + return String.format(EXPORT_FILENAME_TEMPLATE, filenameId); } } diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/export/ExportVorgangProcessor.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/ExportVorgangProcessor.java similarity index 96% rename from alfa-service/src/main/java/de/ozgcloud/alfa/export/ExportVorgangProcessor.java rename to alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/ExportVorgangProcessor.java index 8c570cff79bdad0796683d6ecaf92888c841138f..b7621e342cb52f19593b07ee03384b25285feb6e 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/export/ExportVorgangProcessor.java +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/ExportVorgangProcessor.java @@ -33,7 +33,7 @@ class ExportVorgangProcessor implements RepresentationModelProcessor<EntityModel return ModelBuilder.fromModel(model) .ifMatch(IS_VORGANG_ABGESCHLOSSEN) - .addLink(linkTo(methodOn(ExportVorgangController.class).exportVorgang(vorgang.getId())).withRel(REL_EXPORT)) + .addLink(linkTo(methodOn(ExportVorgangController.class).exportToXdomea(vorgang.getId())).withRel(REL_EXPORT)) .buildModel(); } } diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/XdomeaMedienart.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/XdomeaMedienart.java new file mode 100644 index 0000000000000000000000000000000000000000..42338a5e6befc601a62735b18d700dfee7fcc795 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/XdomeaMedienart.java @@ -0,0 +1,16 @@ +package de.ozgcloud.alfa.export; + +enum XdomeaMedienart { + + ELEKTRONISCHES_DOKUMENT("001"); + + private String code; + + XdomeaMedienart(String code) { + this.code = code; + } + + public String getCode() { + return code; + } +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/XdomeaNachrichtBuilder.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/XdomeaNachrichtBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..644265c961a0a0d943d721d12d5f1c5c9d33d067 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/XdomeaNachrichtBuilder.java @@ -0,0 +1,115 @@ +package de.ozgcloud.alfa.export; + +import java.util.Collections; +import java.util.List; + +import de.xoev.xdomea.AbgabeAbgabe0401; +import de.xoev.xdomea.AbgabeAbgabe0401.Schriftgutobjekt; +import de.xoev.xdomea.AkteType; +import de.xoev.xdomea.DokumentType; +import de.xoev.xdomea.HistorienProtokollInformationType; +import de.xoev.xdomea.NkAbgabeType; +import de.xoev.xdomea.VorgangType; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +class XdomeaNachrichtBuilder { + + private VorgangType vorgang; + private NkAbgabeType kopf; + private AkteType aktenzeichen; + private List<DokumentType> representations = Collections.emptyList(); + private List<DokumentType> attachments = Collections.emptyList(); + private List<DokumentType> kommentare = Collections.emptyList(); + private List<DokumentType> postfachMails = Collections.emptyList(); + private List<DokumentType> bescheids = Collections.emptyList(); + private List<HistorienProtokollInformationType> historie = Collections.emptyList(); + + public static XdomeaNachrichtBuilder builder() { + return new XdomeaNachrichtBuilder(); + } + + public XdomeaNachrichtBuilder withKopf(NkAbgabeType kopf) { + this.kopf = kopf; + return this; + } + + public XdomeaNachrichtBuilder withVorgang(VorgangType vorgangType) { + this.vorgang = vorgangType; + return this; + } + + public XdomeaNachrichtBuilder withAktenzeichen(AkteType akteType) { + this.aktenzeichen = akteType; + return this; + } + + public XdomeaNachrichtBuilder withRepresentations(List<DokumentType> representations) { + this.representations = representations; + return this; + } + + public XdomeaNachrichtBuilder withAttachments(List<DokumentType> attachments) { + this.attachments = attachments; + return this; + } + + public XdomeaNachrichtBuilder withHistorie(List<HistorienProtokollInformationType> historie) { + this.historie = historie; + return this; + } + + public XdomeaNachrichtBuilder withKommentare(List<DokumentType> kommentare) { + this.kommentare = kommentare; + return this; + } + + public XdomeaNachrichtBuilder withPostfachMails(List<DokumentType> postfachMails) { + this.postfachMails = postfachMails; + return this; + } + + public XdomeaNachrichtBuilder withBescheids(List<DokumentType> bescheids) { + this.bescheids = bescheids; + return this; + } + + public AbgabeAbgabe0401 build() { + addVorgangDokumente(); + addVorgangChangeHistory(); + return createAbgabeType(); + } + + void addVorgangDokumente() { + representations.forEach(vorgang.getDokument()::add); + attachments.forEach(vorgang.getDokument()::add); + kommentare.forEach(vorgang.getDokument()::add); + postfachMails.forEach(vorgang.getDokument()::add); + bescheids.forEach(vorgang.getDokument()::add); + } + + void addVorgangChangeHistory() { + historie.forEach(vorgang.getHistorienProtokollInformation()::add); + } + + AbgabeAbgabe0401 createAbgabeType() { + var abgabeType = new AbgabeAbgabe0401(); + abgabeType.setKopf(kopf); + abgabeType.getSchriftgutobjekt().add(createSchriftgutobjektVorgang()); + abgabeType.getSchriftgutobjekt().add(createSchriftgutobjektAkte()); + return abgabeType; + } + + private Schriftgutobjekt createSchriftgutobjektVorgang() { + var schriftgutobjekt = new Schriftgutobjekt(); + schriftgutobjekt.setVorgang(vorgang); + return schriftgutobjekt; + } + + private Schriftgutobjekt createSchriftgutobjektAkte() { + var schriftgutobjekt = new Schriftgutobjekt(); + schriftgutobjekt.setAkte(aktenzeichen); + return schriftgutobjekt; + } +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/XdomeaNamespacePrefixMapper.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/XdomeaNamespacePrefixMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..08894a2387b574d9616faebb9eac3d15603f772c --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/XdomeaNamespacePrefixMapper.java @@ -0,0 +1,47 @@ +package de.ozgcloud.alfa.export; + +import java.util.Map; + +import org.glassfish.jaxb.runtime.marshaller.NamespacePrefixMapper; +import org.springframework.stereotype.Component; + +@Component +class XdomeaNamespacePrefixMapper extends NamespacePrefixMapper { + + static final String XDOMEA_NAMESPACE_URI = "urn:xoev-de:xdomea:schema:3.0.0"; + static final String XDOMEA_NAMESPACE_PREFIX = "xdomea"; + + static final String XDOMEA_NAMESPACE_DINSPEC = "dinspec91379"; + static final String XDOMEA_NAMESPACE_DINSPEC_URI = "urn:xoev-de:kosit:xoev:datentyp:din-spec-91379_2019-03"; + + static final String XDOMEA_NAMESPACE_GML = "gml"; + static final String XDOMEA_NAMESPACE_GML_URI = "http://www.opengis.net/gml/3.2"; + + static final String XDOMEA_NAMESPACE_XOEV_CODE = "xoev-code"; + static final String XDOMEA_NAMESPACE_XOEV_CODE_URI = "http://xoev.de/schemata/code/1_0"; + + static final String XDOMEA_NAMESPACE_XOEV_LC = "xoev-lc"; + static final String XDOMEA_NAMESPACE_XOEV_LC_URI = "http://xoev.de/latinchars/1_1/datatypes"; + + private static final Map<String, String> NAMESPACE_MAP = Map.of( + XDOMEA_NAMESPACE_URI, XDOMEA_NAMESPACE_PREFIX, + XDOMEA_NAMESPACE_DINSPEC_URI, XDOMEA_NAMESPACE_DINSPEC, + XDOMEA_NAMESPACE_GML_URI, XDOMEA_NAMESPACE_GML, + XDOMEA_NAMESPACE_XOEV_CODE_URI, XDOMEA_NAMESPACE_XOEV_CODE, + XDOMEA_NAMESPACE_XOEV_LC_URI, XDOMEA_NAMESPACE_XOEV_LC); + + @Override + public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) { + return NAMESPACE_MAP.getOrDefault(namespaceUri, suggestion); + } + + @Override + public String[] getPreDeclaredNamespaceUris() { + return new String[] { + XDOMEA_NAMESPACE_DINSPEC_URI, + XDOMEA_NAMESPACE_GML_URI, + XDOMEA_NAMESPACE_XOEV_CODE_URI, + XDOMEA_NAMESPACE_XOEV_LC_URI + }; + } +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/XdomeaProperties.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/XdomeaProperties.java new file mode 100644 index 0000000000000000000000000000000000000000..2d2157c690d1b1c354875b477ec6163752cc1234 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/XdomeaProperties.java @@ -0,0 +1,26 @@ +package de.ozgcloud.alfa.export; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.springframework.validation.annotation.Validated; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Configuration +@ConfigurationProperties("ozgcloud.xdomea") +@Validated +@Builder +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class XdomeaProperties { + + private String behoerdenschluessel; + private String behoerdenschluesselUri; + private String behoerdenschluesselVersion; +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/XdomeaPropertiesValidator.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/XdomeaPropertiesValidator.java new file mode 100644 index 0000000000000000000000000000000000000000..8cc320ecb6346fbc79bd42a2826b08bec38aaff3 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/XdomeaPropertiesValidator.java @@ -0,0 +1,44 @@ +package de.ozgcloud.alfa.export; + +import org.apache.commons.beanutils.BeanUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.validation.Errors; +import org.springframework.validation.Validator; + +import de.ozgcloud.common.errorhandling.TechnicalException; + +public class XdomeaPropertiesValidator implements Validator { + + @Override + public boolean supports(Class<?> clazz) { + return XdomeaProperties.class.isAssignableFrom(clazz); + } + + @Override + public void validate(Object target, Errors errors) { + var properties = (XdomeaProperties) target; + validateBehoerdenschluesselProperties(errors, properties); + } + + private void validateBehoerdenschluesselProperties(Errors errors, XdomeaProperties properties) { + if (StringUtils.isNotBlank(properties.getBehoerdenschluessel())) { + validateNotBlank("behoerdenschluesselUri", properties, errors); + validateNotBlank("behoerdenschluesselVersion", properties, errors); + } + } + + private void validateNotBlank(String propertyName, XdomeaProperties properties, Errors errors) { + getPropertyValue(propertyName, properties); + if (StringUtils.isBlank(getPropertyValue(propertyName, properties))) { + errors.rejectValue(propertyName, String.format("ozgcloud.xdomea.%s.empty", propertyName), String.format("%s must be set", propertyName)); + } + } + + private static String getPropertyValue(String fieldName, XdomeaProperties properties) { + try { + return BeanUtils.getSimpleProperty(properties, fieldName); + } catch (Exception e) { + throw new TechnicalException("Property does not exist", e); + } + } +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/XdomeaXmlMarshaller.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/XdomeaXmlMarshaller.java new file mode 100644 index 0000000000000000000000000000000000000000..441bd579380934ebdfe3d26a587d92afe4f711b5 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/export/XdomeaXmlMarshaller.java @@ -0,0 +1,24 @@ +package de.ozgcloud.alfa.export; + +import java.io.StringWriter; + +import javax.xml.transform.stream.StreamResult; + +import org.springframework.oxm.jaxb.Jaxb2Marshaller; +import org.springframework.stereotype.Component; + +import de.xoev.xdomea.AbgabeAbgabe0401; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Component +public class XdomeaXmlMarshaller { + + private final Jaxb2Marshaller marshaller; + + public String marshal(AbgabeAbgabe0401 abgabe) { + var stringWriter = new StringWriter(); + marshaller.marshal(abgabe, new StreamResult(stringWriter)); + return stringWriter.toString(); + } +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/file/DokumentTypeBuilder.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/file/DokumentTypeBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..f0a11becc28fcd9642d620b1298f5d59ead96e1a --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/file/DokumentTypeBuilder.java @@ -0,0 +1,82 @@ +package de.ozgcloud.alfa.file; + +import org.apache.commons.lang3.StringUtils; + +import de.ozgcloud.alfa.common.IdentifikationObjektTypeBuilder; +import de.ozgcloud.alfa.common.VersionTypeBuilder; +import de.ozgcloud.alfa.common.file.OzgFile; +import de.xoev.xdomea.AllgemeineMetadatenType; +import de.xoev.xdomea.DokumentType; +import de.xoev.xdomea.IdentifikationObjektType; +import de.xoev.xdomea.MediumCodeType; +import de.xoev.xdomea.VersionType; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class DokumentTypeBuilder { + + static final String VERSION_NUMMER = "1"; + static final String ALLGEMEINE_METADATEN_MEDIUM_CODE = "001"; + + private Long ordinalNumber; + private String formEngineName; + private OzgFile ozgFile; + + public static DokumentTypeBuilder builder() { + return new DokumentTypeBuilder(); + } + + public DokumentTypeBuilder withOrdinalNumber(Long ordinalNumber) { + this.ordinalNumber = ordinalNumber; + return this; + } + + public DokumentTypeBuilder withFormEngineName(String formEngineName) { + this.formEngineName = formEngineName; + return this; + } + + public DokumentTypeBuilder withOzgFile(OzgFile ozgFile) { + this.ozgFile = ozgFile; + return this; + } + + public DokumentType build() { + var dokumentType = new DokumentType(); + dokumentType.setIdentifikation(createIdentifikation()); + dokumentType.setAllgemeineMetadaten(createAllgemeineMetadaten()); + dokumentType.getVersion().add(createVersionType()); + return dokumentType; + } + + VersionType createVersionType() { + return VersionTypeBuilder.builder() + .withOzgFile(ozgFile) + .withErsteller(formEngineName) + .withSonstigerName(StringUtils.EMPTY) + .build(); + } + + IdentifikationObjektType createIdentifikation() { + return IdentifikationObjektTypeBuilder.builder() + .withObjectID(ozgFile.getId().toString()) + .withOrdinalNumber(ordinalNumber) + .build(); + } + + AllgemeineMetadatenType createAllgemeineMetadaten() { + var allgemeineMetadaten = new AllgemeineMetadatenType(); + allgemeineMetadaten.setBetreff(ozgFile.getName()); + allgemeineMetadaten.setKennzeichen(StringUtils.EMPTY); + allgemeineMetadaten.setBemerkung(StringUtils.EMPTY); + allgemeineMetadaten.setMedium(createMediumCode()); + return allgemeineMetadaten; + } + + private MediumCodeType createMediumCode() { + var mediumCode = new MediumCodeType(); + mediumCode.setCode(ALLGEMEINE_METADATEN_MEDIUM_CODE); + return mediumCode; + } +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/file/ExportFileService.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/file/ExportFileService.java new file mode 100644 index 0000000000000000000000000000000000000000..fd7442319cbf13109c91a94e72a04cc5d5af764d --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/file/ExportFileService.java @@ -0,0 +1,46 @@ +package de.ozgcloud.alfa.file; + +import java.io.OutputStream; +import java.util.List; +import java.util.concurrent.atomic.AtomicLong; +import java.util.stream.Stream; + +import org.springframework.stereotype.Service; + +import de.ozgcloud.alfa.common.binaryfile.BinaryFileService; +import de.ozgcloud.alfa.common.binaryfile.FileId; +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.file.OzgFileService; +import de.ozgcloud.alfa.vorgang.VorgangWithEingang; +import de.xoev.xdomea.DokumentType; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Service +public class ExportFileService { + + private final OzgFileService ozgFileService; + private final BinaryFileService binaryFileService; + + public Stream<OzgFile> getRepresentations(VorgangWithEingang vorgang) { + return ozgFileService.getRepresentations(vorgang.getId()); + } + + public Stream<OzgFile> getAttachments(VorgangWithEingang vorgang) { + return ozgFileService.getAttachments(vorgang.getId()); + } + + public Stream<DokumentType> createDokumentTypes(List<OzgFile> ozgFiles, String formEngineName) { + var ordinalNumberGenerator = new AtomicLong(1); + return ozgFiles.stream().map(ozgFile -> DokumentTypeBuilder.builder() + .withOrdinalNumber(ordinalNumberGenerator.getAndIncrement()) + .withFormEngineName(formEngineName) + .withOzgFile(ozgFile) + .build()); + } + + public void writeOzgFile(FileId fileId, OutputStream outputStream) { + binaryFileService.writeFileContent(fileId, outputStream); + } + +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/historie/ExportHistorieService.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/historie/ExportHistorieService.java new file mode 100644 index 0000000000000000000000000000000000000000..4f3e62cffd7e5a5e07f7dccc55a2f8ca59e092f7 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/historie/ExportHistorieService.java @@ -0,0 +1,66 @@ +package de.ozgcloud.alfa.historie; + +import java.util.function.Function; +import java.util.stream.Stream; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import de.ozgcloud.alfa.common.DateConverter; +import de.ozgcloud.alfa.common.command.CommandOrder; +import de.ozgcloud.alfa.vorgang.VorgangWithEingang; +import de.xoev.xdomea.HistorienProtokollInformationType; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Service +public class ExportHistorieService { + + private final VorgangChangeHistoryService vorgangChangeHistoryService; + + public Stream<HistorienProtokollInformationType> createHistorienProtokollInformationTypes(VorgangWithEingang vorgang) { + var history = vorgangChangeHistoryService.createVorgangChangeHistory(vorgang); + return Stream.of( + history.getStatusChangeHistory().stream().map(this::createHistorienProtokollInformationType), + history.getAktenzeichenChangeHistory().stream().map(this::createHistorienProtokollInformationType), + history.getAssignedUserChangeHistory().stream().map(this::createHistorienProtokollInformationType)) + .flatMap(Function.identity()); + } + + HistorienProtokollInformationType createHistorienProtokollInformationType(VorgangChange vorgangChange) { + var historienProtokollInformationType = new HistorienProtokollInformationType(); + historienProtokollInformationType.setMetadatumAlterWert(createValueBeforeChange(vorgangChange)); + historienProtokollInformationType.setMetadatumNeuerWert(createValueAfterChange(vorgangChange)); + historienProtokollInformationType.setAkteur(createAkteur(vorgangChange)); + historienProtokollInformationType.setDatumUhrzeit(DateConverter.toXmlGregorianCalendar(vorgangChange.getFinishedAt())); + historienProtokollInformationType.setAktion(vorgangChange.getOrder()); + return historienProtokollInformationType; + } + + String createAkteur(VorgangChange vorgangChange) { + return appendOrganisationseinheitenID(vorgangChange.getAuthorFullName(), vorgangChange.getOrganisationseinheitenID()); + } + + String createValueBeforeChange(VorgangChange vorgangChange) { + return createValueChange(vorgangChange, vorgangChange.getValueBeforeChange()); + } + + String createValueAfterChange(VorgangChange vorgangChange) { + return createValueChange(vorgangChange, vorgangChange.getValueAfterChange()); + } + + private String createValueChange(VorgangChange vorgangChange, String valueChange) { + if (isAssignUserOrder(vorgangChange)) { + return appendOrganisationseinheitenID(valueChange, vorgangChange.getOrganisationseinheitenID()); + } + return valueChange; + } + + private boolean isAssignUserOrder(VorgangChange vorgangChange) { + return vorgangChange.getOrder().equals(CommandOrder.ASSIGN_USER.name()); + } + + String appendOrganisationseinheitenID(String text, String organisationseinheitenID) { + return StringUtils.isNotBlank(text) ? text + "; " + organisationseinheitenID : StringUtils.EMPTY; + } +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/kommentar/DokumentTypeBuilder.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/kommentar/DokumentTypeBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..26ca34e45be143fbd7aa2d46c5cd21f223416835 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/kommentar/DokumentTypeBuilder.java @@ -0,0 +1,79 @@ +package de.ozgcloud.alfa.kommentar; + +import java.util.Collections; +import java.util.List; + +import de.ozgcloud.alfa.common.AnlageDokumentTypeBuilder; +import de.ozgcloud.alfa.common.DateConverter; +import de.ozgcloud.alfa.common.IdentifikationObjektTypeBuilder; +import de.ozgcloud.alfa.common.file.OzgFile; +import de.xoev.xdomea.AnlageDokumentType; +import de.xoev.xdomea.DokumentType; +import de.xoev.xdomea.HistorienProtokollInformationType; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +class DokumentTypeBuilder { + + static final String TYP = "Notiz"; + static final String AKTION = "CREATE_KOMMENTAR"; + + private Kommentar kommentar; + private List<OzgFile> kommentarAttachments = Collections.emptyList(); + private String authorFullName; + private String organisationseinheitenID; + + public static DokumentTypeBuilder builder() { + return new DokumentTypeBuilder(); + } + + public DokumentTypeBuilder withKommentar(Kommentar kommentar) { + this.kommentar = kommentar; + return this; + } + + public DokumentTypeBuilder withKommentarAttachments(List<OzgFile> kommentarAttachments) { + this.kommentarAttachments = kommentarAttachments; + return this; + } + + public DokumentTypeBuilder withAuthorFullName(String authorFullName) { + this.authorFullName = authorFullName; + return this; + } + + public DokumentTypeBuilder withOrganisationseinheitenID(String organisationseinheitenID) { + this.organisationseinheitenID = organisationseinheitenID; + return this; + } + + public DokumentType build() { + var dokumentType = new DokumentType(); + dokumentType.setIdentifikation(IdentifikationObjektTypeBuilder.builder() + .withObjectID(kommentar.getId()) + .build()); + dokumentType.setTyp(TYP); + dokumentType.getHistorienProtokollInformation().add(createHistorie()); + kommentarAttachments.stream().map(this::createAnlage).forEach(dokumentType.getAnlage()::add); + return dokumentType; + } + + AnlageDokumentType createAnlage(OzgFile ozgFile) { + return AnlageDokumentTypeBuilder.builder().withOzgFile(ozgFile).build(); + } + + HistorienProtokollInformationType createHistorie() { + var historienProtokollInformationType = new HistorienProtokollInformationType(); + historienProtokollInformationType.setMetadatumName(kommentar.getText()); + historienProtokollInformationType.setAkteur(createAkteur()); + historienProtokollInformationType.setDatumUhrzeit(DateConverter.toXmlGregorianCalendar(kommentar.getCreatedAt())); + historienProtokollInformationType.setAktion(AKTION); + return historienProtokollInformationType; + } + + String createAkteur() { + return this.authorFullName + "; " + this.organisationseinheitenID; + } + +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/kommentar/ExportKommentarService.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/kommentar/ExportKommentarService.java new file mode 100644 index 0000000000000000000000000000000000000000..1d4d9e209314cb629342e45e5c0ca18ab9e57fb1 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/kommentar/ExportKommentarService.java @@ -0,0 +1,67 @@ +package de.ozgcloud.alfa.kommentar; + +import java.util.List; +import java.util.stream.Stream; + +import org.springframework.stereotype.Service; + +import de.ozgcloud.alfa.common.binaryfile.BinaryFileService; +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.user.UserId; +import de.ozgcloud.alfa.common.user.UserService; +import de.ozgcloud.alfa.kommentar.KommentarsExportData.KommentarsExportDataBuilder; +import de.ozgcloud.alfa.vorgang.VorgangWithEingang; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Service +public class ExportKommentarService { + + private final KommentarService kommentarService; + private final BinaryFileService binaryFileService; + private final UserService userService; + + public KommentarsExportData createExportData(VorgangWithEingang vorgang) { + KommentarsExportDataBuilder builder = KommentarsExportData.builder(); + getKommentare(vorgang) + .map(kommentar -> createKommentarExportData(vorgang, kommentar)) + .forEach(kommentarExportData -> addKommentarExportData(kommentarExportData, builder)); + return builder.build(); + } + + KommentarExportData createKommentarExportData(VorgangWithEingang vorgang, Kommentar kommentar){ + return new KommentarExportData(vorgang.getOrganisationseinheitenID(), kommentar); + } + + void addKommentarExportData(KommentarExportData kommentarExportData, KommentarsExportDataBuilder builder) { + List<OzgFile> attachments = getAttachments(kommentarExportData.kommentar); + + var dokumentType = DokumentTypeBuilder.builder() + .withKommentarAttachments(attachments) + .withKommentar(kommentarExportData.kommentar) + .withOrganisationseinheitenID(kommentarExportData.organisationsEinheitenID) + .withAuthorFullName(getAuthorFullName(kommentarExportData.kommentar)) + .build(); + + builder.dokumentType(dokumentType); + builder.attachments(attachments); + } + + List<OzgFile> getAttachments(Kommentar kommentar) { + return binaryFileService.getFiles(kommentar.getAttachments()).toList(); + } + + String getAuthorFullName(Kommentar kommentar) { + return userService.getById(UserId.from(kommentar.getCreatedBy())).getFullName(); + } + + Stream<Kommentar> getKommentare(VorgangWithEingang vorgang) { + return kommentarService.findByVorgangId(vorgang.getId()); + } + + record KommentarExportData( + String organisationsEinheitenID, + Kommentar kommentar + ) { + } +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/kommentar/KommentarsExportData.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/kommentar/KommentarsExportData.java new file mode 100644 index 0000000000000000000000000000000000000000..a550d397e705d277af24be94fa742681a792997f --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/kommentar/KommentarsExportData.java @@ -0,0 +1,22 @@ +package de.ozgcloud.alfa.kommentar; + +import java.util.List; + +import de.ozgcloud.alfa.common.file.OzgFile; +import de.xoev.xdomea.DokumentType; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Singular; + +@Builder +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@Getter +public class KommentarsExportData { + + @Singular + private List<DokumentType> dokumentTypes; + @Singular + private List<OzgFile> attachments; +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/postfach/DokumentTypeBuilder.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/postfach/DokumentTypeBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..1a82477373682b64b4581952fb28345ac655937c --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/postfach/DokumentTypeBuilder.java @@ -0,0 +1,93 @@ +package de.ozgcloud.alfa.postfach; + +import java.time.ZonedDateTime; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import de.ozgcloud.alfa.common.AnlageDokumentTypeBuilder; +import de.ozgcloud.alfa.common.DateConverter; +import de.ozgcloud.alfa.common.IdentifikationObjektTypeBuilder; +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.user.UserProfile; +import de.ozgcloud.alfa.postfach.PostfachMail.Direction; +import de.xoev.xdomea.AnlageDokumentType; +import de.xoev.xdomea.DokumentType; +import de.xoev.xdomea.HistorienProtokollInformationType; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +class DokumentTypeBuilder { + private static final String TYP = "Nachricht"; + private static final String ANTRAGSTELLER = "Antragsteller"; + private final Map<Direction, String> mapDirectionToString = Map.of( + Direction.IN, "Nachricht empfangen", + Direction.OUT, "Nachricht gesendet"); + + private PostfachMail postfachMail; + private List<OzgFile> ozgFileAttachments; + private UserProfile userProfile; + private String organisationseinheitenId; + + public static DokumentTypeBuilder builder() { + return new DokumentTypeBuilder(); + } + + public DokumentTypeBuilder withPostfachMail(PostfachMail postfachMail) { + this.postfachMail = postfachMail; + return this; + } + + public DokumentTypeBuilder withOzgFiles(List<OzgFile> ozgFiles) { + this.ozgFileAttachments = ozgFiles; + return this; + } + + public DokumentTypeBuilder withUserProfile(UserProfile userProfile) { + this.userProfile = userProfile; + return this; + } + + public DokumentTypeBuilder withOrganisationseinheitenId(String organisationseinheitenId) { + this.organisationseinheitenId = organisationseinheitenId; + return this; + } + + public DokumentType build() { + var dokumentType = new DokumentType(); + dokumentType.setIdentifikation(IdentifikationObjektTypeBuilder.builder() + .withObjectID(postfachMail.getId()) + .build()); + dokumentType.setTyp(TYP); + dokumentType.getHistorienProtokollInformation().add(createHistorienProtokollInformation()); + Optional.ofNullable(ozgFileAttachments).orElseGet(Collections::emptyList).stream().map(this::createAnlage) + .forEach(dokumentType.getAnlage()::add); + return dokumentType; + } + + AnlageDokumentType createAnlage(OzgFile ozgFile) { + return AnlageDokumentTypeBuilder.builder().withOzgFile(ozgFile).build(); + } + + HistorienProtokollInformationType createHistorienProtokollInformation() { + var historienInformation = new HistorienProtokollInformationType(); + historienInformation.setMetadatumName(postfachMail.getMailBody()); + historienInformation.setAkteur(getAkteur()); + historienInformation.setDatumUhrzeit(DateConverter.toXmlGregorianCalendar(getSentTime())); + historienInformation.setAktion(mapDirectionToString.get(postfachMail.getDirection())); + return historienInformation; + } + + String getAkteur() { + return Optional.ofNullable(userProfile) + .map(user -> user.getFullName() + "; " + organisationseinheitenId) + .orElse(ANTRAGSTELLER); + } + + ZonedDateTime getSentTime() { + return postfachMail.getDirection() == Direction.IN ? postfachMail.getCreatedAt() : postfachMail.getSentAt(); + } + +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/postfach/ExportNachrichtService.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/postfach/ExportNachrichtService.java new file mode 100644 index 0000000000000000000000000000000000000000..40dfc97e8ef03910763677008b0468fb2c5044fa --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/postfach/ExportNachrichtService.java @@ -0,0 +1,62 @@ +package de.ozgcloud.alfa.postfach; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; + +import org.springframework.stereotype.Service; + +import de.ozgcloud.alfa.common.binaryfile.BinaryFileService; +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.user.UserProfile; +import de.ozgcloud.alfa.common.user.UserService; +import de.ozgcloud.alfa.postfach.PostfachMailExportData.PostfachMailExportDataBuilder; +import de.ozgcloud.alfa.vorgang.VorgangWithEingang; +import de.xoev.xdomea.DokumentType; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class ExportNachrichtService { + private final PostfachMailService postfachMailService; + private final BinaryFileService binaryFileService; + private final UserService userService; + + public PostfachMailExportData createExportData(VorgangWithEingang vorgang) { + var builder = PostfachMailExportData.builder(); + getPostfachMails(vorgang.getId()) + .forEach(mail -> addPostfachMailExportData( + new PostfachMailExportInput(mail, getOrganisationseinheitenId(vorgang), getAttachments(mail)), builder)); + return builder.build(); + } + + public Stream<PostfachMail> getPostfachMails(String vorgangId) { + return postfachMailService.getAll(vorgangId); + } + + private String getOrganisationseinheitenId(VorgangWithEingang vorgang) { + return vorgang.getEingang().getZustaendigeStelle().getOrganisationseinheitenId(); + } + + List<OzgFile> getAttachments(PostfachMail postfachMail) { + return binaryFileService.getFiles(postfachMail.getAttachments()).toList(); + } + + void addPostfachMailExportData(PostfachMailExportInput postfachMailExportInput, PostfachMailExportDataBuilder builder) { + builder.attachments(postfachMailExportInput.attachments()); + builder.dokumentType(buildDokumentType(postfachMailExportInput)); + } + + DokumentType buildDokumentType(PostfachMailExportInput postfachMailExportInput) { + return DokumentTypeBuilder.builder() + .withPostfachMail(postfachMailExportInput.postfachMail()) + .withOzgFiles(postfachMailExportInput.attachments()) + .withUserProfile(getUserProfile(postfachMailExportInput.postfachMail()).orElse(null)) + .withOrganisationseinheitenId(postfachMailExportInput.organisationseinheitenId()) + .build(); + } + + Optional<UserProfile> getUserProfile(PostfachMail postfachMail) { + return Optional.ofNullable(postfachMail.getCreatedBy()).map(userService::getById); + } +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/postfach/PostfachMailExportData.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/postfach/PostfachMailExportData.java new file mode 100644 index 0000000000000000000000000000000000000000..7c359508b96cd8a6471be34307bd77b0044da3c7 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/postfach/PostfachMailExportData.java @@ -0,0 +1,23 @@ +package de.ozgcloud.alfa.postfach; + +import java.util.List; + +import de.ozgcloud.alfa.common.file.OzgFile; +import de.xoev.xdomea.DokumentType; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Singular; + +@Builder +@Getter +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class PostfachMailExportData { + + @Singular + private List<DokumentType> dokumentTypes; + @Singular + private List<OzgFile> attachments; + +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/postfach/PostfachMailExportInput.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/postfach/PostfachMailExportInput.java new file mode 100644 index 0000000000000000000000000000000000000000..07ce2b45857e032667efbbd9d0c75a1497c6f95e --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/postfach/PostfachMailExportInput.java @@ -0,0 +1,8 @@ +package de.ozgcloud.alfa.postfach; + +import java.util.List; + +import de.ozgcloud.alfa.common.file.OzgFile; + +record PostfachMailExportInput(PostfachMail postfachMail, String organisationseinheitenId, List<OzgFile> attachments) { +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/AnwendungsspezifischeErweiterungTypeCreator.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/AnwendungsspezifischeErweiterungTypeCreator.java new file mode 100644 index 0000000000000000000000000000000000000000..05b2f17709d3e4c2a8c26d1fbce3c7315a20b078 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/AnwendungsspezifischeErweiterungTypeCreator.java @@ -0,0 +1,27 @@ +package de.ozgcloud.alfa.vorgang; + +import java.util.Collections; + +import org.springframework.stereotype.Component; + +import de.xoev.xdomea.AnwendungsspezifischeErweiterungType; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Component +class AnwendungsspezifischeErweiterungTypeCreator { + + static final String KENNUNG = "IDOZGCloud1234567"; + static final String NAME = "Anwendungsspezifische Erweiterung OZGCloud Basis"; + + private final FeldGruppeTypeCreator feldGruppeTypeCreator; + + public AnwendungsspezifischeErweiterungType create(VorgangWithEingang vorgang) { + var ozgcloudErweiterungType = new AnwendungsspezifischeErweiterungType(); + ozgcloudErweiterungType.setKennung(KENNUNG); + ozgcloudErweiterungType.setName(NAME); + ozgcloudErweiterungType.getFeldgruppe().addAll(Collections.singleton(feldGruppeTypeCreator.create(vorgang))); + return ozgcloudErweiterungType; + } + +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/AnwendungsspezifischeErweiterungXMLTypeCreator.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/AnwendungsspezifischeErweiterungXMLTypeCreator.java new file mode 100644 index 0000000000000000000000000000000000000000..2af8e7cd35c3b5eac78704fa035c3a9aece954e6 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/AnwendungsspezifischeErweiterungXMLTypeCreator.java @@ -0,0 +1,19 @@ +package de.ozgcloud.alfa.vorgang; + +import org.springframework.stereotype.Component; + +import de.xoev.xdomea.AnwendungsspezifischeErweiterungXMLType; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Component +public class AnwendungsspezifischeErweiterungXMLTypeCreator { + + private final FormDataMapper formDataMapper; + + public AnwendungsspezifischeErweiterungXMLType create(VorgangWithEingang vorgang) { + var erweiterungXmlType = new AnwendungsspezifischeErweiterungXMLType(); + erweiterungXmlType.getAny().add(formDataMapper.toAntragsdaten(vorgang)); + return erweiterungXmlType; + } +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/DatatypeMapper.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/DatatypeMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..9a740682a45f0793f2926172b98212060617c603 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/DatatypeMapper.java @@ -0,0 +1,44 @@ +package de.ozgcloud.alfa.vorgang; + +import static java.util.Objects.*; + +import java.time.LocalDate; +import java.time.ZonedDateTime; +import java.util.Collection; + +import org.springframework.stereotype.Component; + +import de.xoev.xdomea.DatatypeType; + +@Component +class DatatypeMapper { + + public DatatypeType from(Object object) { + if (isNull(object)) { + return DatatypeType.STRING; + } + var objectClass = object.getClass(); + if (String.class.equals(objectClass)) { + return DatatypeType.STRING; + } + if (Integer.class.equals(objectClass)) { + return DatatypeType.INTEGER; + } + if (Boolean.class.equals(objectClass)) { + return DatatypeType.BOOLEAN; + } + if (LocalDate.class.equals(objectClass)) { + return DatatypeType.DATE; + } + if (ZonedDateTime.class.equals(objectClass)) { + return DatatypeType.DATETIME; + } + if (Float.class.equals(objectClass)) { + return DatatypeType.FLOAT; + } + if (object instanceof Collection<?> collection && !collection.isEmpty()) { + return from(collection.iterator().next()); + } + return DatatypeType.STRING; + } +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/ExportFelder.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/ExportFelder.java new file mode 100644 index 0000000000000000000000000000000000000000..46db0e389e308eba98b8a9e9664306c1c972016b --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/ExportFelder.java @@ -0,0 +1,61 @@ +package de.ozgcloud.alfa.vorgang; + +import de.ozgcloud.alfa.common.DatentypCode; +import de.xoev.xdomea.DatentypCodeType; +import de.xoev.xdomea.FeldType; + +enum ExportFelder { + LEIKA_ID("LeikaID", "ID einer Leistung aus dem OZG-Leistungskatalog", DatentypCode.STRING.getCode()), + DATUM_ANTRAGSEINGANG("DatumAntragseingang", "Das Datum des Antragseingangs", DatentypCode.DATE.getCode()), + NAME("Name", null, DatentypCode.STRING.getCode()), + VORNAME("Vorname", null, DatentypCode.STRING.getCode()), + GEBURTSDATUM("Geburtsdatum", null, DatentypCode.DATE.getCode()), + PLZ("PLZAntragsteller", null, DatentypCode.STRING.getCode()); + + private static final String LIST_URI = "urn:xoev-de:xdomea:codeliste:datentyp"; + private static final String LIST_VERSION_ID = "1.1"; + + private String name; + private String beschreibung; + private String datentypCode; + + ExportFelder(String name, String beschreibung, String datentypCode) { + this.name = name; + this.beschreibung = beschreibung; + this.datentypCode = datentypCode; + } + + public String getName() { + return name; + } + + public String getBeschreibung() { + return beschreibung; + } + + public String getDatentypCode() { + return datentypCode; + } + + public FeldType createFeld(String wert) { + var feld = createFeld(); + feld.setWert(wert); + return feld; + } + + public FeldType createFeld() { + var feld = new FeldType(); + feld.setName(name); + feld.setBeschreibung(beschreibung); + feld.setDatentyp(fromCode(datentypCode)); + return feld; + } + + private DatentypCodeType fromCode(String code) { + var type = new DatentypCodeType(); + type.setCode(code); + type.setListURI(LIST_URI); + type.setListVersionID(LIST_VERSION_ID); + return type; + } +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/ExportVorgangService.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/ExportVorgangService.java new file mode 100644 index 0000000000000000000000000000000000000000..49ae46dc6950161c2121bb7fc395a07cf96317ae --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/ExportVorgangService.java @@ -0,0 +1,55 @@ +package de.ozgcloud.alfa.vorgang; + +import java.util.Optional; +import java.util.UUID; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import de.xoev.xdomea.AkteType; +import de.xoev.xdomea.AllgemeineMetadatenType; +import de.xoev.xdomea.IdentifikationObjektType; +import de.xoev.xdomea.NkAbgabeType; +import de.xoev.xdomea.VorgangType; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Service +public class ExportVorgangService { + + private final VorgangService vorgangService; + + private final VorgangTypeCreator vorgangTypeCreator; + private final KopfCreator kopfCreator; + + public VorgangWithEingang getVorgang(String vorgangId) { + return vorgangService.findVorgangWithEingang(vorgangId); + } + + public VorgangType createVorgangType(VorgangWithEingang vorgangWithEingang) { + return vorgangTypeCreator.create(vorgangWithEingang); + } + + public NkAbgabeType createKopf(VorgangWithEingang vorgangWithEingang) { + return kopfCreator.createKopf(vorgangWithEingang); + } + + public AkteType createAkteType(VorgangWithEingang vorgangWithEingang) { + var akteType = new AkteType(); + akteType.setIdentifikation(createIdentifikationObjektType()); + akteType.setAllgemeineMetadaten(createAllgemeineMetadatenType(vorgangWithEingang)); + return akteType; + } + + IdentifikationObjektType createIdentifikationObjektType() { + var identifikationObjektType = new IdentifikationObjektType(); + identifikationObjektType.setID(UUID.randomUUID().toString()); + return identifikationObjektType; + } + + AllgemeineMetadatenType createAllgemeineMetadatenType(VorgangWithEingang vorgangWithEingang) { + var allgemeineMetadatenType = new AllgemeineMetadatenType(); + allgemeineMetadatenType.setKennzeichen(Optional.ofNullable(vorgangWithEingang.getAktenzeichen()).orElse(StringUtils.EMPTY)); + return allgemeineMetadatenType; + } +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/FeldGruppeTypeCreator.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/FeldGruppeTypeCreator.java new file mode 100644 index 0000000000000000000000000000000000000000..6b22705890f313c97caae1fad6692ea7405dd208 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/FeldGruppeTypeCreator.java @@ -0,0 +1,39 @@ +package de.ozgcloud.alfa.vorgang; + +import static java.util.Optional.*; + +import java.time.format.DateTimeFormatter; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import de.xoev.xdomea.FeldType; +import de.xoev.xdomea.FeldgruppeType; + +@Component +class FeldGruppeTypeCreator { + + static final String NAME = "FeldgruppeOZGCloudBasis"; + static final String BESCHREIBUNG = "Feldgruppe für OZGCloud Basis"; + + public FeldgruppeType create(VorgangWithEingang vorgang) { + var feldgruppe = new FeldgruppeType(); + feldgruppe.setName(NAME); + feldgruppe.setBeschreibung(BESCHREIBUNG); + feldgruppe.getFeld().addAll(createFeldType(vorgang)); + return feldgruppe; + } + + List<FeldType> createFeldType(VorgangWithEingang vorgang) { + var antragsteller = ofNullable(vorgang.getEingang()).flatMap(eingang -> ofNullable(eingang.getAntragsteller())); + return List.of( + ExportFelder.LEIKA_ID.createFeld(), + ExportFelder.DATUM_ANTRAGSEINGANG.createFeld(DateTimeFormatter.ISO_DATE_TIME.format(vorgang.getCreatedAt())), + ExportFelder.NAME.createFeld(antragsteller.flatMap(a -> ofNullable(a.getNachname())).orElse(StringUtils.EMPTY)), + ExportFelder.VORNAME.createFeld(antragsteller.flatMap(a -> ofNullable(a.getVorname())).orElse(StringUtils.EMPTY)), + ExportFelder.GEBURTSDATUM.createFeld(antragsteller.flatMap(a -> ofNullable(a.getGeburtsdatum())).orElse(StringUtils.EMPTY)), + ExportFelder.PLZ.createFeld(antragsteller.flatMap(a -> ofNullable(a.getPlz())).orElse(StringUtils.EMPTY))); + } + +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/FormDataMapper.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/FormDataMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..b5b8a45e9e650bc8e193de707b082ec057e8758f --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/FormDataMapper.java @@ -0,0 +1,101 @@ +package de.ozgcloud.alfa.vorgang; + +import static java.util.Objects.*; + +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.springframework.stereotype.Component; + +import de.ozgcloud.alfa.common.DateConverter; +import de.xoev.xdomea.Antragsdaten; +import de.xoev.xdomea.AntragsdatenGroupType; +import de.xoev.xdomea.AntragsdatenItemType; +import de.xoev.xdomea.AntragsdatenMultiValueFieldType; +import de.xoev.xdomea.AntragsdatenSingleValueFieldType; +import de.xoev.xdomea.DatatypeType; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Component +class FormDataMapper { + + private final DatatypeMapper datatypeMapper; + + public Antragsdaten toAntragsdaten(VorgangWithEingang vorgang) { + var antragsdaten = new Antragsdaten(); + antragsdaten.getItem().addAll(mapFormData(vorgang)); + antragsdaten.getItem().addAll(mapOtherData(vorgang)); + return antragsdaten; + } + + List<AntragsdatenItemType> mapFormData(VorgangWithEingang vorgang) { + return Optional.ofNullable(vorgang.getEingang()).map(Eingang::getFormData).map(this::mapData).orElse(List.of()); + } + + List<AntragsdatenItemType> mapOtherData(VorgangWithEingang vorgang) { + return Optional.ofNullable(vorgang.getEingang()).map(Eingang::getAntragsteller).map(Antragsteller::getOtherData).map(this::mapData) + .orElse(List.of()); + } + + List<AntragsdatenItemType> mapData(Map<String, Object> data) { + return buildItems(WrappedValueExtractor.extractWrappedValues(data)); + } + + List<AntragsdatenItemType> buildItems(Map<?, ?> formData) { + var items = new ArrayList<AntragsdatenItemType>(); + for (var formDataEntry : formData.entrySet()) { + var key = (String) formDataEntry.getKey(); + var value = formDataEntry.getValue(); + if (value instanceof Map<?, ?> map) { + items.add(buildAntragsdatenGroup(key, map)); + } else if (value instanceof Collection<?> collection) { + items.add(buildMultiValueField(key, collection)); + } else { + items.add(buildSingleValueField(key, value)); + + } + } + return items; + } + + AntragsdatenItemType buildAntragsdatenGroup(String name, Map<?, ?> values) { + var antragsGroup = new AntragsdatenGroupType(); + antragsGroup.setName(name); + antragsGroup.getItem().addAll(buildItems(values)); + return antragsGroup; + } + + AntragsdatenItemType buildMultiValueField(String name, Collection<?> values) { + var multiValue = new AntragsdatenMultiValueFieldType(); + multiValue.setName(name); + var datatype = datatypeMapper.from(values); + multiValue.setType(datatype); + var multiValueList = multiValue.getValue(); + values.stream().map(v -> formatValue(datatype, v)).forEach(multiValueList::add); + return multiValue; + } + + AntragsdatenItemType buildSingleValueField(String name, Object value) { + var singleValue = new AntragsdatenSingleValueFieldType(); + singleValue.setName(name); + if (nonNull(value)) { + var datatype = datatypeMapper.from(value); + singleValue.setType(datatype); + singleValue.setValue(formatValue(datatype, value)); + } + return singleValue; + } + + Object formatValue(DatatypeType datatype, Object value) { + return switch (datatype) { + case STRING -> String.valueOf(value); + case DATETIME -> DateConverter.toXmlGregorianCalendar((ZonedDateTime) value); + default -> value; + }; + } +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/KontaktTypeCreator.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/KontaktTypeCreator.java new file mode 100644 index 0000000000000000000000000000000000000000..8ca2aced5adb1a651b78c066c088395449b3fbd8 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/KontaktTypeCreator.java @@ -0,0 +1,58 @@ +package de.ozgcloud.alfa.vorgang; + +import java.util.Optional; +import java.util.function.Predicate; + +import javax.xml.datatype.XMLGregorianCalendar; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import de.ozgcloud.alfa.common.DateConverter; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.xoev.xdomea.GeburtType; +import de.xoev.xdomea.KontaktType; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Component +class KontaktTypeCreator { + + private static final Predicate<Antragsteller> HAS_VORNAME = antragsteller -> StringUtils.isNotBlank(antragsteller.getVorname()); + private static final Predicate<Antragsteller> HAS_NACHNAME = antragsteller -> StringUtils.isNotBlank(antragsteller.getNachname()); + private static final Predicate<Antragsteller> HAS_ANREDE = antragsteller -> StringUtils.isNotBlank(antragsteller.getAnrede()); + private static final Predicate<Antragsteller> HAS_GEBURTSDATUM = antragsteller -> geburtsdatumToISO(antragsteller).isPresent(); + + private final NameNatuerlichePersonTypeCreator nameNatuerlichePersonTypeCreator; + + public Optional<KontaktType> create(VorgangWithEingang vorgang) { + return getAntragstellerIfHasRequiredData(vorgang).map(this::toKontaktType); + } + + Optional<Antragsteller> getAntragstellerIfHasRequiredData(VorgangWithEingang vorgang) { + return Optional.ofNullable(vorgang.getEingang().getAntragsteller()) + .filter(HAS_VORNAME.or(HAS_NACHNAME).or(HAS_ANREDE).or(HAS_GEBURTSDATUM)); + } + + KontaktType toKontaktType(Antragsteller antragsteller) { + var kontakt = new KontaktType(); + kontakt.setName(nameNatuerlichePersonTypeCreator.create(antragsteller)); + + geburtsdatumToISO(antragsteller) + .map(this::createGeburtType) + .ifPresent(kontakt::setGeburt); + + return kontakt; + } + + static Optional<XMLGregorianCalendar> geburtsdatumToISO(Antragsteller antragsteller) { + return DateConverter.convertGermanFormatToISO(antragsteller.getGeburtsdatum()); + } + + GeburtType createGeburtType(XMLGregorianCalendar geburtsdatumIso) { + var geburtType = new GeburtType(); + geburtType.setDatum(geburtsdatumIso); + return geburtType; + } + +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/KopfCreator.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/KopfCreator.java new file mode 100644 index 0000000000000000000000000000000000000000..5305519177c60d83ac4de118977b4fbd4c549fa2 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/KopfCreator.java @@ -0,0 +1,93 @@ +package de.ozgcloud.alfa.vorgang; + +import java.time.ZoneOffset; +import java.time.ZonedDateTime; + +import org.springframework.stereotype.Component; + +import de.ozgcloud.alfa.common.DateConverter; +import de.ozgcloud.alfa.common.UUIDConverter; +import de.ozgcloud.alfa.export.XdomeaProperties; +import de.xoev.xdomea.BehoerdenkennungType; +import de.xoev.xdomea.Code; +import de.xoev.xdomea.KontaktType; +import de.xoev.xdomea.NachrichtentypCodeType; +import de.xoev.xdomea.NkAbgabeType; +import de.xoev.xdomea.OrganisationseinheitType; +import de.xoev.xdomea.SystemType; +import io.micrometer.common.util.StringUtils; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Component +class KopfCreator { + + static final String NACHRICHTENTYP_CODE_TYPE_LIST_URI = "urn:xoev-de:xdomea:codeliste:nachrichtentyp"; + static final String NACHRICHTENTYP_CODE_TYPE_LIST_VERSION_ID = "2.0"; + static final String NACHRICHTENTYP_ABGABE_ABGABE_TYPE_CODE = "0401"; + static final String PRODUKT_NAME = "OZG-Cloud"; + + private final XdomeaProperties xdomeaProperties; + + public NkAbgabeType createKopf(VorgangWithEingang vorgang) { + var nkAbgabeType = new NkAbgabeType(); + nkAbgabeType.setProzessID(UUIDConverter.fromObjectId(vorgang.getId())); + nkAbgabeType.setNachrichtentyp(createNachrichtentyp()); + nkAbgabeType.setErstellungszeitpunkt(DateConverter.toXmlGregorianCalendar(ZonedDateTime.now(ZoneOffset.UTC))); + nkAbgabeType.setAbsender(createAbsender(vorgang.getEingang().getZustaendigeStelle().getOrganisationseinheitenId())); + nkAbgabeType.setEmpfaenger(createKontaktType()); + nkAbgabeType.setSendendesSystem(createSendendesSystem()); + nkAbgabeType.setImportbestaetigung(true); + nkAbgabeType.setEmpfangsbestaetigung(true); + return nkAbgabeType; + } + + NachrichtentypCodeType createNachrichtentyp() { + var nachrichtentypCode = new NachrichtentypCodeType(); + nachrichtentypCode.setCode(NACHRICHTENTYP_ABGABE_ABGABE_TYPE_CODE); + nachrichtentypCode.setListURI(NACHRICHTENTYP_CODE_TYPE_LIST_URI); + nachrichtentypCode.setListVersionID(NACHRICHTENTYP_CODE_TYPE_LIST_VERSION_ID); + return nachrichtentypCode; + } + + KontaktType createAbsender(String organisationseinheitId) { + var absender = createKontaktType(); + absender.setOrganisationseinheit(createOrganisationseinheitType(organisationseinheitId)); + return absender; + } + + KontaktType createKontaktType() { + var kontakt = new KontaktType(); + if (StringUtils.isNotBlank(xdomeaProperties.getBehoerdenschluessel())) { + kontakt.setBehoerdenkennung(createBehoerdenkennung()); + } + return kontakt; + } + + OrganisationseinheitType createOrganisationseinheitType(String organisationseinheitId) { + var organisationseinheit = new OrganisationseinheitType(); + organisationseinheit.setName(organisationseinheitId); + return organisationseinheit; + } + + BehoerdenkennungType createBehoerdenkennung() { + var behoerdenkennungType = new BehoerdenkennungType(); + behoerdenkennungType.setBehoerdenschluessel(createBehoerdenschluessel()); + return behoerdenkennungType; + } + + Code createBehoerdenschluessel() { + var behoerdenschluessel = new Code(); + behoerdenschluessel.setCode(xdomeaProperties.getBehoerdenschluessel()); + behoerdenschluessel.setListURI(xdomeaProperties.getBehoerdenschluesselUri()); + behoerdenschluessel.setListVersionID(xdomeaProperties.getBehoerdenschluesselVersion()); + return behoerdenschluessel; + } + + SystemType createSendendesSystem() { + var sendendesSystem = new SystemType(); + sendendesSystem.setProduktname(PRODUKT_NAME); + return sendendesSystem; + } + +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/NameNatuerlichePersonTypeCreator.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/NameNatuerlichePersonTypeCreator.java new file mode 100644 index 0000000000000000000000000000000000000000..3f4431f47450482dd6c2543460f19219f3d1d5c5 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/NameNatuerlichePersonTypeCreator.java @@ -0,0 +1,29 @@ +package de.ozgcloud.alfa.vorgang; + +import static java.util.Optional.*; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import de.xoev.xdomea.AllgemeinerNameType; +import de.xoev.xdomea.NameNatuerlichePersonType; + +@Component +class NameNatuerlichePersonTypeCreator { + + public NameNatuerlichePersonType create(Antragsteller antragsteller) { + var nameNatuerlichPerson = new NameNatuerlichePersonType(); + nameNatuerlichPerson.setAnrede(ofNullable(antragsteller).map(Antragsteller::getAnrede).orElse(StringUtils.EMPTY)); + nameNatuerlichPerson.setVorname( + createAllgemeinerNameType(ofNullable(antragsteller).map(Antragsteller::getVorname).orElse(StringUtils.EMPTY))); + nameNatuerlichPerson.setFamilienname( + createAllgemeinerNameType(ofNullable(antragsteller).map(Antragsteller::getNachname).orElse(StringUtils.EMPTY))); + return nameNatuerlichPerson; + } + + private AllgemeinerNameType createAllgemeinerNameType(String name) { + var allgemeinerName = new AllgemeinerNameType(); + allgemeinerName.setName(name); + return allgemeinerName; + } +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/VorgangTypeCreator.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/VorgangTypeCreator.java new file mode 100644 index 0000000000000000000000000000000000000000..11b5a0502926d5b23aa29665cd47b64cf93c5c37 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/VorgangTypeCreator.java @@ -0,0 +1,57 @@ +package de.ozgcloud.alfa.vorgang; + +import java.util.UUID; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import de.xoev.xdomea.AllgemeineMetadatenType; +import de.xoev.xdomea.IdentifikationObjektType; +import de.xoev.xdomea.MediumCodeType; +import de.xoev.xdomea.VorgangType; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Component +class VorgangTypeCreator { + + static final Long NUMMER_IM_UEBERGEORDNETEN_CONTAINER = 1L; + static final String ALLGEMEINE_METADATEN_MEDIUM_CODE = "001"; + + private final AnwendungsspezifischeErweiterungTypeCreator anwendungsspezifischeErweiterungTypeCreator; + private final AnwendungsspezifischeErweiterungXMLTypeCreator anwendungsspezifischeErweiterungXMLTypeCreator; + private final KontaktTypeCreator kontaktTypeCreator; + + public VorgangType create(VorgangWithEingang vorgangWithEingang) { + var vorgang = new VorgangType(); + vorgang.setAnwendungsspezifischeErweiterung(anwendungsspezifischeErweiterungTypeCreator.create(vorgangWithEingang)); + vorgang.setAnwendungsspezifischeErweiterungXML(anwendungsspezifischeErweiterungXMLTypeCreator.create(vorgangWithEingang)); + vorgang.setIdentifikation(createIdentifikation()); + vorgang.setAllgemeineMetadaten(createAllgemeineMetadaten(vorgangWithEingang)); + kontaktTypeCreator.create(vorgangWithEingang).ifPresent(vorgang.getKontakt()::add); + return vorgang; + } + + IdentifikationObjektType createIdentifikation() { + var identifikation = new IdentifikationObjektType(); + identifikation.setID(UUID.randomUUID().toString()); + identifikation.setNummerImUebergeordnetenContainer(NUMMER_IM_UEBERGEORDNETEN_CONTAINER); + return identifikation; + } + + AllgemeineMetadatenType createAllgemeineMetadaten(VorgangWithEingang vorgang) { + var allgemeineMetadaten = new AllgemeineMetadatenType(); + allgemeineMetadaten.setBetreff(vorgang.getName()); + allgemeineMetadaten.setKennzeichen(vorgang.getNummer()); + allgemeineMetadaten.setBemerkung(StringUtils.EMPTY); + allgemeineMetadaten.setMedium(createMediumCode()); + return allgemeineMetadaten; + } + + private MediumCodeType createMediumCode() { + var mediumCode = new MediumCodeType(); + mediumCode.setCode(ALLGEMEINE_METADATEN_MEDIUM_CODE); + return mediumCode; + } + +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/WrappedValueExtractor.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/WrappedValueExtractor.java new file mode 100644 index 0000000000000000000000000000000000000000..12a2d36bc271932aa84defc5e7d43a0bfa2bafd9 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/WrappedValueExtractor.java @@ -0,0 +1,36 @@ +package de.ozgcloud.alfa.vorgang; + +import java.util.HashMap; +import java.util.Map; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +class WrappedValueExtractor { + + static final String WRAPPER_KEY = "value"; + + public static Map<String, Object> extractWrappedValues(Map<String, Object> formData) { + Map<String, Object> result = new HashMap<>(); + for (var entry : formData.entrySet()) { + result.put(entry.getKey(), replaceWrappedValueWithDirectValue(entry.getValue())); + } + return result; + } + + @SuppressWarnings("unchecked") + static Object replaceWrappedValueWithDirectValue(Object value) { + if (!(value instanceof Map)) { + return value; + } + Map<String, Object> formData = (Map<String, Object>) value; + return isWrappedValue(formData) ? + replaceWrappedValueWithDirectValue(formData.get(WRAPPER_KEY)) : + extractWrappedValues(formData); + } + + static boolean isWrappedValue(Map<String, Object> formData) { + return formData.containsKey(WRAPPER_KEY) && formData.size() == 1; + } +} diff --git a/alfa-xdomea/src/main/resources/ozgcloud_XML-Schemata/ozgcloud.xsd b/alfa-xdomea/src/main/resources/ozgcloud_XML-Schemata/ozgcloud.xsd new file mode 100644 index 0000000000000000000000000000000000000000..16daa7f5862da6b2b0e36a69b2f6d30969f555b9 --- /dev/null +++ b/alfa-xdomea/src/main/resources/ozgcloud_XML-Schemata/ozgcloud.xsd @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema targetNamespace="urn:ozgcloud-de:xdomea:schema:1.0.0" + xmlns:ozgcloud="urn:ozgcloud-de:xdomea:schema:1.0.0" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xdomea="urn:xoev-de:xdomea:schema:3.0.0" + elementFormDefault="qualified"> + + <xs:import namespace="urn:xoev-de:xdomea:schema:3.0.0" schemaLocation="../xdomea_3-0-0_XML-Schemata/xdomea.xsd"/> + + <xs:element name="Antragsdaten"> + <xs:complexType> + <xs:sequence> + <xs:element name="Item" type="ozgcloud:AntragsdatenItemType" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> + + <xs:complexType name="AntragsdatenItemType" abstract="true"> + <xs:attribute name="name" type="xs:string" use="required"/> + </xs:complexType> + + <xs:complexType name="AntragsdatenFieldType" abstract="true"> + <xs:complexContent> + <xs:extension base="ozgcloud:AntragsdatenItemType"> + <xs:attribute name="type" type="ozgcloud:DatatypeType" default="string"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + + <xs:complexType name="AntragsdatenSingleValueFieldType"> + <xs:complexContent> + <xs:extension base="ozgcloud:AntragsdatenFieldType"> + <xs:all> + <xs:element name="Value" type="xs:anyType"/> + </xs:all> + </xs:extension> + </xs:complexContent> + </xs:complexType> + + <xs:complexType name="AntragsdatenMultiValueFieldType"> + <xs:complexContent> + <xs:extension base="ozgcloud:AntragsdatenFieldType"> + <xs:sequence> + <xs:element name="Value" type="xs:anyType" maxOccurs="unbounded"/> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + + <xs:complexType name="AntragsdatenGroupType"> + <xs:complexContent> + <xs:extension base="ozgcloud:AntragsdatenItemType"> + <xs:sequence> + <xs:element name="Item" type="ozgcloud:AntragsdatenItemType" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + + <xs:simpleType name="DatatypeType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="string"/> + <xs:enumeration value="date"/> + <xs:enumeration value="datetime"/> + <xs:enumeration value="integer"/> + <xs:enumeration value="float"/> + <xs:enumeration value="boolean"/> + </xs:restriction> + </xs:simpleType> +</xs:schema> \ No newline at end of file diff --git a/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Baukasten.xsd b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Baukasten.xsd new file mode 100644 index 0000000000000000000000000000000000000000..97b358a114505f27f22593e524a5c21d5ba8136c --- /dev/null +++ b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Baukasten.xsd @@ -0,0 +1,1818 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xdomea="urn:xoev-de:xdomea:schema:3.0.0" + xmlns:xoev-code="http://xoev.de/schemata/code/1_0" + targetNamespace="urn:xoev-de:xdomea:schema:3.0.0" + version="3.0.0" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> + <xs:annotation> + <xs:appinfo> + <standard> + <nameLang>xdomea - XÖV-Standard für den IT-gestützten Austausch und die IT-gestützte Aussonderung behördlichen Schriftgutes</nameLang> + <nameKurz>xdomea</nameKurz> + <nameTechnisch>xdomea</nameTechnisch> + <kennung>urn:xoev-de:xdomea:kosit:standard:xdomea</kennung> + <beschreibung>xdomea ist der vom IT-Planungsrat verabschiedete verbindliche Standard für den Austausch von Akten, Vorgängen und Dokumenten im Kontext der Übermittlung, der Abgabe sowie der Aussonderung von Schriftgutobjekten (www.it-planungsrat.de, Beschluss 2017/39). Weiterhin kann xdomea für den Austausch zwischen Fachverfahren und DMS/VBS sowie für die Zwischenarchivierung genutzt werden. + +Um diese Anwendungsszenarien bestmöglich zu unterstützen, ist xdomea gemäß des XÖV-Rahmenwerkes nach dem Baukastenprinzip aufgebaut und bietet einzelne Nachrichten(gruppen) für die jeweiligen Prozesse an. + +Der Standard xdomea wird von der gleichnamigen Arbeitsgruppe des IT-Planungsrates weiterentwickelt und gepflegt. Der Betrieb des Standards erfolgt durch die Koordinierungsstelle für IT-Standards (KoSIT). +</beschreibung> + </standard> + <versionStandard> + <version>3.0.0</version> + <beschreibung>Die Version 3.0.0 ist durch den IT-Planungsrat beschlossen. Details zum Beschluss sowie zu den Fristen der Umsetzung sind der Veröffentlichung im Bundesanzeiger unter www.bundesanzeiger.de zu entnehmen.</beschreibung> + <versionXOEVProfil>1.7.2</versionXOEVProfil> + <versionXOEVHandbuch>2.3.1</versionXOEVHandbuch> + <versionXGenerator>3.0.1</versionXGenerator> + <versionModellierungswerkzeug>19.0</versionModellierungswerkzeug> + <nameModellierungswerkzeug>MagicDraw</nameModellierungswerkzeug> + </versionStandard> + </xs:appinfo> + <xs:documentation>Der Baukasten beinhaltet alle spezifischen Komponenten, die entweder aus XÖV-Kernkomponenten abgeleitet sind oder für xdomea erstellt wurden.</xs:documentation> + </xs:annotation> + <xs:include schemaLocation="xdomea-Datentypen.xsd"/> + <xs:import schemaLocation="http://xoev.de/schemata/code/1_0/xoev-code.xsd" + namespace="http://xoev.de/schemata/code/1_0"/> + <xs:complexType name="AkteType"> + <xs:annotation> + <xs:appinfo> + <title>Akte</title> + </xs:appinfo> + <xs:documentation>Akte enthält die Metadatenfelder für den Austausch von Akten einschließlich der archivspezifischen Metadaten, anwendungsspezifischer Metadaten, Historien- und Protokollinformationen sowie Informationen zum internen Geschäftsgang. Die absendende Behörde kann festlegen, welche Informationen dem Empfänger mit der Übertragung zur Verfügung gestellt werden sollen. So kann auch der Anforderung nach einer ggf. erforderlichen Beschränkung der übertragenen Metadaten Rechnung getragen werden (z.B. auf Grund datenschutzrechtlicher oder sonstiger gesetzlicher Bestimmungen).</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Identifikation" type="xdomea:IdentifikationObjektType"> + <xs:annotation> + <xs:documentation>Über Identifikation werden zur systemübergreifend eindeutigen Identifizierung der Akte spezifische Merkmale übergeben.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="AllgemeineMetadaten" + minOccurs="0" + type="xdomea:AllgemeineMetadatenType"> + <xs:annotation> + <xs:documentation>Über AllgemeineMetadaten werden allgemeine Metadaten zu einer Akte angegeben.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="ArchivspezifischeMetadaten" + minOccurs="0" + type="xdomea:MetadatenAussonderungType"> + <xs:annotation> + <xs:documentation>Über ArchivspezifischeMetadaten werden die für die Archivierung und Aussonderung relevanten Metadaten zu einer Akte angegeben.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Standort" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Aufbewahrungsort der Akte.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Typ" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die weitere Spezifikation der Akte, um u. a. Recherche durchzuführen oder um zusätzliche Metadaten festzulegen. Beispiele sind Bauakte oder auch Personalakte.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Laufzeit" minOccurs="0" type="xdomea:ZeitraumType"> + <xs:annotation> + <xs:documentation>Die Laufzeit der Akte, d.h. Zeitpunkt des Beginns und des Endes.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="HistorienProtokollInformation" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:HistorienProtokollInformationType"> + <xs:annotation> + <xs:documentation>Über HistorienProtokollInformation werden die zur Historisierung und Protokollierung relevanten Metadaten zu einer Akte angegeben, in der die Veränderungen an den beschreibenden Attributen und dem Zustand der Akte erfasst werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="InternerGeschaeftsgang" + minOccurs="0" + type="xdomea:GeschaeftsgangType"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Der interne Geschäftsgang kann nach organisatorischer Absprache zwischen den austauschenden Systemen genutzt werden, ist aber nicht verpflichtender Bestandteil von xdomea.</implementationHint> + </xs:appinfo> + <xs:documentation>Über InternerGeschaeftsgang wird der Akte zum Nachweis des internen Geschäftsgangs eine spezifische Ausprägung eines Geschäftsgangs zugeordnet.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Akteninhalt" minOccurs="0"> + <xs:annotation> + <xs:documentation>Die Sachverhalte in der Akte sind inhaltlich mittels üblicher Akteninhalte wie z.B. Vorgänge abgegrenzt.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Dokument" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:DokumentType"> + <xs:annotation> + <xs:documentation>Ein Dokument, das hierarchisch in die Akte eingebunden bzw. der Akte untergeordnet ist.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Vorgang" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:VorgangType"> + <xs:annotation> + <xs:documentation>Ein Vorgang, der hierarchisch in die Akte eingebunden bzw. der Akte untergeordnet ist.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Teilakte" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:AkteType"> + <xs:annotation> + <xs:documentation>Über diese Eigenschaft wird eine Teilakte hierarchisch in eine Akte eingebunden bzw. einer Akte untergeordnet.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Verweis" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:VerweisType"> + <xs:annotation> + <xs:documentation>Über einen Verweis wird eine inhaltliche Querbeziehung der Akte zu einem anderen Schriftgutobjekt dargestellt.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Kontakt" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:KontaktType"> + <xs:annotation> + <xs:documentation>Eine Kontaktinformation zu einem Geschäftsprozessbeteiligten.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="ZdA" minOccurs="0" type="xs:boolean"> + <xs:annotation> + <xs:appinfo> + <implementationHint>ZdA (zu den Akten) steht für das Schließen eines Schriftgutobjekts (Teilvorgang, Vorgang, Teilakte oder Akte). Die hierfür in den Verwaltungen genutzten Bezeichnungen können anders lauten (z.B. „Schließen der Akte oder des Vorgangs“).</implementationHint> + </xs:appinfo> + <xs:documentation>ZdA kennzeichnet, ob die Akte zu den Akten verfügt wurde (Wert 1) oder nicht (Wert 0).</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="ZdADatum" minOccurs="0" type="xs:date"> + <xs:annotation> + <xs:appinfo> + <implementationHint>ZdA (zu den Akten) steht für das Schließen eines Schriftgutobjekts (Teilvorgang, Vorgang, Teilakte oder Akte). Die hierfür in den Verwaltungen genutzten Bezeichnungen können anders lauten (z.B. „Schließen der Akte oder des Vorgangs“).</implementationHint> + </xs:appinfo> + <xs:documentation>ZdADatum kennzeichnet, wann der Vorgang zu den Akten verfügt wurde.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="AnwendungsspezifischeErweiterung" + minOccurs="0" + type="xdomea:AnwendungsspezifischeErweiterungType"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Die Speicherung der nicht-auflösbaren Daten beim Empfang erfolgt in einer XML-Datei zum Schriftgutobjekt im empfangenden System. Die Umsetzung muss systemspezifisch gelöst werden - hierbei muss durch das System sichergestellt sein, dass die empfangenen Informationen nicht verloren gehen.</implementationHint> + </xs:appinfo> + <xs:documentation>AnwendungsspezifischeErweiterung darf nur dazu genutzt werden, weitere (z.B. fachspezifische) Metadaten zu spezifizieren, deren Übermittlung mit den bereits in xdomea spezifizierten Metadaten nicht möglich ist.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="AnwendungsspezifischeErweiterungXML" + minOccurs="0" + type="xdomea:AnwendungsspezifischeErweiterungXMLType"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Die Speicherung der nicht-auflösbaren Daten beim Empfang erfolgt in einer XML-Datei zum Schriftgutobjekt im empfangenden System. Die Umsetzung muss systemspezifisch gelöst werden - hierbei muss durch das System sichergestellt sein, dass die empfangenen Informationen nicht verloren gehen.</implementationHint> + </xs:appinfo> + <xs:documentation>AnwendungsspezifischeErweiterungXML darf nur dazu genutzt werden, weitere (z.B. fachspezifische) Metadaten zu spezifizieren, deren Übermittlung mit den bereits in xdomea spezifizierten Metadaten nicht möglich ist. Die AnwendungsspezifischeErweiterungXML bietet die Möglichkeit, mittels Einbindung externer XML-Schemata diese Metadaten zu spezifizieren. Es können beliebige XML-Schemata mit unterschiedlichen Namensräumen angegeben werden. Die XML-Schema-Validierung der weiterführenden Metadaten erfolgt innerhalb der xdomea-Nachricht selbst "lax".</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="AktenplanType"> + <xs:annotation> + <xs:appinfo> + <title>Aktenplan</title> + </xs:appinfo> + <xs:documentation>Der Aktenplan enthält ein aufgabenbezogenes mehrstufiges Ordnungssystem mit einer hierarchischen Gliederung für das Bilden und Kennzeichnen von Akten und Vorgängen sowie das Zuordnen von Dokumenten.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Bezeichnung" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Name des Aktenplans.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Typ" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Typ des Aktenplans, z.B. Teilaktenplan.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Version" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Version des Aktenplans.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Einheit" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:AktenplaneinheitAktenplanType"> + <xs:annotation> + <xs:documentation>Die Einheit eines Aktenplans, die Auskunft über die hierarchische Strukturierung eines Aktenplans gibt. Eine Aktenplanheit entspricht z.B. einer Hauptgruppe, Obergruppe, Gruppe, Untergruppe oder Betreffseinheit.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Gueltigkeit" minOccurs="0" type="xdomea:ZeitraumType"> + <xs:annotation> + <xs:documentation>Die Gültigkeit des Aktenplans mit Beginn und Ende.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Aktenplandatei" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:FormatType"> + <xs:annotation> + <xs:documentation>Die Datei zum Aktenplan als Primärdokument.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="AktenplaneinheitAktenplanType"> + <xs:annotation> + <xs:appinfo> + <title>AktenplaneinheitAktenplan</title> + </xs:appinfo> + <xs:documentation>Eine Aktenplaneinheit gibt Auskunft über die hierarchische Strukturierung eines Aktenplans. Eine Aktenplanheit entspricht z.B. einer Hauptgruppe, Obergruppe, Gruppe, Untergruppe oder Betreffseinheit.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:extension base="xdomea:AktenplaneinheitType"> + <xs:sequence> + <xs:element name="Aussonderungsart" type="xdomea:AussonderungsartType"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Die Aussonderungsart vererbt sich auf alle unter einer Hierarchiestufe angelegten Schriftgutobjekte.</implementationHint> + </xs:appinfo> + <xs:documentation>Die Aussonderungsart gibt für eine Akte oder einen Vorgang das Ergebnis der archivischen Bewertung an. Die Aussonderungsart wird vom Aktenplan (zweistufiges Aussonderungsverfahren) auf zugehörige Vorgänge und Dokumente vererbt.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Gueltigkeit" minOccurs="0" type="xdomea:ZeitraumType"> + <xs:annotation> + <xs:documentation>Die Gültigkeit einer Aktenplaneinheit in einem Aktenplan.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Stillgelegt" type="xs:boolean"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Für die Umsetzung in den Systemen wird empfohlen, sofern kein anderer Wert hinterlegt wurde, als Standardwert den Wert 0 für "nicht stillgelegt" anzugeben.</implementationHint> + </xs:appinfo> + <xs:documentation>Stillgelegt gibt an, ob eine Aktenplaneinheit inaktiv ist (Wert 1) oder nicht (Wert 0). Der Grund für eine Stilllegung kann eintreten, wenn z.B. auf einen bestimmten Zeitpunkt hin der alte Aktenplan "stillgelegt" und der neue Aktenplan in Kraft tritt - aktive Einheiten werden dann in den neuen Aktenplan übernommen, stillgelegte werden abgeschlossen und nicht übernommen.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Aufbewahrungsdauer" type="xdomea:AufbewahrungsdauerType"> + <xs:annotation> + <xs:documentation>Die Aufbewahrungsdauer legt fest, wie viele Jahre eine Akte oder ein Vorgang nach der Verfügung zur Akte (zdA-Verfügung) innerhalb der aktenführenden Stelle aufzubewahren ist oder ob die Aufbewahrung unbefristet erfolgen soll. Nach Ablauf der Aufbewahrungsfrist erfolgt die Aussonderung in Abhängigkeit von der Aussonderungsart.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Einheit" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:AktenplaneinheitAktenplanType"> + <xs:annotation> + <xs:documentation>Eine Aktenplaneinheit, die hierarchisch einer anderen Aktenplaneinheit untergeordnet ist.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="VerweisAktenplaneinheit" + minOccurs="0" + maxOccurs="unbounded" + type="xs:string"> + <xs:annotation> + <xs:documentation>Ein Verweis auf eine andere Aktenplaneinheit in einem aktuellen oder früheren Aktenplan.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="AnwendungsspezifischeErweiterung" + minOccurs="0" + type="xdomea:AnwendungsspezifischeErweiterungType"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Die Speicherung der nicht-auflösbaren Daten beim Empfang erfolgt in einer XML-Datei zum Schriftgutobjekt im empfangenden System. Die Umsetzung muss systemspezifisch gelöst werden - hierbei muss durch das System sichergestellt sein, dass die empfangenen Informationen nicht verloren gehen.</implementationHint> + </xs:appinfo> + <xs:documentation>AnwendungsspezifischeErweiterung darf nur dazu genutzt werden, weitere (z.B. fachspezifische) Metadaten zu spezifizieren, deren Übermittlung mit den bereits in xdomea spezifizierten Metadaten nicht möglich ist.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="AnwendungsspezifischeErweiterungXML" + minOccurs="0" + type="xdomea:AnwendungsspezifischeErweiterungXMLType"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Die Speicherung der nicht-auflösbaren Daten beim Empfang erfolgt in einer XML-Datei zum Schriftgutobjekt im empfangenden System. Die Umsetzung muss systemspezifisch gelöst werden - hierbei muss durch das System sichergestellt sein, dass die empfangenen Informationen nicht verloren gehen.</implementationHint> + </xs:appinfo> + <xs:documentation>AnwendungsspezifischeErweiterungXML darf nur dazu genutzt werden, weitere (z.B. fachspezifische) Metadaten zu spezifizieren, deren Übermittlung mit den bereits in xdomea spezifizierten Metadaten nicht möglich ist. Die AnwendungsspezifischeErweiterungXML bietet die Möglichkeit, mittels Einbindung externer XML-Schemata diese Metadaten zu spezifizieren. Es können beliebige XML-Schemata mit unterschiedlichen Namensräumen angegeben werden. Die XML-Schema-Validierung der weiterführenden Metadaten erfolgt innerhalb der xdomea-Nachricht selbst "lax".</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="AktenplaneinheitType"> + <xs:annotation> + <xs:appinfo> + <title>Aktenplaneinheit</title> + </xs:appinfo> + <xs:documentation>Die Aktenplaneinheit repräsentiert in dem aufgabenbezogenem Ordnungssystem Aktenplan eine Aufgabe.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Kennzeichen" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Das Kennzeichen einer Aktenplaneinheit.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Inhaltsangabe" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die ausführliche Beschreibung der Aufgabe, die durch die Aktenplaneinheit repräsentiert wird.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="BetreffKurz" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die kurze Beschreibung der Aufgabe, die durch die Aktenplaneinheit repräsentiert wird.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="AllgemeineMetadatenType"> + <xs:annotation> + <xs:appinfo> + <title>AllgemeineMetadaten</title> + </xs:appinfo> + <xs:documentation>AllgemeineMetadaten enthält die Metadaten, die der allgemeinen Charakterisierung eines Schriftgutobjektes dienen.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Betreff" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Betreff des Schriftgutobjektes, z.B. für eine Akte der Aktentitel.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Kennzeichen" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Aus dem Aktenplan abgeleitete Kennung des Schriftgutobjektes zur Identifikation und Zuordnung zum Schriftgut in einer Behörde. Bei Akten ist das Kennzeichen das Aktenzeichen, es setzt sich zusammen aus dem zugehörigen Aktenplankennzeichen und einer eindeutigen Ordnungsnummer. Auf Vorgangsebene ist das Kennzeichen das Vorgangszeichen, das sich aus dem Aktenzeichen sowie einer zusätzlichen Nummer für den Vorgang zusammensetzt. Auf Dokumentebene wird als Kennzeichen das Geschäftszeichen verwendet. Dies besteht in der Regel aus dem Aktenzeichen resp. Vorgangszeichen, einer laufenden Nummer sowie der Organisationskurzbezeichnung der zuständigen Organisationseinheit.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Federfuehrung" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Organisationseinheit mit der Hauptverantwortung bzw. der Zuständigkeit für einen Geschäftsprozess.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Aktenfuehrung" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Organisationseinheit mit der Hauptverantwortung bzw. der Zuständigkeit für die Aktenführung.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Vertraulichkeitsstufe" + minOccurs="0" + type="xdomea:VertraulichkeitsstufeCodeType"> + <xs:annotation> + <xs:documentation>Die Vertraulichkeitsstufe beschreibt, welche Kriterien z.B. für die Weitergabe und Veröffentlichung eines Schriftgutobjekts beachtet werden müssen. Mögliche Werte sind "Geheim", "NfD", "Offen", "Streng geheim" oder "Vertraulich".</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Bemerkung" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Zusätzliches Feld zur Übermittlung weiterer Informationen in einem konkreten Geschäftsprozess.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Medium" minOccurs="0" type="xdomea:MediumCodeType"> + <xs:annotation> + <xs:documentation>Das Medium beschreibt, ob es sich um ein Papier- und/oder elektronisches Dokument handelt. Mögliche Werte sind "Papier", "Elektronisch" oder "Hybrid".</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Aktenplaneinheit" + minOccurs="0" + type="xdomea:AktenplaneinheitType"> + <xs:annotation> + <xs:documentation>Die Aktenplaneinheit, dem das Schriftgutobjekt zugeordnet ist.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="AllgemeinerNameType"> + <xs:annotation> + <xs:appinfo> + <title>AllgemeinerName</title> + </xs:appinfo> + <xs:documentation>AllgemeinerName leitet sich von der entsprechenden XÖV-Kernkomponente ab. Er dient der Darstellung von Vor- und Nachnamen und fasst deren gemeinsame Eigenschaften zusammen.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Name" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Name ist der eigentliche Familien- oder Vorname als Zeichenkette. Nachnamen, z.B. mit Adelstiteln bzw. ausländische Nachnamen werden als ein Name übermittelt und nicht in verschiedene Bestandteile aufgeteilt.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="AnlageDokumentType"> + <xs:annotation> + <xs:appinfo> + <title>AnlageDokument</title> + </xs:appinfo> + <xs:documentation>AnlageDokument ist eine Erweiterung eines Dokuments zu einer Anlage mit einer entsprechenden Anlagennummer. Über sie werden andere Dokumente, die einem Dokument als Anlage zugeordnet werden, als solche gekennzeichnet.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:extension base="xdomea:DokumentType"> + <xs:sequence> + <xs:element name="Nummer" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die fortlaufende Nummer eines Anlagendokuments zu einem Dokument.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="AnschriftType"> + <xs:annotation> + <xs:appinfo> + <title>Anschrift</title> + </xs:appinfo> + <xs:documentation>Die Anschrift leitet sich von der entsprechenden XÖV-Kernkomponente ab. Sie beschreibt einen Ort mit den klassischen Ordnungsbegriffen wie Orts- und Straßennamen sowie ergänzenden Informationen wie z.B. Postfach. Eine Anschrift kann genutzt werden, um Orte zu benennen, an denen sich Personen aufhalten, an denen Objekte zu finden sind, oder an denen Ereignisse stattfinden. Darüber hinaus kann sie genutzt werden, um Post oder Waren zuzustellen. Daher enthält sie auch die notwendigen Attribute, um Postfächer zu adressieren.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Staat" minOccurs="0" type="xdomea:StaatType"> + <xs:annotation> + <xs:documentation>Der Staat, dem die Anschrift postalisch zugeordnet wird.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Strasse" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Straße enthält den Namen bzw. die Bezeichnung einer Straße. Eine Straße ist ein planmäßig angelegter, i. allg. befestigter Verkehrsweg innerhalb eines Ortes. Es soll möglichst der amtliche Straßenname aus einem offiziellen Straßenverzeichnis genutzt werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Hausnummer" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Eine Hausnummer dient der genauen Lokalisierung eines Grundstücks, Gebäudes oder Gebäudeteils (Eingang) in einer Straße. Hausnummern können entsprechend der üblichen Praxis in vielen Gemeinden mit ergänzenden Angaben zur weiteren Unterteilung versehen werden, etwa "12a" oder "17 1/3". Da manche Gebäude oder Organisationen sich als Einheit über mehrere Hausnummern erstrecken, können auch Hausnummernbereiche angegeben werden, etwa "12a - 12e" oder "1 - 3".</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Postfach" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Ein Postfach (oft Postfachnummer) ist ein Schlüssel zur Identifikation eines Postfaches in einer Postfiliale. Eine Beschränkung auf numerische Postfachbezeichnungen wurde bewusst nicht vorgenommen.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Postleitzahl" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Eine Postleitzahl ist eine Angabe, um postalische Zustellgebiete unabhängig von Gebietskörperschaften (Gemeinde, Kreis, ...) zu bezeichnen. In Deutschland sind durch Postleitzahlen bezeichnete Bereiche und verwaltungspolitische Grenzen in der Regel aufeinander abgestimmt. Größere Gemeinden und Städte sind häufig in mehrere Postleitzahlengebiete aufgeteilt. Postleitzahlen werden durch die Deutsche Post AG verwaltet. Eine Beschränkung auf deutsche Postleitzahlen (5-stellig) wurde bewusst nicht vorgenommen.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Ort" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Ort enthält den Namen eines Ortes (Gemeinde, Ortschaft oder Stadt). Als Ortsname sollte der amtliche Gemeindename genutzt werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Zusatz" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Ein Anschriftenzusatz beinhaltet ggf. erforderliche weitere Präzisierungen zu einer Anschrift.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Typ" minOccurs="0" type="xdomea:AnschriftstypCodeType"> + <xs:annotation> + <xs:documentation>Im Typ wird beschrieben, um welche Art der Anschrift es sich handelt. Mögliche Werte sind "Aktuelle Anschrift", "Hauptsitz" oder "Zweitsitz".</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="AnwendungsspezifischeErweiterungType"> + <xs:annotation> + <xs:appinfo> + <title>AnwendungsspezifischeErweiterung</title> + </xs:appinfo> + <xs:documentation>AnwendungsspezifischeErweiterung darf nur dazu genutzt werden, weitere (z.B. fachspezifische) Metadaten zu spezifizieren, deren Übermittlung mit den bereits in xdomea spezifizierten Metadaten nicht möglich ist.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Kennung" type="xs:string"> + <xs:annotation> + <xs:documentation>Das Identifikationskennzeichen der anwendungsspezifischen Erweiterung.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Name" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Name der anwendungsspezifischen Erweiterung.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Beschreibung" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die textuelle Erläuterung zu einer anwendungsspezifischen Erweiterung.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Versionsnummer" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Versionsnummer der anwendungsspezifischen Erweiterung.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Versionsdatum" minOccurs="0" type="xs:date"> + <xs:annotation> + <xs:documentation>Das Datum, an dem die Version der anwendungsspezifischen Erweiterung erstellt wurde.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Feldgruppe" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:FeldgruppeType"> + <xs:annotation> + <xs:documentation>Eine Feldgruppe, die der anwendungsspezifischen Erweiterung zugeordnet ist.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Feld" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:FeldType"> + <xs:annotation> + <xs:documentation>Ein Feld, das der anwendungsspezifischen Erweiterung zugeordnet ist.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="AnwendungsspezifischeErweiterungXMLType"> + <xs:annotation> + <xs:appinfo> + <title>AnwendungsspezifischeErweiterungXML</title> + </xs:appinfo> + <xs:documentation>AnwendungsspezifischeErweiterungXML darf nur dazu genutzt werden, weitere (z.B. fachspezifische) Metadaten zu spezifizieren, deren Übermittlung mit den bereits in xdomea spezifizierten Metadaten nicht möglich ist. Die AnwendungsspezifischeErweiterungXML bietet über ein xs:any-Element die Möglichkeit, mittels Einbindung externer XML-Schemata diese Metadaten zu spezifizieren. Es können beliebige XML-Schemata mit unterschiedlichen Namensräumen angegeben werden. Die XML-Schema-Validierung der weiterführenden Metadaten erfolgt innerhalb der xdomea-Nachricht selbst "lax".</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:any minOccurs="0" + maxOccurs="unbounded" + namespace="##any" + processContents="lax"/> + </xs:sequence> + </xs:complexType> + <xs:complexType name="AufbewahrungsdauerType"> + <xs:annotation> + <xs:appinfo> + <title>Aufbewahrungsdauer</title> + </xs:appinfo> + <xs:documentation>Die Aufbewahrungsdauer legt fest, wie viele Jahre eine Akte oder ein Vorgang nach der Verfügung zur Akte (zdA-Verfügung) innerhalb der aktenführenden Stelle aufzubewahren ist oder ob die Aufbewahrung unbefristet erfolgen soll.</xs:documentation> + </xs:annotation> + <xs:choice> + <xs:element name="AnzahlJahre" type="xs:unsignedShort"> + <xs:annotation> + <xs:documentation>Anzahl der Jahre, die eine Akte oder ein Vorgang nach der Verfügung zur Akte (zdA-Verfügung) innerhalb der aktenführenden Stelle aufzubewahren ist.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Unbefristet" fixed="1" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Eine Akte oder ein Vorgang ist nach der Verfügung zur Akte (zdA-Verfügung) innerhalb der aktenführenden Stelle unbefristet aufzubewahren.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:choice> + </xs:complexType> + <xs:complexType name="AussonderungsartType"> + <xs:annotation> + <xs:appinfo> + <title>Aussonderungsart</title> + </xs:appinfo> + <xs:documentation>Die Aussonderungsart gibt das Ergebnis der archivischen Bewertung an. Damit eine automatische Selektion der auszusondernden Vorgänge erfolgen kann, muss in Vorgangsbearbeitungssystemen für Akten und Vorgänge ein Metadatum "Aussonderungsart" oder "AussonderungsartKonfigurierbar" vorgegeben werden. Die Aussonderungsart liegt beim zweistufigen Aussonderungsverfahren bereits im DMS/VBS vor (durch Bewertung von Akten und Vorgängen im DMS oder durch Hinterlegung eines Bewertungskatalogs am Aktenplan) oder sie wird im vierstufigen Aussonderungsverfahren durch die Übernahme des Bewertungsverzeichnisses ins DMS/VBS übernommen.</xs:documentation> + </xs:annotation> + <xs:choice> + <xs:element name="Aussonderungsart" type="xdomea:AussonderungsartCodeType"> + <xs:annotation> + <xs:documentation>Die Aussonderungsart als Wert aus einer vorgegebenen Codeliste.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="AussonderungsartKonfigurierbar" type="xs:string"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Die möglichen Werte für AussonderungsartKonfigurierbar müssen zwischen den beteiligten Kommunikationspartnern (abgebende Stelle und Archiv) vereinbart werden.</implementationHint> + </xs:appinfo> + <xs:documentation>Die Aussonderungsart als frei konfigurierbarer Wert.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:choice> + </xs:complexType> + <xs:complexType name="BearbeitungType"> + <xs:annotation> + <xs:appinfo> + <title>Bearbeitung</title> + </xs:appinfo> + <xs:documentation>Die Erledigung eines Beteiligungsschrittes in einem Geschäftsgang.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Bearbeiter" type="xdomea:KontaktType"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Wird ein Schritt durch den Bearbeiter eines vorhergehenden Schrittes als "übersprungen" markiert, so wird derjenige in dem übersprungenen Schritt auch als Bearbeiter geführt. An dieser Stelle wird für den Bearbeiter der Datentyp "KontaktType" verwendet, da damit der Geschäftsgang (auch organisationsübergreifend) gesteuert werden kann.</implementationHint> + </xs:appinfo> + <xs:documentation>Die spezifische Ausprägung eines Kontaktes, der die Informationen zum Bearbeiter des Beteiligungsschrittes enthält.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Datum" type="xs:date"> + <xs:annotation> + <xs:documentation>Das Datum des Bearbeitungsabschlusses.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Uhrzeit" minOccurs="0" type="xs:time"> + <xs:annotation> + <xs:documentation>Der Zeitpunkt des Bearbeitungsabschlusses.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Vermerk" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Eine Bemerkung auf einem Schriftgutobjekt, die den Geschäftsgang und die Bearbeitung steuert. Sie dient dem Nachvollziehen der Erledigung eines Geschäftsvorfalls. Im konkreten Fall von xdomea ist hiermit die Bestätigung der Erledigung eines Beteiligungsschrittes im externen und internen Geschäftsgang gemeint.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Notiz" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die ergänzende Anmerkung, die der Bearbeiter zum Beteiligungsschritt erfasst.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Anlage" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:DokumentType"> + <xs:annotation> + <xs:documentation>Ein Dokument, das der Bearbeiter des Beteiligungsschrittes dem Beteiligungsschritt z.B. als Stellungnahme beifügt.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="BehoerdenkennungType"> + <xs:annotation> + <xs:appinfo> + <title>Behoerdenkennung</title> + </xs:appinfo> + <xs:documentation>Die Behördenkennung leitet sich von der entsprechenden XÖV-Kernkomponente ab. Sie fasst die Eigenschaften zusammen, über die eine Behörde identifiziert werden kann. Die Behördenkennung ist prioritär zur Übermittlung der im DVDV verzeichneten Behördenschlüssel vorgesehen, kann aber auch für andere Behördenkennungen, bspw. die BKZ der Justizverwaltung eingesetzt werden. Eine Behördenkennung im DVDV besteht aus einem Präfix und der eigentlichen Kennung. Die Codelisten für die Präfixe sowie die Kennungen pro Präfix werden durch die koordinierende Stelle für das DVDV verwaltet. Ein Beispiel für die weitere Nutzung: Bei einer Identifikation von Behörden auf kommunaler Ebene anhand des amtlichen Gemeindeschlüssels (AGS) der Gemeinde, für die die Behörde zuständig ist, lautet der Präfix ags:, die Kennung ist dann der AGS der jeweiligen Gemeinde.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Behoerdenschluessel" minOccurs="0" type="xoev-code:Code"> + <xs:annotation> + <xs:documentation>Schlüssel zur eindeutigen Identifikation einer Behörde. Die Kennung kennzeichnet eine Behörde ggf. innerhalb der durch den Präfix bezeichneten Klasse (z.B. DVDV) eindeutig. Im Zusammenhang mit dem DVDV wird die Kennung durch die koordinierende Stelle für das DVDV verwaltet. Die tatsächlich zu nutzende Codeliste kann an dieser Stelle nicht angegeben werden, da es voraussichtlich pro Präfix jeweils eine Codeliste der Kennungen der Behörden mit diesem Präfix geben wird. (Zum Beispiel die Codeliste der Amtlichen Gemeindeschlüssel für die Behörden auf kommunaler Ebene, die anhand dieses Ordnungsmerkmals im DVDV verzeichnet sind und mit dem Präfix ags: adressiert werden. Eine andere zulässige Liste wäre die Codeliste der Kennungen aller Bundesbehörden, die jeweils mit dem Präfix dbs: zu versehen sind. Nach jetzigem Kenntnisstand kann nicht ausgeschlossen werden, dass Inhalte der Codelisten mit Kennungen für Behörden unterschiedlichen Typs immer disjunkt sind.)</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Praefix" minOccurs="0" type="xoev-code:Code"> + <xs:annotation> + <xs:documentation>Der Präfix bezeichnet eine Klasse von Behördenkennungen. Beispiel: So werden u.a. alle Behördenkennungen der Behörden, die anhand des amtlichen Gemeindeschlüssels (AGS) identifiziert werden können, den Präfix ags: erhalten. Die Liste der Präfixe für Behördenkennungen werden im Zusammenhang mit dem DVDV durch das Bundesverwaltungsamt als koordinierende Stelle für das DVDV verwaltet.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="BeteiligungsschrittType"> + <xs:annotation> + <xs:appinfo> + <title>Beteiligungsschritt</title> + </xs:appinfo> + <xs:documentation>Das Verwaltungshandeln an einem Schriftgutobjekt wird in dem zugehörigen Geschäftsgang protokolliert, der sich aus einzelnen Beteiligungsschritten zusammensetzt. Jeder Beteiligungsschritt hat einen Verfügungsteil, in dem der Bearbeitungsschritt festgelegt, und einen Bearbeitungsteil, in dem der Beteiligungsschritt bearbeitet wird. Die Beteiligungsschritte im Geschäftsgang werden fortlaufend nummeriert.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Nummer" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Nummer des Beteiligungsschrittes innerhalb der fortlaufenden Nummerierung im Geschäftsgang. Die Nummerierung ist innerhalb eines xdomea-Geschäftsgangsobjekts eindeutig. Werden in den xdomea-Geschäftsgang neue Bearbeitungsschritte eingefügt, werden dementsprechend die Nummern der nachfolgenden Beteiligungsschritte verändert. Beteiligungsschritte, die abgeschlossen sind, sind unveränderlich.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Status" type="xdomea:BeteiligungsstatusCodeType"> + <xs:annotation> + <xs:documentation>Der Status beschreibt den Fortschritt eines Beteiligungsschrittes.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Verfuegung" type="xdomea:VerfuegungType"> + <xs:annotation> + <xs:documentation>Steuerungsinformation und Arbeitsanweisung bei der Bearbeitung eines Geschäftsvorfalls. Im konkreten Fall von xdomea ist hier die Arbeitsanweisung für den Bearbeiter eines Beteiligungsschrittes im externen und internen Geschäftsgang gemeint.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Bearbeitung" minOccurs="0" type="xdomea:BearbeitungType"> + <xs:annotation> + <xs:documentation>In der Bearbeitung sind die Informationen zum Bearbeitungsteil des Beteiligungsschrittes zusammengefasst.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="DokumentType"> + <xs:annotation> + <xs:appinfo> + <title>Dokument</title> + </xs:appinfo> + <xs:documentation>Dokument enthält die Metadatenfelder für den Austausch von Dokumenten einschließlich der archivspezifischen Metadaten, anwendungsspezifischer Metadaten, Historien- und Protokollinformationen sowie Informationen zum internen Geschäftsgang. In der Objekthierarchie des Organisationskonzepts elektronische Verwaltungsarbeit ist das Dokument die kleinste logische Einheit des Schriftguts. Es handelt sich um ein einzelnes Schriftstück, papiergebunden oder elektronisch erstellt und verwaltet. Zum Dokument gehören zudem alle ergänzenden Angaben (z.B. Metadaten), die zum Verständnis der Primärdokumente notwendig sind. Der Begriff Dokument entspricht nicht nur den ehemaligen Papierdokumenten, sondern kann daneben jede andere digitale Form von Informationen beinhalten. Es kann aus einem (zum Beispiel ein Bild oder ein Datensatz) oder mehreren Einzelobjekten (zum Beispiel mehrere Bilder, einer Datei mit integrierten Bildern, Text und Tabellen, gemischte Inhalte aus mehreren Quellen) bestehen.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Identifikation" type="xdomea:IdentifikationObjektType"> + <xs:annotation> + <xs:documentation>Über Identifikation werden zur systemübergreifend eindeutigen Identifizierung des Dokuments spezifische Merkmale übergeben.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="AllgemeineMetadaten" + minOccurs="0" + type="xdomea:AllgemeineMetadatenType"> + <xs:annotation> + <xs:documentation>Über AllgemeineMetadaten werden allgemeine Metadaten zu einem Dokument angegeben.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="FremdesGeschaeftszeichen" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Das Geschäftszeichen des Dokuments im absendenden System, das im Zuge eines Nachrichtentransfers übermittelt wird.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Posteingangsdatum" minOccurs="0" type="xs:date"> + <xs:annotation> + <xs:documentation>Das Posteingangsdatum eines Eingangsdokumentes. Es ist relevant beim Austausch von Dokumenten im Vorgangs- oder Aktenzusammenhang.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Postausgangsdatum" minOccurs="0" type="xs:date"> + <xs:annotation> + <xs:documentation>Das Postausgangsdatum eines Ausgangsdokumentes. Es ist relevant beim Austausch von Dokumenten im Vorgangs- oder Aktenzusammenhang.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="DatumDesSchreibens" minOccurs="0" type="xs:date"> + <xs:annotation> + <xs:documentation>Das Datum des Schreibens, z.B. das Datum eines Briefes. Es handelt sich nicht um das Erstellungs- oder Veränderungsdatum des Primärdokuments.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Bezug" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Der konkrete Bezug eines Dokuments, z.B. "Ihr Schreiben vom ..."</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Hier" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>"Hier" wird zur Konkretisierung des Betreffs verwendet. Auch als Unterbetreff bekannt.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Bearbeiter" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:appinfo> + <implementationHint>An dieser Stelle wird für den Bearbeiter der Datentyp "String" verwendet, da es sich hierbei lediglich um den Namen des Bearbeiters handelt und keine weiteren Steuerungsinformationen damit verbunden sind.</implementationHint> + </xs:appinfo> + <xs:documentation>Die für die Bearbeitung zuständige Person.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Typ" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Dokumenttyp dient der weiteren Spezifikation des Dokumentes. Der Typ ist relevant beim Austausch von Dokumenten im Vorgangs- oder Aktenzusammenhang. Zulässige Werte sind z.B. Erlass, Vermerk, Bericht, Bescheid.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="HistorienProtokollInformation" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:HistorienProtokollInformationType"> + <xs:annotation> + <xs:documentation>Über HistorienProtokollInformation werden die zur Historisierung und Protokollierung relevanten Metadaten zu einem Dokument angegeben, in der die Veränderungen an den beschreibenden Attributen und dem Zustand des Dokumentes erfasst werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="InternerGeschaeftsgang" + minOccurs="0" + type="xdomea:GeschaeftsgangType"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Der interne Geschäftsgang kann nach organisatorischer Absprache zwischen den austauschenden Systemen genutzt werden, ist aber nicht verpflichtender Bestandteil von xdomea.</implementationHint> + </xs:appinfo> + <xs:documentation>Die spezifische Ausprägung eines Geschäftsgangs, über die der interne Geschäftsgang am Dokument nachgewiesen wird.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Version" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:VersionType"> + <xs:annotation> + <xs:documentation>Über eine Version wird ein bestimmter Bearbeitungszustand zu einem Dokument im Rahmen der Versionierung des Dokumentes abgebildet.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Verweis" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:VerweisType"> + <xs:annotation> + <xs:documentation>Über einen Verweis wird eine inhaltliche Querbeziehung des Dokuments zu einem anderen Schriftgutobjekt dargestellt.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Anlage" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:AnlageDokumentType"> + <xs:annotation> + <xs:documentation>Ein dem Dokument zugeordnetes Anlagendokument.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Absender" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:KontaktType"> + <xs:annotation> + <xs:documentation>Die spezifische Ausprägung eines Kontakts, der die Informationen zum Absender des Dokumentes enthält.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Empfaenger" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:KontaktType"> + <xs:annotation> + <xs:documentation>Die spezifische Ausprägung eines Kontakts, der die Informationen zum Empfänger des Dokumentes enthält.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="WeitererKontakt" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:KontaktType"> + <xs:annotation> + <xs:documentation>Die spezifische Ausprägung eines Kontakts, der die Informationen zu einem weiteren Beteiligten enthält, der nicht Empfänger oder Absender des Dokuments ist.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="AnwendungsspezifischeErweiterung" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:AnwendungsspezifischeErweiterungType"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Die Speicherung der nicht-auflösbaren Daten beim Empfang erfolgt in einer XML-Datei zum Schriftgutobjekt im empfangenden System. Die Umsetzung muss systemspezifisch gelöst werden - hierbei muss durch das System sichergestellt sein, dass die empfangenen Informationen nicht verloren gehen.</implementationHint> + </xs:appinfo> + <xs:documentation>AnwendungsspezifischeErweiterung darf nur dazu genutzt werden, weitere (z.B. fachspezifische) Metadaten zu spezifizieren, deren Übermittlung mit den bereits in xdomea spezifizierten Metadaten nicht möglich ist.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="AnwendungsspezifischeErweiterungXML" + minOccurs="0" + type="xdomea:AnwendungsspezifischeErweiterungXMLType"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Die Speicherung der nicht-auflösbaren Daten beim Empfang erfolgt in einer XML-Datei zum Schriftgutobjekt im empfangenden System. Die Umsetzung muss systemspezifisch gelöst werden - hierbei muss durch das System sichergestellt sein, dass die empfangenen Informationen nicht verloren gehen.</implementationHint> + </xs:appinfo> + <xs:documentation>AnwendungsspezifischeErweiterungXML darf nur dazu genutzt werden, weitere (z.B. fachspezifische) Metadaten zu spezifizieren, deren Übermittlung mit den bereits in xdomea spezifizierten Metadaten nicht möglich ist. Die AnwendungsspezifischeErweiterungXML bietet die Möglichkeit, mittels Einbindung externer XML-Schemata diese Metadaten zu spezifizieren. Es können beliebige XML-Schemata mit unterschiedlichen Namensräumen angegeben werden. Die XML-Schema-Validierung der weiterführenden Metadaten erfolgt innerhalb der xdomea-Nachricht selbst "lax".</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="FeldType"> + <xs:annotation> + <xs:appinfo> + <title>Feld</title> + </xs:appinfo> + <xs:documentation>Ein Feld ist ein anwendungsspezifisches Metadatum, das bei dem Austausch eines Schriftgutobjektes übergeben wird. Die Konfiguration eines Feldes in den austauschenden Systemen muss zwischen den Kommunikationspartnern abgesprochen und in den Systemen umgesetzt sein.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Name" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Name des Feldes.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Beschreibung" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Hinweise und Erläuterungen zu einem Feld.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Datentyp" minOccurs="0" type="xdomea:DatentypCodeType"> + <xs:annotation> + <xs:documentation>Der Datentyp des Feldwertes. Gültige Angaben sind die W3C-Datentypen.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Wert" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Wert des Feldes.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="FeldgruppeType"> + <xs:annotation> + <xs:appinfo> + <title>Feldgruppe</title> + </xs:appinfo> + <xs:documentation>Eine Feldgruppe gruppiert mehrere Felder als anwendungsspezifische Metadaten beim Austausch eines Schriftgutobjektes.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Name" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Name der Feldgruppe.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Beschreibung" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Hinweise und Erläuterungen zu einer Feldgruppe.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Unterfeldgruppe" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:FeldgruppeType"> + <xs:annotation> + <xs:documentation>Über Unterfeldgruppe erfolgt die hierarchische Unterteilung einer Feldgruppe in weitere Feldgruppen.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Feld" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:FeldType"> + <xs:annotation> + <xs:documentation>Über Feld erfolgt die Unterteilung einer Feldgruppe in konkrete Felder.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="FormatType"> + <xs:annotation> + <xs:appinfo> + <title>Format</title> + </xs:appinfo> + <xs:documentation>Ein Format gibt die Syntax und Semantik einer Datei (z.B. Primärdokument, Aktenplandatei) an.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Name" type="xdomea:DateiformatCodeType"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Für zusätzliche Formatnamen enthält die Codeliste den Wert "Sonstiges" - ist dieser Wert benannt, so muss unter SonstigerName der Name des Formats angegeben werden.</implementationHint> + </xs:appinfo> + <xs:documentation>Der Name des Formats. Gültige Werte sind z.B. doc, pdf, jpg.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SonstigerName" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Die Voraussetzung für die Nutzung von SonstigerName ist die Angabe von "Sonstiges" als Namenswert.</implementationHint> + </xs:appinfo> + <xs:documentation>Der sonstige Name des Formats.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Version" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Version des Formats, z.B. für pdf 1.4 wäre hier "1.4" anzugeben.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Primaerdokument" type="xdomea:PrimaerdokumentType"> + <xs:annotation> + <xs:documentation>Über Primaerdokument werden Dateiangaben zum tatsächlich beschriebenen Primärdokument eines Formats angegeben.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="GeburtType"> + <xs:annotation> + <xs:appinfo> + <title>Geburt</title> + </xs:appinfo> + <xs:documentation>Geburt fasst geburtsbezogene Informationen einer natürlichen Person zusammen.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Datum" type="xs:date"> + <xs:annotation> + <xs:documentation>Das Datum der Geburt.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="GeschaeftsgangType"> + <xs:annotation> + <xs:appinfo> + <title>Geschaeftsgang</title> + </xs:appinfo> + <xs:documentation>In einem Geschäftsgang wird das vorgenommene Verwaltungshandeln an Schriftgutobjekten festgehalten.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Identifikation" type="xdomea:IdentifikationObjektType"> + <xs:annotation> + <xs:documentation>Die Identifikation zur systemübergreifend eindeutigen Identifizierung des Geschäftsgangs.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Beteiligungsschritt" + maxOccurs="unbounded" + type="xdomea:BeteiligungsschrittType"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Es müssen immer alle Beteiligungsschritte eines Geschäftsgangs geliefert werden - unabhängig davon, welchen Status sie besitzen.</implementationHint> + </xs:appinfo> + <xs:documentation>Ein dem Geschäftsgang zugeordneter Beteiligungsschritt, der im Zuge des Geschäftsgangs durchgeführt wird. Die Beteiligungsschritte sind fortlaufend nummeriert.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="HistorienProtokollInformationType"> + <xs:annotation> + <xs:appinfo> + <title>HistorienProtokollInformation</title> + </xs:appinfo> + <xs:documentation>Die Historien- und Protokollinformationen entstehen durch die Bearbeitung von Schriftgutobjekten. Sie protokollieren die Veränderungen an den Metadaten und dem Zustand eines Schriftgutobjektes, die für den Nachweis des Verwaltungshandelns relevant sind - dazu gehören zum Beispiel die Anlage von Vorgängen und Akten, deren Umprotokollierung oder die zdA-Verfügung. Bei der Historisierung werden der alte und der neue Zustand nach der Änderung mit der Angabe des Zeitpunktes und der Uhrzeit der Änderung und der Person, die die Änderung vorgenommen hat, gespeichert.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="MetadatumName" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Das Metadatum, das sich geändert hat.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="MetadatumAlterWert" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Wert des Metadatums vor der Änderung.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="MetadatumNeuerWert" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Wert des Metadatums als Ergebnis der Änderung.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Akteur" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Person, die die Änderung vorgenommen hat. Wird die Änderung automatisch durch das System und nicht manuell durch eine Person vorgenommen, so ist das entsprechende System anzugeben.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="DatumUhrzeit" type="xs:dateTime"> + <xs:annotation> + <xs:documentation>Das Datum und die Uhrzeit der erfassten Änderung.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Bemerkung" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Hinweise und Erläuterungen zu der Änderung eines Metadatums.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Aktion" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Aktion, die die konkrete Änderung des Metadatums näher beschreibt, z.B. gelöscht, neu.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="IdentifikationObjektType"> + <xs:annotation> + <xs:appinfo> + <title>IdentifikationObjekt</title> + </xs:appinfo> + <xs:documentation>Die Zusammenfassung von Merkmalen zur eindeutigen Identifizierung eines Schriftgutobjektes (Dokument, Vorgang, Akte) bzw. von Geschäftsgängen und zur Nummerierung im übergeordneten Schriftgutobjekt.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="ID" type="xdomea:stringUUIDType"> + <xs:annotation> + <xs:documentation>Jedes Schriftgutobjekt (Dokument, Vorgang, Akte) und jeder Geschäftsgang erhält beim Nachrichtenaustausch eine UUID, die sowohl im sendenden als auch empfangenden System als externe ID gespeichert wird.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="NummerImUebergeordnetenContainer" + minOccurs="0" + type="xs:unsignedInt"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Die Nummer dient nicht zur Identifizierung von Schriftgutobjekten - hierzu sollte die ID verwendet werden. Es darf keine doppelte Nummernvergabe erfolgen, aber Lücken z.B. durch gelöschte oder verschobene Schriftgutobjekte sind möglich. Innerhalb eines Schriftgutobjekts ist keine Mischform zulässig (d.h. einige Schriftgutobjekte mit Nummer und andere ohne).</implementationHint> + </xs:appinfo> + <xs:documentation>Die laufende Nummer des Schriftgutobjekts im übergeordneten Objekt (z.B. die Heftungsnummer eines Dokuments in einem Vorgang, die Nummer eines Bandes in einer Akte).</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="KommunikationType"> + <xs:annotation> + <xs:appinfo> + <title>Kommunikation</title> + </xs:appinfo> + <xs:documentation>Die Kommunikation leitet sich von der entsprechenden XÖV-Kernkomponente ab. Sie fasst Angaben zur Erreichbarkeit über elektronische Kommunikationskanäle (z.B. Telefon, Fax, E-Mail) zusammen.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="IstDienstlich" minOccurs="0" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Mit IstDienstlich kann angegeben werden, ob es sich um dienstliche oder private Kommunikationsdaten handelt. Handelt es sich um dienstliche Kommunikationsdaten, so ist der Wert 1 anzugeben. Handelt es sich um private Kommunikationsdaten, so ist der Wert 0 anzugeben.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Kanal" minOccurs="0" type="xdomea:KommunikationsartCodeType"> + <xs:annotation> + <xs:documentation>Der Kanal gibt an, über welchen Kommunikationskanal eine Erreichbarkeit besteht (z.B. Telefon, Fax, E-Mail).</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Kennung" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Kennung beinhaltet die konkrete Angabe zur Erreichbarkeit über einen Kommunikationskanal, d.h. die Telefonnummer, Faxnummer, E-Mail-Adresse oder dergleichen. Die Kennung soll strukturiert erfasst werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Zusatz" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Im Zusatz können zusätzliche freie Angaben zur Erreichbarkeit über einen Kommunikationskanal erfasst werden, z.B. "erreichbar tagsüber zwischen 9 und 16 Uhr".</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="IstInstitution" minOccurs="0" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Mit IstInstitution kann angegeben werden, ob es sich um Kommunikationsdaten einer Institution handelt oder nicht. Handelt es sich um eine Institution, so ist der Wert 1 anzugeben. Handelt es sich um keine Institution, so ist der Wert 0 anzugeben.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="KontaktType"> + <xs:annotation> + <xs:appinfo> + <title>Kontakt</title> + <implementationHint>Je nach Anwendungsfall ist mindestens eines der enthaltenen Elemente mit Daten zu befüllen.</implementationHint> + </xs:appinfo> + <xs:documentation>Ein Kontakt fasst wesentliche Merkmale zu einem Kommunikationspartner zusammen, z.B. Anschriften, Kommunikationsmöglichkeiten.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Behoerdenkennung" + minOccurs="0" + type="xdomea:BehoerdenkennungType"> + <xs:annotation> + <xs:documentation>Die Kennung der Behörde zur Adressierung, z.B. im DVDV.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Institution" minOccurs="0" type="xdomea:NameOrganisationType"> + <xs:annotation> + <xs:documentation>Die Institution des Kontakts. Eine Institution ist z.B. ein Unternehmen oder eine Behörde.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Organisationseinheit" + minOccurs="0" + type="xdomea:OrganisationseinheitType"> + <xs:annotation> + <xs:documentation>Die Organisationseinheit des Kontakts.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Name" minOccurs="0" type="xdomea:NameNatuerlichePersonType"> + <xs:annotation> + <xs:documentation>Der Name des Ansprechpartners zum Kontakt.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Taetigkeit" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Tätigkeit gibt an, welche Position der im Kontakt angegebene Ansprechpartner in der jeweiligen Institution einnimmt. Es können hier die Amtsbezeichnung (z.B. Regierungsrat), Dienstbezeichnung (z.B. Referendar), der Dienstgrad (z.B. General) oder die Berufsbezeichnung (z.B. IT-Berater) angegeben werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Zustaendigkeit" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Zuständigkeit gibt die Bereiche an, für die der im Kontakt angegebene Ansprechpartner oder die Institution verantwortlich ist, z.B. "Leiter der Abteilung O", "Projektleiter des XYZ-Projekts".</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Anschrift" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:AnschriftType"> + <xs:annotation> + <xs:documentation>Eine strukturierte Anschrift des Kontakts.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Kommunikation" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:KommunikationType"> + <xs:annotation> + <xs:documentation>Eine Kommunikationsmöglichkeit des Kontakts, die die Angaben zur Erreichbarkeit über elektronische Kommunikationskanäle enthält.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Rolle" minOccurs="0" type="xoev-code:Code"> + <xs:annotation> + <xs:documentation>Die Rolle des Kontakts im konkreten Geschäftsprozess, z.B Antragsteller, Zustellungsbevollmächtigter, Gutachter.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="UnstrukturierteAnschrift" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:UnstrukturierteAnschriftType"> + <xs:annotation> + <xs:documentation>Eine unstrukturierte Anschrift des Kontakts.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Geburt" minOccurs="0" type="xdomea:GeburtType"> + <xs:annotation> + <xs:documentation>Die Geburtsangaben des Ansprechpartners zum Kontakt.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="MetadatenAussonderungType"> + <xs:annotation> + <xs:appinfo> + <title>MetadatenAussonderung</title> + </xs:appinfo> + <xs:documentation>MetadatenAussonderung fasst die Informationen zu einem abschließend bearbeiteten Schriftgutobjekt (Vorgang oder Akte) zusammen, die für seine Aufbewahrung und Aussonderung relevant sind.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Aufbewahrungsdauer" + minOccurs="0" + type="xdomea:AufbewahrungsdauerType"> + <xs:annotation> + <xs:documentation>Die Aufbewahrungsdauer legt fest, wie viele Jahre eine Akte oder ein Vorgang nach der Verfügung zur Akte (zdA-Verfügung) innerhalb der aktenführenden Stelle aufzubewahren ist oder ob die Aufbewahrung unbefristet erfolgen soll. Nach Ablauf der Aufbewahrungsfrist erfolgt die Aussonderung in Abhängigkeit von der Aussonderungsart.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Aussonderungsart" + minOccurs="0" + type="xdomea:AussonderungsartType"> + <xs:annotation> + <xs:documentation>Die Aussonderungsart gibt das Ergebnis der archivischen Bewertung an. Damit eine automatische Selektion der auszusondernden Vorgänge erfolgen kann, muss in Vorgangsbearbeitungssystemen für Akten und Vorgänge ein Metadatum "Aussonderungsart" vorgegeben werden. Die Aussonderungsart wird vom Aktenplan (zweistufiges Aussonderungsverfahren) oder von der Akte (vierstufiges Aussonderungsverfahren) auf zugehörige Vorgänge und Dokumente vererbt.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Kennung" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Kennung enthält bei der Durchführung einer Aussonderung die Archivkennung, bei einer Abgabe die Kennung des Schriftgutobjekts aus dem System der übernehmenden Behörde.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Bewertungsvorschlag" + minOccurs="0" + type="xdomea:BewertungsvorschlagCodeType"> + <xs:annotation> + <xs:documentation>Der Bewertungsvorschlag ist ein Hinweis des Bearbeiters eines Schriftgutobjekts an das zuständige Archiv. Er kann die Werte archivwürdig oder vernichten annehmen.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Aufbewahrungsende" minOccurs="0" type="xs:date"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Über die Belegung dieses Feldes mit 31.12.JJJJ kann auch nur ein Endjahr angegeben werden. Die Art der Aussonderung (taggenau oder jährlich) ist mit dem zuständigen Archiv abzustimmen.</implementationHint> + </xs:appinfo> + <xs:documentation>Das Aufbewahrungsende gibt taggenau das Ende der Aufbewahrungsfrist an.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="NameNatuerlichePersonType"> + <xs:annotation> + <xs:appinfo> + <title>NameNatuerlichePerson</title> + </xs:appinfo> + <xs:documentation>NameNatuerlichePerson leitet sich von der entsprechenden XÖV-Kernkomponente ab. Der Name der Person ist eine Benennung dieser Person, die dazu dient, diese Person von anderen Personen zu unterscheiden.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Anrede" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Anrede ist der Namenszusatz (auch eine Anrede ohne Namen nur mit Titel ist eine Anrede!) bei der Anrede (mündlich oder schriftlich) oder bei einem Anruf (fernmündlich) an eine Person oder Personengruppe, z.B. Herr, Frau.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Titel" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Ein Titel wird häufig im Zusammenhang mit Namen verwendet, ist aber kein originärer Bestandteil des Namens. Im Unterschied dazu gehören Adelstitel zum Familiennamen und sind daher in diesem Verständnis kein Titel. Zu den Titeln zählen beispielsweise akademische Grade, Dienst- und Amtsbezeichnungen oder militärische Ränge. Es können auch Titel übermittelt werden, die keine Titel im Sinne des Meldewesens sind.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Familienname" minOccurs="0" type="xdomea:AllgemeinerNameType"> + <xs:annotation> + <xs:documentation>Der Familienname ist der aktuelle Nachname einer Person und Ausdruck einer bestimmten Familienzugehörigkeit dieser Person.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Vorname" minOccurs="0" type="xdomea:AllgemeinerNameType"> + <xs:annotation> + <xs:documentation>Der Vorname ist der Name bzw. der Teil des Namens, der nicht die Zugehörigkeit zu einer Familie ausdrückt, sondern das Individuum innerhalb der Familie bezeichnet und dazu dient, es von anderen Familienmitgliedern zu unterscheiden.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="NameOrganisationType"> + <xs:annotation> + <xs:appinfo> + <title>NameOrganisation</title> + </xs:appinfo> + <xs:documentation>NameOrganisation leitet sich von der entsprechenden XÖV-Kernkomponente ab und fasst Angaben zum Namen einer Organisation zusammen.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Name" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Der offizielle Name einer Organisation. Entspricht bei registrierten Organisationen dem im Register eingetragenen Namen.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Kurzbezeichnung" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Kurzbezeichnung des Namens einer Organisation.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="NkBasisType"> + <xs:annotation> + <xs:appinfo> + <title>NkBasis</title> + </xs:appinfo> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="ProzessID" type="xdomea:stringUUIDType"> + <xs:annotation> + <xs:documentation>Die UUID des Prozesses, zu dem die Nachricht gehört. Sie dient zur Identifikation bei Rückmeldungen.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Nachrichtentyp" type="xdomea:NachrichtentypCodeType"> + <xs:annotation> + <xs:documentation>Der Nachrichtentyp gibt die Bezeichnung der Nachricht an.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Erstellungszeitpunkt" type="xs:dateTime"> + <xs:annotation> + <xs:documentation>Der Zeitpunkt der Nachrichtenerzeugung.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Absender" type="xdomea:KontaktType"> + <xs:annotation> + <xs:documentation>Der Absender der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Empfaenger" type="xdomea:KontaktType"> + <xs:annotation> + <xs:documentation>Der Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SendendesSystem" minOccurs="0" type="xdomea:SystemType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem System, aus dem die Daten gesendet werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Hinweis" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Hinweis umfasst Erläuterungen zu der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="AnwendungsspezifischeErweiterung" + minOccurs="0" + type="xdomea:AnwendungsspezifischeErweiterungType"> + <xs:annotation> + <xs:documentation>AnwendungsspezifischeErweiterung darf nur dazu genutzt werden, weitere (z.B. fachspezifische) Metadaten zu spezifizieren, deren Übermittlung mit den bereits in xdomea spezifizierten Metadaten nicht möglich ist.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="AnwendungsspezifischeErweiterungXML" + minOccurs="0" + type="xdomea:AnwendungsspezifischeErweiterungXMLType"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Die Speicherung der nicht-auflösbaren Daten beim Empfang erfolgt in einer XML-Datei zum Schriftgutobjekt im empfangenden System. Die Umsetzung muss systemspezifisch gelöst werden - hierbei muss durch das System sichergestellt sein, dass die empfangenen Informationen nicht verloren gehen.</implementationHint> + </xs:appinfo> + <xs:documentation>AnwendungsspezifischeErweiterungXML darf nur dazu genutzt werden, weitere (z.B. fachspezifische) Metadaten zu spezifizieren, deren Übermittlung mit den bereits in xdomea spezifizierten Metadaten nicht möglich ist. Die AnwendungsspezifischeErweiterungXML bietet die Möglichkeit, mittels Einbindung externer XML-Schemata diese Metadaten zu spezifizieren. Es können beliebige XML-Schemata mit unterschiedlichen Namensräumen angegeben werden. Die XML-Schema-Validierung der weiterführenden Metadaten erfolgt innerhalb der xdomea-Nachricht selbst "lax".</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="NkFVDatenType"> + <xs:annotation> + <xs:appinfo> + <title>NkFVDaten</title> + </xs:appinfo> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen zu Nachrichten im Rahmen eines Austauschs von Fachverfahrensdaten.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:extension base="xdomea:NkBasisType"> + <xs:sequence> + <xs:element name="EmpfangendesSystem" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:SystemType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem System, das die Daten erhalten soll.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="NkNichtFVDatenEinEmpfaengerMitEmpfangsbestaetigungType"> + <xs:annotation> + <xs:appinfo> + <title>NkNichtFVDatenEinEmpfaengerMitEmpfangsbestaetigung</title> + </xs:appinfo> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger einer Nachricht, bei der es sich nicht um eine Empfangs-/Importnachricht auf eine andere Nachricht handelt, die einen Empfänger besitzt und mit der eine Empfangsbestätigung angefordert werden kann.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:extension base="xdomea:NkBasisType"> + <xs:sequence> + <xs:element name="Empfangsbestaetigung" type="xs:boolean"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Für die Umsetzung in den Systemen wird empfohlen, sofern kein anderer Wert hinterlegt wurde, als Standardwert den Wert 0 für "keine Empfangsbestätigung senden" anzugeben.</implementationHint> + </xs:appinfo> + <xs:documentation>Die Angabe, ob vom Empfänger der Nachricht eine Empfangsbestätigung erwünscht wird. Eine erwünschte Empfangsbestätigung wird mit 1 gekennzeichnet. Wird keine Empfangsbestätigung gewünscht, so wird dies mit 0 gekennzeichnet.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="NkNichtFVDatenWeitereEmpfaengerMitEmpfangsbestaetigungType"> + <xs:annotation> + <xs:appinfo> + <title>NkNichtFVDatenWeitereEmpfaengerMitEmpfangsbestaetigung</title> + </xs:appinfo> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger einer Nachricht, bei der es sich nicht um eine Empfangs-/Importnachricht auf eine andere Nachricht handelt, die mehrere Empfänger besitzen kann und mit der eine Empfangsbestätigung angefordert werden kann.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:extension base="xdomea:NkNichtFVDatenWeitereEmpfaengerType"> + <xs:sequence> + <xs:element name="Empfangsbestaetigung" type="xs:boolean"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Für die Umsetzung in den Systemen wird empfohlen, sofern kein anderer Wert hinterlegt wurde, als Standardwert den Wert 0 für "keine Empfangsbestätigung senden" anzugeben.</implementationHint> + </xs:appinfo> + <xs:documentation>Die Angabe, ob vom Empfänger der Nachricht eine Empfangsbestätigung erwünscht wird. Eine erwünschte Empfangsbestätigung wird mit 1 gekennzeichnet. Wird keine Empfangsbestätigung gewünscht, so wird dies mit 0 gekennzeichnet.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="NkNichtFVDatenWeitereEmpfaengerType"> + <xs:annotation> + <xs:appinfo> + <title>NkNichtFVDatenWeitereEmpfaenger</title> + </xs:appinfo> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger einer Nachricht, bei der es sich nicht um eine Empfangs-/Importnachricht auf eine andere Nachricht handelt und die beliebige Empfänger besitzen kann.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:extension base="xdomea:NkBasisType"> + <xs:sequence> + <xs:element name="WeitererEmpfaenger" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:KontaktType"> + <xs:annotation> + <xs:documentation>Ein weiterer Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="OrganisationseinheitType"> + <xs:annotation> + <xs:appinfo> + <title>Organisationseinheit</title> + </xs:appinfo> + <xs:documentation>Die Organisationseinheit leitet sich von der entsprechenden XÖV-Kernkomponente ab. Sie fasst Angaben zur Darstellung der internen hierarchischen Organisationsstruktur einer Institution zusammen, z.B. zur Darstellung von Abteilungen, Referaten.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Name" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Bezeichnung der Organisationseinheit.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="PrimaerdokumentType"> + <xs:annotation> + <xs:appinfo> + <title>Primaerdokument</title> + </xs:appinfo> + <xs:documentation>Ein Primärdokument gehört zum eigentlichen Inhalt eines Dokuments. Es kann sowohl in analoger Form als Inhalt eines Papierdokuments oder in digitaler Form als Inhalt eines elektronischen Dokuments (Datei) vorliegen.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Dateiname" type="xdomea:stringDateinameType"> + <xs:annotation> + <xs:documentation>Der Dateiname des Primärdokumentes, der z.B. nach dem Muster "UUID", "UUID.Dateiformat" oder "UUID_Dokumentname.Dateiformat" gebildet werden kann.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="DateinameOriginal" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Name der Datei zum Zeitpunkt des Imports in ein DMS / VBS.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Ersteller" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:appinfo> + <implementationHint>An dieser Stelle wird für den Ersteller der Datentyp "String" verwendet, da es sich hierbei lediglich um den Namen des Erstellers handelt und keine weiteren Steuerungsinformationen damit verbunden sind.</implementationHint> + </xs:appinfo> + <xs:documentation>Der Ersteller des Primärdokuments.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="DatumUhrzeit" minOccurs="0" type="xs:dateTime"> + <xs:annotation> + <xs:documentation>Der Erstellungszeitpunkt des Primärdokuments.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SignaturSiegel" + minOccurs="0" + type="xdomea:SignaturSiegelType"> + <xs:annotation> + <xs:documentation>Angaben zur elektronischen Signatur oder zum elektronischen Siegel, die zum Dokument gehören.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="SignaturSiegelType"> + <xs:annotation> + <xs:appinfo> + <title>Signatur und Siegel</title> + </xs:appinfo> + <xs:documentation>Angaben zur elektronischen Signatur oder zum elektronischen Siegel.</xs:documentation> + </xs:annotation> + <xs:choice> + <xs:element name="SignaturSiegelEingebettet" fixed="1" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Die elektronische Signatur oder das elektronische Siegel zum Dokument liegt eingebettet vor.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SignaturSiegelDatei" + maxOccurs="unbounded" + type="xdomea:stringDateinameType"> + <xs:annotation> + <xs:documentation>Die elektronische Signatur oder das elektronische Siegel zum Dokument liegt in einer separaten Datei vor.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:choice> + </xs:complexType> + <xs:complexType name="StaatType"> + <xs:annotation> + <xs:appinfo> + <title>Staat</title> + </xs:appinfo> + <xs:documentation>Staat leitet sich von der entsprechenden XÖV-Kernkomponente ab. Als Staat bezeichnet man eine politische Ordnung, die ein gemeinsames als Staatsgebiet abgegrenztes Territorium, ein dazugehöriges Staatsvolk und eine Machtausübung über dieses umfasst.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Staat" type="xdomea:StaatCodeType"> + <xs:annotation> + <xs:documentation>Staat enthält einen Schlüssel zur Identifikation eines Staates.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="SystemType"> + <xs:annotation> + <xs:appinfo> + <title>System</title> + <implementationHint>Je nach Anwendungsfall ist mindestens eines der enthaltenen Elemente mit Daten zu befüllen.</implementationHint> + </xs:appinfo> + <xs:documentation>Ein System ist ein die xdomea-Nachrichten erzeugendes Produkt (z.B. DMS oder VBS).</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="InstanzID" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Instanz-ID dient der eindeutigen Identifikation des Systems, in dem die xdomea-Nachricht erzeugt wird. Die Identifizierung des Mandantens ist darin enthalten.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Produktname" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Name des Produktes.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Version" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Version des Produktes.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="UnstrukturierteAnschriftType"> + <xs:annotation> + <xs:appinfo> + <title>UnstrukturierteAnschrift</title> + </xs:appinfo> + <xs:documentation>Die unstrukturierte Anschrift dient der Übermittlung von Anschriften, die nicht der regulären Anschrift entsprechen.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Typ" minOccurs="0" type="xdomea:AnschriftstypCodeType"> + <xs:annotation> + <xs:documentation>Im Typ wird beschrieben, um welche Art der Anschrift es sich handelt. Mögliche Werte sind "Aktuelle Anschrift", "Hauptsitz" oder "Zweitsitz".</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Zeile1" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Erste Zeile der unstrukturierten Anschrift.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Zeile2" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Zweite Zeile der unstrukturierten Anschrift.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Zeile3" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Dritte Zeile der unstrukturierten Anschrift.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Zeile4" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Vierte Zeile der unstrukturierten Anschrift.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Zeile5" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Fünfte Zeile der unstrukturierten Anschrift.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Zeile6" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Sechste Zeile der unstrukturierten Anschrift.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Zusatz" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Ein Anschriftenzusatz beinhaltet ggf. erforderliche weitere Präzisierungen zu einer Anschrift.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="VerfuegungType"> + <xs:annotation> + <xs:appinfo> + <title>Verfuegung</title> + </xs:appinfo> + <xs:documentation>Eine Verfügung ist ein Mittel zur Steuerung der Bearbeitung eines Schriftgutobjektes in einem Beteiligungsschritt. Die Bearbeitung eines Geschäftsvorfalls wird durch förmliche und abschließend gezeichnete Verfügungen eingeleitet, fortgeführt und abgeschlossen. Gegenstand von Verfügungen können insbesondere sein: Entwürfe von Schreiben Beteiligung anderer Organisationseinheiten Hinweise zur Sicherung eines ausreichenden schriftlichen Nachweises der Bearbeitung Abschließende Verfügung zur weiteren Bearbeitung oder zu deren Abschluss (Schlussverfügung)</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Ersteller" type="xdomea:KontaktType"> + <xs:annotation> + <xs:appinfo> + <implementationHint>An dieser Stelle wird für den Ersteller der Datentyp "KontaktType" verwendet, da damit der Geschäftsgang (auch organisationsübergreifend) gesteuert werden kann.</implementationHint> + </xs:appinfo> + <xs:documentation>Die spezifische Ausprägung eines Kontaktes, durch die der Erlasser der Verfügung bestimmt wird.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Adressat" type="xdomea:KontaktType"> + <xs:annotation> + <xs:documentation>Die spezifische Ausprägung eines Kontaktes, durch die der Empfänger der Verfügung bestimmt wird.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Erstellungsdatum" type="xs:date"> + <xs:annotation> + <xs:documentation>Das Erstellungsdatum der Verfügung.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Erstellungsuhrzeit" minOccurs="0" type="xs:time"> + <xs:annotation> + <xs:documentation>Die Erstellungsuhrzeit der Verfügung.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Verfuegung" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die textuelle Beschreibung der Verfügung, z.B. zur Kenntnis, zur Mitzeichnung, zur Bearbeitung.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="TerminDatum" minOccurs="0" type="xs:date"> + <xs:annotation> + <xs:documentation>Das vom Ersteller für die Erledigung der Verfügung festgelegte Datum.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="TerminUhrzeit" minOccurs="0" type="xs:time"> + <xs:annotation> + <xs:documentation>Die vom Ersteller für die Erledigung der Verfügung festgelegte Uhrzeit.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Notiz" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Hinweise oder Erläuterungen zu einer Verfügung.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="VersionType"> + <xs:annotation> + <xs:appinfo> + <title>Version</title> + </xs:appinfo> + <xs:documentation>Eine Version ist ein definierter Stand eines Dokuments zu einem bestimmten Zeitpunkt. Verschiedene Versionen stellen die Veränderung und Weiterentwicklung eines Dokumentes dar. Welche Veränderungen zu einer neuen Version führen, ist eine organisatorische Festlegung. Um die Chronologie abzubilden, erhält auch das Originaldokument eine Versionsnummer.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Nummer" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Nummer der Version.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Format" maxOccurs="unbounded" type="xdomea:FormatType"> + <xs:annotation> + <xs:documentation>Ein Format, das der Dokumentversion zugeordnet ist.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="VerweisType"> + <xs:annotation> + <xs:appinfo> + <title>Verweis</title> + <implementationHint>Mindestens eines der Elemente ID bzw. SGOKennzeichen muss gefüllt sein.</implementationHint> + </xs:appinfo> + <xs:documentation>Ein Verweis stellt eine inhaltliche Querbeziehung eines Schriftgutobjekts zu einem anderen Schriftgutobjekt dar.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="ID" minOccurs="0" type="xdomea:stringUUIDType"> + <xs:annotation> + <xs:documentation>Die UUID des Schriftgutobjektes, zu dem der inhaltliche Querverweis dargestellt wird.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SGOTyp" type="xdomea:SchriftgutobjekttypCodeType"> + <xs:annotation> + <xs:documentation>Der Typ des Schriftgutobjektes, auf das verwiesen wird. Mögliche Werte sind "Akte", "Dokument" und "Vorgang".</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SGOKennzeichen" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Das Kennzeichen des Schriftgutobjektes, auf das verwiesen wird.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Bemerkung" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Hinweise und Bemerkungen zu diesem Verweis.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="VorgangType"> + <xs:annotation> + <xs:appinfo> + <title>Vorgang</title> + </xs:appinfo> + <xs:documentation>Vorgang enthält die Metadatenfelder für den Austausch von Vorgängen einschließlich der archivspezifischen Metadaten, anwendungsspezifischer Metadaten, Historien- und Protokollinformationen sowie Informationen zum internen Geschäftsgang. Die absendende Behörde kann jeweils festlegen, welche Informationen dem Empfänger mit der Übertragung zur Verfügung gestellt werden sollen. So kann auch der Anforderung nach einer ggf. erforderlichen Beschränkung der übertragenen Metadaten Rechnung getragen werden (z.B. auf Grund datenschutzrechtlicher oder sonstiger gesetzlicher Bestimmungen).</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Identifikation" type="xdomea:IdentifikationObjektType"> + <xs:annotation> + <xs:documentation>Über Identifikation werden zur systemübergreifend eindeutigen Identifizierung des Vorgangs spezifische Merkmale übergeben.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="AllgemeineMetadaten" + minOccurs="0" + type="xdomea:AllgemeineMetadatenType"> + <xs:annotation> + <xs:documentation>Über AllgemeineMetadaten werden allgemeine Metadaten zu einem Vorgang angegeben.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="ArchivspezifischeMetadaten" + minOccurs="0" + type="xdomea:MetadatenAussonderungType"> + <xs:annotation> + <xs:documentation>Über ArchivspezifischeMetadaten werden die für die Archivierung und Aussonderung relevanten Metadaten zu einem Vorgang angegeben.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Aktenbetreff" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Inhaltsangabe der Akte, der der Vorgang untergeordnet ist. Dies ist relevant als Kontextinformation bei der Versendung von Vorgängen ohne die Akte.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Typ" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die weitere Spezifikation des Vorgangs über einen Typ, u.a zur Recherche oder zur Festlegung zusätzlicher Metadaten. Mögliche Werte sind z.B. Genehmigungsverfahren, Widerspruchsverfahren, Kabinettsvorlage etc.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="ZdA" minOccurs="0" type="xs:boolean"> + <xs:annotation> + <xs:appinfo> + <implementationHint>ZdA (zu den Akten) steht für das Schließen eines Schriftgutobjekts (Teilvorgang, Vorgang, Teilakte oder Akte). Die hierfür in den Verwaltungen genutzten Bezeichnungen können anders lauten (z.B. „Schließen der Akte oder des Vorgangs“).</implementationHint> + </xs:appinfo> + <xs:documentation>ZdA kennzeichnet, ob der Vorgang zu den Akten verfügt wurde (Wert 1) oder nicht (Wert 0).</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="ZdADatum" minOccurs="0" type="xs:date"> + <xs:annotation> + <xs:appinfo> + <implementationHint>ZdA (zu den Akten) steht für das Schließen eines Schriftgutobjekts (Teilvorgang, Vorgang, Teilakte oder Akte). Die hierfür in den Verwaltungen genutzten Bezeichnungen können anders lauten (z.B. „Schließen der Akte oder des Vorgangs“).</implementationHint> + </xs:appinfo> + <xs:documentation>ZdADatum kennzeichnet, wann der Vorgang zu den Akten verfügt wurde.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Laufzeit" minOccurs="0" type="xdomea:ZeitraumType"> + <xs:annotation> + <xs:documentation>Die Laufzeit des Vorgangs, d.h. Zeitpunkt des Beginns und des Endes.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="HistorienProtokollInformation" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:HistorienProtokollInformationType"> + <xs:annotation> + <xs:documentation>Über HistorienProtokollInformation werden die zur Historisierung und Protokollierung relevanten Metadaten zu einem Vorgang angegeben, in der die Veränderungen an den beschreibenden Attributen und dem Zustand des Vorgangs erfasst werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="InternerGeschaeftsgang" + minOccurs="0" + type="xdomea:GeschaeftsgangType"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Der interne Geschäftsgang kann nach organisatorischer Absprache zwischen den austauschenden Systemen genutzt werden, ist aber nicht verpflichtender Bestandteil von xdomea.</implementationHint> + </xs:appinfo> + <xs:documentation>Die spezifische Ausprägung eines Geschäftsgangs, über die der interne Geschäftsgang am Vorgang nachgewiesen wird.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Dokument" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:DokumentType"> + <xs:annotation> + <xs:documentation>Ein Dokument, das hierarchisch in den Vorgang eingebunden bzw. dem Vorgang untergeordnet ist.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Verweis" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:VerweisType"> + <xs:annotation> + <xs:documentation>Über einen Verweis wird eine inhaltliche Querbeziehung des Vorgangs zu einem anderen Schriftgutobjekt dargestellt.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Kontakt" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:KontaktType"> + <xs:annotation> + <xs:documentation>Eine Kontaktinformation zu einem Geschäftsprozessbeteiligten.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Teilvorgang" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:VorgangType"> + <xs:annotation> + <xs:documentation>Über einen Teilvorgang kann ein Vorgang hierarchisch in einen anderen Vorgang eingebunden bzw. einem anderen Vorgang untergeordnet werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="AnwendungsspezifischeErweiterung" + minOccurs="0" + type="xdomea:AnwendungsspezifischeErweiterungType"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Die Speicherung der nicht-auflösbaren Daten beim Empfang erfolgt in einer XML-Datei zum Schriftgutobjekt im empfangenden System. Die Umsetzung muss systemspezifisch gelöst werden - hierbei muss durch das System sichergestellt sein, dass die empfangenen Informationen nicht verloren gehen.</implementationHint> + </xs:appinfo> + <xs:documentation>AnwendungsspezifischeErweiterung darf nur dazu genutzt werden, weitere (z.B. fachspezifische) Metadaten zu spezifizieren, deren Übermittlung mit den bereits in xdomea spezifizierten Metadaten nicht möglich ist.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="AnwendungsspezifischeErweiterungXML" + minOccurs="0" + type="xdomea:AnwendungsspezifischeErweiterungXMLType"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Die Speicherung der nicht-auflösbaren Daten beim Empfang erfolgt in einer XML-Datei zum Schriftgutobjekt im empfangenden System. Die Umsetzung muss systemspezifisch gelöst werden - hierbei muss durch das System sichergestellt sein, dass die empfangenen Informationen nicht verloren gehen.</implementationHint> + </xs:appinfo> + <xs:documentation>AnwendungsspezifischeErweiterungXML darf nur dazu genutzt werden, weitere (z.B. fachspezifische) Metadaten zu spezifizieren, deren Übermittlung mit den bereits in xdomea spezifizierten Metadaten nicht möglich ist. Die AnwendungsspezifischeErweiterungXML bietet die Möglichkeit, mittels Einbindung externer XML-Schemata diese Metadaten zu spezifizieren. Es können beliebige XML-Schemata mit unterschiedlichen Namensräumen angegeben werden. Die XML-Schema-Validierung der weiterführenden Metadaten erfolgt innerhalb der xdomea-Nachricht selbst "lax".</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="ZeitraumType"> + <xs:annotation> + <xs:appinfo> + <title>Zeitraum</title> + </xs:appinfo> + <xs:documentation>Der Zeitraum kennzeichnet einen Abschnitt auf dem Zeitstrahl durch Angabe von Beginn und/oder Ende.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Beginn" minOccurs="0" type="xs:date"> + <xs:annotation> + <xs:documentation>Der Beginn eines Zeitraums beschreibt den Zeitpunkt, ab dem ein Sachverhalt eintritt bzw. rechtskräftig wirksam ist. Der Beginn ist immer Teil der Dauer des Zeitraumes. Beispiele sind: Fristbeginn (BKA) Wirksamkeitsdatum der Änderung des Familiennamens (Personenstand) Eheschließungsdatum (Personenstand)</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Ende" minOccurs="0" type="xs:date"> + <xs:annotation> + <xs:documentation>Das Ende eines Zeitraumes beschreibt den Zeitpunkt, ab dem ein Sachverhalt endet bzw. nicht mehr rechtskräftig ist. Das Ende ist selbst Teil der Dauer des Zeitraumes. Beispiele sind: Fristdatum (Bau) Ablaufdatum (Finanz) Faelligkeitsdatum (Finanz) Wirksamkeitsdatum der Aufhebung/Scheidung der Ehe (Personenstand)</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> +</xs:schema> diff --git a/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Datentypen.xsd b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Datentypen.xsd new file mode 100644 index 0000000000000000000000000000000000000000..060a9d2ea4dbde2c8d6df4f3a500417aab09f16f --- /dev/null +++ b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Datentypen.xsd @@ -0,0 +1,5329 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xdomea="urn:xoev-de:xdomea:schema:3.0.0" + xmlns:xoev-code="http://xoev.de/schemata/code/1_0" + targetNamespace="urn:xoev-de:xdomea:schema:3.0.0" + version="3.0.0" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> + <xs:annotation> + <xs:appinfo> + <standard> + <nameLang>xdomea - XÖV-Standard für den IT-gestützten Austausch und die IT-gestützte Aussonderung behördlichen Schriftgutes</nameLang> + <nameKurz>xdomea</nameKurz> + <nameTechnisch>xdomea</nameTechnisch> + <kennung>urn:xoev-de:xdomea:kosit:standard:xdomea</kennung> + <beschreibung>xdomea ist der vom IT-Planungsrat verabschiedete verbindliche Standard für den Austausch von Akten, Vorgängen und Dokumenten im Kontext der Übermittlung, der Abgabe sowie der Aussonderung von Schriftgutobjekten (www.it-planungsrat.de, Beschluss 2017/39). Weiterhin kann xdomea für den Austausch zwischen Fachverfahren und DMS/VBS sowie für die Zwischenarchivierung genutzt werden. + +Um diese Anwendungsszenarien bestmöglich zu unterstützen, ist xdomea gemäß des XÖV-Rahmenwerkes nach dem Baukastenprinzip aufgebaut und bietet einzelne Nachrichten(gruppen) für die jeweiligen Prozesse an. + +Der Standard xdomea wird von der gleichnamigen Arbeitsgruppe des IT-Planungsrates weiterentwickelt und gepflegt. Der Betrieb des Standards erfolgt durch die Koordinierungsstelle für IT-Standards (KoSIT). +</beschreibung> + </standard> + <versionStandard> + <version>3.0.0</version> + <beschreibung>Die Version 3.0.0 ist durch den IT-Planungsrat beschlossen. Details zum Beschluss sowie zu den Fristen der Umsetzung sind der Veröffentlichung im Bundesanzeiger unter www.bundesanzeiger.de zu entnehmen.</beschreibung> + <versionXOEVProfil>1.7.2</versionXOEVProfil> + <versionXOEVHandbuch>2.3.1</versionXOEVHandbuch> + <versionXGenerator>3.0.1</versionXGenerator> + <versionModellierungswerkzeug>19.0</versionModellierungswerkzeug> + <nameModellierungswerkzeug>MagicDraw</nameModellierungswerkzeug> + </versionStandard> + </xs:appinfo> + <xs:documentation>Datentypen enthält spezifische Datentypen, welche von Datentypen aus anderen Namensräumen (z.B. UN/CEFACT, W3C) abgeleitet wurden.</xs:documentation> + </xs:annotation> + <xs:import schemaLocation="http://xoev.de/schemata/code/1_0/xoev-code.xsd" + namespace="http://xoev.de/schemata/code/1_0"/> + <xs:complexType name="AllgemeineRueckmeldungCodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>AllgemeineRueckmeldung</nameLang> + <nameKurz>AllgemeineRueckmeldung</nameKurz> + <nameTechnisch>allgemeinerueckmeldung</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:allgemeinerueckmeldung</kennung> + <beschreibung>Die Werteliste der allgemeinen Rückmeldungen.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.1</version> + <datumGueltigkeitAb>2021-10-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von Rückmeldungen für Fachverfahrensnachrichten unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0000000"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Ausführung wurde erfolgreich beendet.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Das DMS ist im Rahmen der Kommunikation vom Fachverfahren in Richtung DMS nicht verfügbar oder antwortet nicht in angemessener Zeit (Time-out).</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Verbindungsabbruch im Rahmen der Kommunikation vom Fachverfahren in Richtung DMS.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Kennung ist dem DMS nicht bekannt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000004"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Dem Benutzer bzw. der Rolle fehlen die erforderlichen Rechte zum Aufruf der Nachricht im Rahmen der Kommunikation vom Fachverfahren in Richtung DMS.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000005"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die ID des Fachverfahrens ist im Rahmen der Kommunikation vom Fachverfahren in Richtung DMS unbekannt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000006"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die ID der Verwaltung ist im Rahmen der Kommunikation vom Fachverfahren in Richtung DMS unbekannt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000007"> + <xs:annotation> + <xs:appinfo> + <beschreibung>DMS-Session-ID ist im Rahmen der Kommunikation vom Fachverfahren in Richtung DMS ungültig bzw. nicht bekannt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000008"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die übergebene XML-Struktur entspricht im Rahmen der Kommunikation vom Fachverfahren in Richtung DMS nicht dem angegebenen Schema und ist nicht valide.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000009"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Nachricht ist im Rahmen der Kommunikation vom Fachverfahren in Richtung DMS bereits verarbeitet.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000010"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Stapellänge ist im Rahmen der Kommunikation vom Fachverfahren in Richtung DMS kleiner oder gleich 0.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000011"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Stapellänge ist im Rahmen der Kommunikation vom Fachverfahren in Richtung DMS größer als 1 und somit in der Dialogverarbeitung unzulässig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000012"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Stapellänge ist im Rahmen der Kommunikation vom Fachverfahren in Richtung DMS kleiner als 1 und somit in der Stapelverarbeitung unzulässig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000013"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Länge des Stapels stimmt im Rahmen der Kommunikation vom Fachverfahren in Richtung DMS nicht mit der Anzahl der Objekte im Stapel überein.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000014"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Stapel ist im Rahmen der Kommunikation vom Fachverfahren in Richtung DMS syntaktisch nicht korrekt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000015"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Übertragungsfehler im Rahmen der Kommunikation vom Fachverfahren in Richtung DMS.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000016"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Das Verzeichnis ist im Rahmen der Kommunikation vom Fachverfahren in Richtung DMS ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000017"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die URL ist im Rahmen der Kommunikation vom Fachverfahren in Richtung DMS ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000018"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Datei kann im Rahmen der Kommunikation vom Fachverfahren in Richtung DMS nicht gefunden werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000019"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Datenbanktabelle ist im Rahmen der Kommunikation vom Fachverfahren in Richtung DMS nicht zugreifbar.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000499"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Unbekannter Fehler im Rahmen der Kommunikation vom Fachverfahren in Richtung DMS.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000501"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Das Fachverfahren ist im Rahmen der Kommunikation vom DMS in Richtung Fachverfahren nicht verfügbar oder antwortet nicht in angemessener Zeit (Time-out).</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000502"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Verbindungsabbruch im Rahmen der Kommunikation vom DMS in Richtung Fachverfahren.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000503"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Kennung ist im Rahmen der Kommunikation vom DMS in Richtung Fachverfahren dem System nicht bekannt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000504"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Dem Benutzer fehlen im Rahmen der Kommunikation vom DMS in Richtung Fachverfahren die erforderlichen Rechte zum Aufruf der Nachricht.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000505"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die ID des Fachverfahrens ist im Rahmen der Kommunikation vom DMS in Richtung Fachverfahren nicht bekannt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000506"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die ID der Verwaltung ist im Rahmen der Kommunikation vom DMS in Richtung Fachverfahren nicht bekannt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000507"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die FV-Session-ID ist im Rahmen der Kommunikation vom DMS in Richtung Fachverfahren ungültig bzw. nicht bekannt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000508"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die übergebene XML-Struktur entspricht im Rahmen der Kommunikation vom DMS in Richtung Fachverfahren nicht dem angegebenen Schema und ist nicht valide.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000509"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Nachricht wurde im Rahmen der Kommunikation vom DMS in Richtung Fachverfahren bereits verarbeitet.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000510"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Stapellänge ist im Rahmen der Kommunikation vom DMS in Richtung Fachverfahren kleiner oder gleich 0.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000511"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Länge des Stapels stimmt im Rahmen der Kommunikation vom DMS in Richtung Fachverfahren nicht mit der Anzahl der Objekte im Stapel überein.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000512"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Stapel ist im Rahmen der Kommunikation vom DMS in Richtung Fachverfahren syntaktisch nicht korrekt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000513"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Übertragungsfehler im Rahmen der Kommunikation vom DMS in Richtung Fachverfahren.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000514"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Das Verzeichnis ist im Rahmen der Kommunikation vom DMS in Richtung Fachverfahren ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000515"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die URL ist im Rahmen der Kommunikation vom DMS in Richtung Fachverfahren ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000516"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Datei kann im Rahmen der Kommunikation vom DMS in Richtung Fachverfahren nicht gefunden werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0000999"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Unbekannter Fehler im Rahmen der Kommunikation vom DMS in Richtung Fachverfahren.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:allgemeinerueckmeldung"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.1"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="AnschriftstypCodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>Anschriftstyp</nameLang> + <nameKurz>Anschriftstyp</nameKurz> + <nameTechnisch>anschriftstyp</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:anschriftstyp</kennung> + <beschreibung>Die Werteliste der Anschriftentypen.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von Anschriftentypen unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Aktuelle Anschrift: Die aktuelle Anschrift, z.B. einer Organisation, einer Person.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Hauptsitz: Die Anschrift ist der Hauptsitz, z.B. einer Organisation, oder der Hauptwohnsitz einer Person.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Zweitsitz: Die Anschrift ist der Zweitsitz, z.B. einer Organisation, oder der Nebenwohnsitz einer Person.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:anschriftstyp"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="AussonderungsartCodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>Aussonderungsart</nameLang> + <nameKurz>Aussonderungsart</nameKurz> + <nameTechnisch>aussonderungsart</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:aussonderungsart</kennung> + <beschreibung>Die Werteliste der Aussonderungsarten.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von Aussonderungsarten unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="A"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Das Schriftgutobjekt ist archivwürdig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="B"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Das Schriftgutobjekt ist zum Bewerten markiert.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="V"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Das Schriftgutobjekt ist zum Vernichten markiert.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:aussonderungsart"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="BeteiligungsstatusCodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>Beteiligungsstatus</nameLang> + <nameKurz>Beteiligungsstatus</nameKurz> + <nameTechnisch>beteiligungsstatus</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:beteiligungsstatus</kennung> + <beschreibung>Die Liste der Statuswerte eines Beteiligungsschrittes im Geschäftsgang.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.1</version> + <datumGueltigkeitAb>2021-10-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von Beteiligungsstatus unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes. Für die Umsetzung in den Systemen wird empfohlen, sofern kein anderer Wert hinterlegt wurde, als Standardwert den Wert 001 für "Der Schritt liegt in der Zukunft." anzugeben.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Schritt liegt in der Zukunft.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Schritt ist aktuell.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Schritt ist abgeschlossen.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="004"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Schritt wurde übersprungen, jedoch nicht aus dem Geschäftsgang gelöscht. Der Schritt wird im Verlauf des Geschäftsgangs nicht mehr angesprochen.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:beteiligungsstatus"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.1"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="BewertungsvorschlagCodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>Bewertungsvorschlag</nameLang> + <nameKurz>Bewertungsvorschlag</nameKurz> + <nameTechnisch>bewertungsvorschlag</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:bewertungsvorschlag</kennung> + <beschreibung>Die Werteliste der Bewertungsvorschläge.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von Bewertungsvorschlägen unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="A"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Das Schriftgutobjekt ist archivwürdig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="V"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Das Schriftgutobjekt ist zum Vernichten markiert.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:bewertungsvorschlag"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="DateiformatCodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>Dateiformat</nameLang> + <nameKurz>Dateiformat</nameKurz> + <nameTechnisch>dateiformat</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:dateiformat</kennung> + <beschreibung>Die Werteliste der gängigen Dateiformate. Für sonstige Formate existiert der Wert "Sonstiges". Die Angaben stammen größtenteils aus der internationalen Formatdatenbank PRONOM (http://www.nationalarchives.gov.uk/pronom/).</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von Dateiformaten unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" type="xs:token" form="unqualified"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:dateiformat"/> + <xs:attribute name="listVersionID" type="xs:normalizedString" use="required"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="DatenaustauschartCodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>Datenaustauschart</nameLang> + <nameKurz>Datenaustauschart</nameKurz> + <nameTechnisch>datenaustauschart</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:datenaustauschart</kennung> + <beschreibung>Die Werteliste der Datenaustauscharten.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.1</version> + <datumGueltigkeitAb>2021-10-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von Datenaustauscharten unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Freigegebenes Verzeichnis</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Datenbanktabelle</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>WebDAV und http(s)</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:datenaustauschart"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.1"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="DatentypCodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>Datentyp</nameLang> + <nameKurz>Datentyp</nameKurz> + <nameTechnisch>datentyp</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:datentyp</kennung> + <beschreibung>Die Werteliste der W3C-Datentypen (http://www.w3.org/TR/xmlschema-2, W3C Recommendation 28 October 2004) ergänzt um anySimpleType als Metadatentyp.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.1</version> + <datumGueltigkeitAb>2021-10-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von Datentypen unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>anyURI</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>base64Binary</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>boolean</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="004"> + <xs:annotation> + <xs:appinfo> + <beschreibung>byte</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="005"> + <xs:annotation> + <xs:appinfo> + <beschreibung>date</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="006"> + <xs:annotation> + <xs:appinfo> + <beschreibung>dateTime</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="007"> + <xs:annotation> + <xs:appinfo> + <beschreibung>decimal</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="008"> + <xs:annotation> + <xs:appinfo> + <beschreibung>double</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="009"> + <xs:annotation> + <xs:appinfo> + <beschreibung>duration</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="010"> + <xs:annotation> + <xs:appinfo> + <beschreibung>ENTITIES</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="011"> + <xs:annotation> + <xs:appinfo> + <beschreibung>ENTITY</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="012"> + <xs:annotation> + <xs:appinfo> + <beschreibung>float</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="013"> + <xs:annotation> + <xs:appinfo> + <beschreibung>gDay</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="014"> + <xs:annotation> + <xs:appinfo> + <beschreibung>gMonth</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="015"> + <xs:annotation> + <xs:appinfo> + <beschreibung>gMonthDay</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="016"> + <xs:annotation> + <xs:appinfo> + <beschreibung>gYear</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="017"> + <xs:annotation> + <xs:appinfo> + <beschreibung>gYearMonth</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="018"> + <xs:annotation> + <xs:appinfo> + <beschreibung>hexBinary</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="019"> + <xs:annotation> + <xs:appinfo> + <beschreibung>ID</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="020"> + <xs:annotation> + <xs:appinfo> + <beschreibung>IDREF</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="021"> + <xs:annotation> + <xs:appinfo> + <beschreibung>IDREFS</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="022"> + <xs:annotation> + <xs:appinfo> + <beschreibung>int</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="023"> + <xs:annotation> + <xs:appinfo> + <beschreibung>integer</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="024"> + <xs:annotation> + <xs:appinfo> + <beschreibung>language</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="025"> + <xs:annotation> + <xs:appinfo> + <beschreibung>long</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="026"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Name</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="027"> + <xs:annotation> + <xs:appinfo> + <beschreibung>NCNAME</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="028"> + <xs:annotation> + <xs:appinfo> + <beschreibung>negativeInteger</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="029"> + <xs:annotation> + <xs:appinfo> + <beschreibung>NMTOKEN</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="030"> + <xs:annotation> + <xs:appinfo> + <beschreibung>NMTOKENS</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="031"> + <xs:annotation> + <xs:appinfo> + <beschreibung>nonNegativeInteger</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="032"> + <xs:annotation> + <xs:appinfo> + <beschreibung>nonPositiveInteger</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="033"> + <xs:annotation> + <xs:appinfo> + <beschreibung>normalizedString</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="034"> + <xs:annotation> + <xs:appinfo> + <beschreibung>NOTATION</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="035"> + <xs:annotation> + <xs:appinfo> + <beschreibung>positiveInteger</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="036"> + <xs:annotation> + <xs:appinfo> + <beschreibung>QName</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="037"> + <xs:annotation> + <xs:appinfo> + <beschreibung>short</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="038"> + <xs:annotation> + <xs:appinfo> + <beschreibung>string</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="039"> + <xs:annotation> + <xs:appinfo> + <beschreibung>time</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="040"> + <xs:annotation> + <xs:appinfo> + <beschreibung>token</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="041"> + <xs:annotation> + <xs:appinfo> + <beschreibung>unsignedByte</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="042"> + <xs:annotation> + <xs:appinfo> + <beschreibung>unsignedInt</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="043"> + <xs:annotation> + <xs:appinfo> + <beschreibung>unsignedLong</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="044"> + <xs:annotation> + <xs:appinfo> + <beschreibung>unsignedShort</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="045"> + <xs:annotation> + <xs:appinfo> + <beschreibung>anySimpleType</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:datentyp"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.1"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="KommunikationsartCodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>Kommunikationskanal / Erreichbarkeit</nameLang> + <nameKurz>Erreichbarkeit</nameKurz> + <nameTechnisch>erreichbarkeit</nameTechnisch> + <kennung>urn:de:xoev:codeliste:erreichbarkeit</kennung> + <beschreibung>Eine Liste der Kommunikationsmedien und -kanäle, über die man eine Person oder Institution erreichen kann.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>KoSIT</herausgebernameKurz> + </codeliste> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von Kommunikationsarten unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" type="xs:token" form="unqualified"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:de:xoev:codeliste:erreichbarkeit"/> + <xs:attribute name="listVersionID" type="xs:normalizedString" use="required"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="KompressionsverfahrenCodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>Kompressionsverfahren</nameLang> + <nameKurz>Kompressionsverfahren</nameKurz> + <nameTechnisch>kompressionsverfahren</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:kompressionsverfahren</kennung> + <beschreibung>Die Werteliste der Kompressionsverfahren.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von Kompressionsverfahren unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>ZIP v2.0</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Gnu ZIP (GZIP) v4.3 / Tape ARchive (TAR)</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:kompressionsverfahren"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="KonfigurationsparameterCodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>Konfigurationsparameter</nameLang> + <nameKurz>Konfigurationsparameter</nameKurz> + <nameTechnisch>konfigurationsparameter</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:konfigurationsparameter</kennung> + <beschreibung>Die Werteliste der Konfigurationsparameter.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.1</version> + <datumGueltigkeitAb>2021-10-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von Konfigurationsparametern unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="001001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Transportweg</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="002001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Datenaustauschart</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="003001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Ablageort</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="004001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>LDAP_Name</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="004002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>LDAP_Hostname</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="004003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>LDAP_Port</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="004004"> + <xs:annotation> + <xs:appinfo> + <beschreibung>LDAP_Bind_DN</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="004005"> + <xs:annotation> + <xs:appinfo> + <beschreibung>LDAP_Password</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="004006"> + <xs:annotation> + <xs:appinfo> + <beschreibung>LDAP_Base_DN</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="004007"> + <xs:annotation> + <xs:appinfo> + <beschreibung>LDAP_Searchfilter</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="004008"> + <xs:annotation> + <xs:appinfo> + <beschreibung>LDAP_MaxResult</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="005001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>SQL_Name</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="005002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>SQL_Hostname</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="005003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>SQL_Datenbank</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="005004"> + <xs:annotation> + <xs:appinfo> + <beschreibung>SQL_Tabelle</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="005005"> + <xs:annotation> + <xs:appinfo> + <beschreibung>SQL_Benutzername</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="005006"> + <xs:annotation> + <xs:appinfo> + <beschreibung>SQL_Passwort</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="005007"> + <xs:annotation> + <xs:appinfo> + <beschreibung>SQL_Query</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="006001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>ADDR_Name</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="006002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>ADDR_ATTR1</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="006003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>ADDR_ATTR2</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="006004"> + <xs:annotation> + <xs:appinfo> + <beschreibung>ADDR_ATTR3</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="006005"> + <xs:annotation> + <xs:appinfo> + <beschreibung>ADDR_ATTR4</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="006006"> + <xs:annotation> + <xs:appinfo> + <beschreibung>ADDR_ATTR5</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="006007"> + <xs:annotation> + <xs:appinfo> + <beschreibung>ADDR_ATTR6</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="006008"> + <xs:annotation> + <xs:appinfo> + <beschreibung>ADDR_ATTR7</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="006009"> + <xs:annotation> + <xs:appinfo> + <beschreibung>ADDR_ATTR8</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="006010"> + <xs:annotation> + <xs:appinfo> + <beschreibung>ADDR_ATTR9</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="006011"> + <xs:annotation> + <xs:appinfo> + <beschreibung>ADDR_ATTR10</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="007001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Standardablage</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="008001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Komprimierter Datenaustausch</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="008002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Kompressionsverfahren</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:konfigurationsparameter"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.1"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="KonfigurationsparameterGruppeCodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>KonfigurationsparameterGruppe</nameLang> + <nameKurz>KonfigurationsparameterGruppe</nameKurz> + <nameTechnisch>konfigurationsparametergruppe</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:konfigurationsparametergruppe</kennung> + <beschreibung>Die Werteliste der Konfigurationsparametergruppen.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.1</version> + <datumGueltigkeitAb>2021-10-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von Konfigurationsparametergruppen unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Transportweg</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Datenaustauschart</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Ablageort</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="004"> + <xs:annotation> + <xs:appinfo> + <beschreibung>LDAP-Adressverzeichnis</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="005"> + <xs:annotation> + <xs:appinfo> + <beschreibung>SQL-Server-Adressverzeichnis</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="006"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Unbekanntes Adressverzeichnis</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="007"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Standardablage</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="008"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Komprimierter Datenaustausch</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:konfigurationsparametergruppe"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.1"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="MediumCodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>Medium</nameLang> + <nameKurz>Medium</nameKurz> + <nameTechnisch>medium</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:medium</kennung> + <beschreibung>Die Werteliste der Medienarten.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von Medientypen unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Elektronisch: Das Schriftgutobjekt liegt ausschließlich in elektronischer Form vor.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Hybrid: Das Schriftgutobjekt liegt teilweise in elektronischer Form und teilweise als Papier vor.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Papier: Das Schriftgutobjekt liegt ausschließlich als Papier vor.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:medium"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="NachrichtentypCodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>Nachrichtentyp</nameLang> + <nameKurz>Nachrichtentyp</nameKurz> + <nameTechnisch>nachrichtentyp</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:nachrichtentyp</kennung> + <beschreibung>Die Werteliste der Nachrichtentypen, die den Namen der jeweiligen Nachricht angeben. Der Schlüssel wird entsprechend folgender Regel gebildet: Die ersten zwei Zeichen geben die Nachrichtengruppe an, zu der der Nachrichtentyp gehört, z.B. 01 für "Information". Die letzten zwei Zeichen ergeben die fortlaufende Nummerierung der Nachrichtentypen in einer Nachrichtengruppe.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>2.0</version> + <datumGueltigkeitAb>2021-10-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von Nachrichtentypen unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0101"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Information.Information</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0102"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Information.EmpfangBestaetigen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0201"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Geschaeftsgang.Geschaeftsgang</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0202"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Geschaeftsgang.EmpfangBestaetigen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0301"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Aktenplan.Aktenplan</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0302"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Aktenplan.EmpfangBestaetigen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0401"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Abgabe.Abgabe</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0402"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Abgabe.ImportBestaetigen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0403"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Abgabe.EmpfangBestaetigen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0501"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Aussonderung.Anbieteverzeichnis</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0502"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Aussonderung.Bewertungsverzeichnis</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0503"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Aussonderung.Aussonderung</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0504"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Aussonderung.AnbietungEmpfangBestaetigen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0505"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Aussonderung.BewertungEmpfangBestaetigen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0506"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Aussonderung.AussonderungImportBestaetigen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0507"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Aussonderung.AussonderungEmpfangBestaetigen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0511"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Aussonderung.AktenplanZurBewertung</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0512"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Aussonderung.AktenplanZurBewertungEmpfangBestaetigen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0513"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Aussonderung.Bewertungskatalog</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0514"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Aussonderung.BewertungskatalogImportBestaetigen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0515"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Aussonderung.BewerteterAktenplanEmpfangBestaetigen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0601"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.DokumentAktualisieren</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0602"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.SGOAnsehen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0603"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.SGOBearbeiten</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0604"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.SGOErstellen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0605"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.SGOAblegen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0606"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.SGODrucken</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0607"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.ProtokolleintragErstellen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0608"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.SGOSuchen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0609"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.MetadatenAnlegen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0610"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.MetadatenAktualisieren</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0611"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.MetadatenAnsehen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0612"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.MetadatenLoeschen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0613"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.SGOLoeschenMarkieren</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0614"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.SGOLoeschmarkierungAufheben</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0615"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.SGOEndgueltigLoeschen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0616"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.SGOLoeschstatusAbfragen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0617"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.SGOUngueltigKennzeichnen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0618"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.DatensatzLoeschen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0619"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.BenachrichtigungAbrufen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0620"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.VertretungAktivierenOderDeaktivieren</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0621"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.VertretungsstatusAbfragen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0622"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.ZustaendigkeitAendern</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0623"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.GesamtprotokollAblegen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0624"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.SGOZDAVerfuegen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0625"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.SystemstatusAbfragen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0626"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.KonfigurationsparameterErstellen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0627"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.KonfigurationsparameterAktualisieren</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0628"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.KonfigurationsparameterAbrufen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0629"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.EmpfangBestaetigen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0630"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.ImportBestaetigen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0631"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.PrimaerdokumentExportieren</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0632"> + <xs:annotation> + <xs:appinfo> + <beschreibung>FVDaten.SGOZDAAufheben</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0701"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Zwischenarchivierung.Auslagerung</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0702"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Zwischenarchivierung.AuslagerungEmpfangBestaetigen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0703"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Zwischenarchivierung.AuslagerungImportBestaetigen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0711"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Zwischenarchivierung. RueckleiheAnforderung</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0712"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Zwischenarchivierung. RueckleiheUebergabe</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0713"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Zwischenarchivierung.RueckleiheEmpfangBestaetigen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0721"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Zwischenarchivierung.RueckuebertragungAnforderung</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0722"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Zwischenarchivierung.RueckuebertragungUebergabe</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0723"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Zwischenarchivierung.RueckuebertragungImportBestaetigen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0724"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Zwischenarchivierung.RueckuebertragungEmpfangBestaetigen</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:nachrichtentyp"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="2.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SchriftgutobjekttypCodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>Schriftgutobjekttyp</nameLang> + <nameKurz>Schriftgutobjekttyp</nameKurz> + <nameTechnisch>schriftgutobjekttyp</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:schriftgutobjekttyp</kennung> + <beschreibung>Die Werteliste der Typen von Schriftgutobjekten.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von Schriftgutobjekttypen unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Akte</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Dokument</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Vorgang</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:schriftgutobjekttyp"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SonstigeFehlermeldungCodeType"> + <xs:annotation> + <xs:documentation>Der Datentyp zu sonstigen Fehlermeldungen aus einer Codeliste für die Importbestätigungen unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" type="xs:token" form="unqualified"/> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" type="xs:anyURI" use="required"/> + <xs:attribute name="listVersionID" type="xs:normalizedString" use="required"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0601CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0601.SpezifischeFehlermeldung</nameLang> + <nameKurz>0601.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0601</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0601</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0601.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0601 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0601001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die ID des Dokuments im DMS ist unbekannt/ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0601002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Das Verzeichnis ist ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0601003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die URL ist ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0601004"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Datei kann nicht gefunden werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0601005"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Es kann keine neue Version erstellt werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0601006"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Name eines Metadatums enthält ungültige Zeichen.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0601007"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Wert eines Metadatums enthält ungültige Zeichen.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0601"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0602CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0602.SpezifischeFehlermeldung</nameLang> + <nameKurz>0602.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0602</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0602</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0602.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0602 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0602001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die ID des Dokuments ist unbekannt/ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0602002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Das Dokument kann nicht geöffnet werden (bspw. ist zum Dokumenttyp keine Applikation registriert oder der Server hat keinen Zugriff auf den Client).</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0602003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Versionsnummer ist ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0602"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0603CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0603.SpezifischeFehlermeldung</nameLang> + <nameKurz>0603.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0603</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0603</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0603.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0603 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0603001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die ID des Dokuments ist unbekannt/ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0603002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Das Dokument kann nicht geöffnet werden (bspw. ist zum Dokumenttyp keine Applikation registriert).</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0603003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Versionsnummer ist ungültig</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0603"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0604CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0604.SpezifischeFehlermeldung</nameLang> + <nameKurz>0604.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0604</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0604</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0604.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0604 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0604001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die ID des Containerobjekts ist unbekannt/ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0604002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Schriftgutobjekttyp ist nicht definiert.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0604003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Das Schriftgutobjekt kann nicht angelegt werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0604004"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Das Objekt kann nicht geöffnet werden (bspw. ist zum Dokumenttyp keine Applikation registriert).</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0604005"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Name eines Metadatums enthält ungültige Zeichen.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0604006"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Wert eines Metadatums enthält ungültige Zeichen.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0604007"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Beschreibung eines Metadatums enthält ungültige Zeichen.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0604"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0605CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0605.SpezifischeFehlermeldung</nameLang> + <nameKurz>0605.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0605</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0605</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0605.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0605 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0605001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die ID des Containers ist im DMS unbekannt/ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0605002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Das Verzeichnis ist ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0605003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die URL ist ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0605004"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Datei kann nicht gefunden werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0605005"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Datei kann im DMS nicht abgelegt werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0605006"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Name eines Metadatums enthält ungültige Zeichen.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0605007"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Wert eines Metadatums enthält ungültige Zeichen.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0605008"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Beschreibung eines Metadatums enthält ungültige Zeichen.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0605"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0606CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0606.SpezifischeFehlermeldung</nameLang> + <nameKurz>0606.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0606</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0606</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0606.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0606 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0606001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die ID des Objektes ist unbekannt/ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0606002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der angegebene Drucker existiert nicht.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0606003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der angegebene Drucker ist nicht bereit.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0606004"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Unterschriftgutobjekttyp existiert nicht.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0606005"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Druck ist fehlgeschlagen.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0606006"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Version des Dokuments existiert nicht.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0606"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0607CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0607.SpezifischeFehlermeldung</nameLang> + <nameKurz>0607.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0607</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0607</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0607.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0607 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0607001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die ID ist unbekannt/ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0607002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Protokolleintragsinformationen beinhalten ungültige Zeichen.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0607003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Protokolleintrag kann nicht angelegt werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0607"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0608CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0608.SpezifischeFehlermeldung</nameLang> + <nameKurz>0608.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0608</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0608</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0608.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0608 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0608001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Suchtyp ist unbekannt/ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0608"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0609CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0609.SpezifischeFehlermeldung</nameLang> + <nameKurz>0609.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0609</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0609</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0609.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0609 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0609001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die ID des Objektes ist unbekannt/ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0609002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Name des Metadatums ist ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0609003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Beschreibung des Metadatums ist ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0609004"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Datentyp des Metadatums existiert nicht.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0609005"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Wert des Metadatums ist ungültig/befindet sich außerhalb des Wertebereichs.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0609006"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Das Metadatum kann nicht angelegt werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0609007"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Datentyp für das Metadatum wurde nicht angegeben.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0609008"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Wert für das Metadatum wurde nicht angegeben.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0609"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0610CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0610.SpezifischeFehlermeldung</nameLang> + <nameKurz>0610.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0610</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0610</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0610.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0610 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0610001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die ID des Objektes ist unbekannt/ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0610002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Name des Metadatums ist ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0610003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Beschreibung des Metadatums ist ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0610004"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Wert des Metadatums ist ungültig/befindet sich außerhalb des Wertebereichs.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0610005"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Das Metadatum kann nicht aktualisiert werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0610006"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Datentyp des Metadatums weicht vom vorhandenen Datentyp ab.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0610007"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Wert des Metadatums wurde nicht gesetzt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0610"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0611CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0611.SpezifischeFehlermeldung</nameLang> + <nameKurz>0611.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0611</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0611</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0611.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.1</version> + <datumGueltigkeitAb>2021-10-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0611 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0611001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die UUID des Objektes ist ungültig/unbekannt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0611002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Name des Metadatums ist ungültig/unbekannt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0611003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Das Metadatum kann nicht ausgelesen werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0611004"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Beschreibung des Metadatums weicht von der vorhandenen Beschreibung ab.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0611005"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Datentyp des Metadatums weicht von dem vorhandenen Datentyp ab.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0611006"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Wert des Metadatums weicht von dem vorhandenen Wert ab.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0611"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.1"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0612CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0612.SpezifischeFehlermeldung</nameLang> + <nameKurz>0612.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0612</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0612</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0612.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0612 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0612001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die ID des Objektes ist ungültig/unbekannt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0612002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Name des Metadatums ist ungültig/unbekannt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0612003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Das Metadatum kann nicht gelöscht werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0612004"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Beschreibung des Metadatums unterscheidet sich von der vorhandenen: Metadatum nicht gelöscht.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0612005"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Datentyp des Metadatums unterscheidet sich von dem vorhandenen: Metadatum nicht gelöscht.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0612006"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Wert des Metadatums unterscheidet sich von dem vorhandenen: Metadatum nicht gelöscht.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0612"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0613CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0613.SpezifischeFehlermeldung</nameLang> + <nameKurz>0613.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0613</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0613</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0613.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0613 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0613001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die ID des Schriftgutobjektes ist unbekannt/ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0613002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Das Schriftgutobjekt kann nicht zum Löschen markiert werden (z. B. weil es zur Bearbeitung gesperrt ist).</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0613"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0614CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0614.SpezifischeFehlermeldung</nameLang> + <nameKurz>0614.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0614</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0614</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0614.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0614 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0614001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die ID des Schriftgutobjektes ist unbekannt/ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0614002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Das Schriftgutobjekt ist nicht zum Löschen markiert.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0614003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Löschmarkierung kann nicht aufgehoben werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0614"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0615CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0615.SpezifischeFehlermeldung</nameLang> + <nameKurz>0615.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0615</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0615</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0615.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0615 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0615001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die ID des Schriftgutobjektes ist unbekannt/ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0615002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Das Schriftgutobjekt kann nicht gelöscht werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0615"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0616CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0616.SpezifischeFehlermeldung</nameLang> + <nameKurz>0616.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0616</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0616</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0616.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0616 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0616001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die ID des Schriftgutobjektes ist unbekannt/ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0616002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Status kann nicht abgefragt werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0616"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0617CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0617.SpezifischeFehlermeldung</nameLang> + <nameKurz>0617.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0617</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0617</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0617.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0617 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0617001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die ID des Objektes ist unbekannt/ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0617002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Das Schriftgutobjekt kann nicht als ungültig gekennzeichnet werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0617"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0618CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0618.SpezifischeFehlermeldung</nameLang> + <nameKurz>0618.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0618</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0618</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0618.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0618 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0618001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die ID des Datensatzes ist im DMS unbekannt/ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0618002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Mindestens ein Schriftgutobjekt kann nicht gelöscht werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0618"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0619CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0619.SpezifischeFehlermeldung</nameLang> + <nameKurz>0619.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0619</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0619</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0619.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0619 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0619001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Nachrichten können nicht abgefragt werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0619002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Keine Nachricht vorhanden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0619"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0620CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0620.SpezifischeFehlermeldung</nameLang> + <nameKurz>0620.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0620</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0620</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0620.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0620 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0620001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Benutzer/Rolle des zu Vertretenden ist unbekannt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0620002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Benutzer/Rolle des Vertreters ist unbekannt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0620003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Vertretung ist bereits aktiviert.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0620004"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Vertretung ist bereits deaktiviert.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0620005"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Vertretung kann nicht aktiviert werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0620006"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Vertretung kann nicht deaktiviert werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0620"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0621CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0621.SpezifischeFehlermeldung</nameLang> + <nameKurz>0621.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0621</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0621</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0621.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.1</version> + <datumGueltigkeitAb>2021-10-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0621 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0621001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Benutzer/Rolle, für den/die der Status abgefragt werden soll, ist unbekannt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0621002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Status kann nicht abgefragt werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0621"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.1"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0622CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0622.SpezifischeFehlermeldung</nameLang> + <nameKurz>0622.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0622</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0622</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0622.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0622 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0622001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>ID des Schriftgutobjektes nicht bekannt/ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0622002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Neu zuständiger/zuständige Benutzer/Rolle ist unbekannt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0622003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Bisher zuständiger/zuständige Benutzer/Rolle ist unbekannt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0622004"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Kennzeichen der aufnehmenden Aktenplaneinheit ist unbekannt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0622005"> + <xs:annotation> + <xs:appinfo> + <beschreibung>ID der aufnehmenden Akte ist unbekannt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0622006"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Kennzeichen der abgebenden Aktenplaneinheit ist unbekannt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0622007"> + <xs:annotation> + <xs:appinfo> + <beschreibung>ID der abgebenden Akte ist unbekannt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0622008"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Name eines Metadatums enthält ungültige Zeichen.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0622009"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Beschreibung des Metadatums enthält ungültige Zeichen.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0622010"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Wert eines Metadatums enthält ungültige Zeichen.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0622011"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Zuständigkeitswechsel kann nicht durchgeführt werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0622"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0623CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0623.SpezifischeFehlermeldung</nameLang> + <nameKurz>0623.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0623</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0623</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0623.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.1</version> + <datumGueltigkeitAb>2021-10-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0623 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0623001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die ID des Schriftgutobjektes ist unbekannt/ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0623002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Das Verzeichnis ist ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0623003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die URL ist ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0623004"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Protokoll als Datei kann nicht abgelegt werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0623005"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Protokoll als xdomea-Geschäftsgang kann nicht abgelegt werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0623006"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Syntaxfehler in xdomea-Geschäftsgang-Daten.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0623007"> + <xs:annotation> + <xs:appinfo> + <beschreibung>HistorienProtokollinformationen konnten nicht angelegt werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0623"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.1"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0624CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0624.SpezifischeFehlermeldung</nameLang> + <nameKurz>0624.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0624</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0624</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0624.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0624 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0624001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>ID des Schriftgutobjektes nicht bekannt/ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0624002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die zdA-Verfügung kann nicht durchgeführt werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0624"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0625CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0625.SpezifischeFehlermeldung</nameLang> + <nameKurz>0625.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0625</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0625</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0625.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0625 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0625001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Systemstatus-ID ist unbekannt/ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0625002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Status kann nicht abgefragt werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0625"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0626CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0626.SpezifischeFehlermeldung</nameLang> + <nameKurz>0626.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0626</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0626</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0626.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0626 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0626001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Name des Konfigurationsparameters ist ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0626002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Wert des Konfigurationsparameters ist ungültig/liegt außerhalb des definierten Wertebereichs.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0626003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Datentyp ist unbekannt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0626"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0627CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0627.SpezifischeFehlermeldung</nameLang> + <nameKurz>0627.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0627</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0627</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0627.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0627 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0627001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Name des Konfigurationsparameters ist ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0627002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Wert des Konfigurationsparameters ist ungültig/liegt außerhalb des definierten Wertebereichs.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0627003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Konfigurationsparameter kann nicht aktualisiert werden (bspw. wegen fehlender Rechte).</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0627004"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Typ des Konfigurationsparameters entspricht nicht dem aktuellen Typ des Konfigurationsparameters.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0627"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0628CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0628.SpezifischeFehlermeldung</nameLang> + <nameKurz>0628.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0628</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0628</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0628.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0628 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0628001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Name des Konfigurationsparameters ist ungültig/unbekannt.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0628002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Der Konfigurationsparameter kann nicht ausgelesen werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0628"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0631CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0631.SpezifischeFehlermeldung</nameLang> + <nameKurz>0631.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0631</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0631</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0631.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0631 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0631001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die ID des Dokuments ist unbekannt/ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0631002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die Versionsnummer ist ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0631"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SpezifischeFehlermeldung0632CodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>0632.SpezifischeFehlermeldung</nameLang> + <nameKurz>0632.SpezifischeFehlermeldung</nameKurz> + <nameTechnisch>spezifischefehlermeldung0632</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0632</kennung> + <beschreibung>Die Werteliste der spezifischen Rückmeldungen zur Nachricht 0632.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.1</version> + <datumGueltigkeitAb>2021-10-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von spezifischen Fehlermeldungen für die Nachricht 0632 unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="0632001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die ID des Schriftgutobjektes ist nicht bekannt/ungültig.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="0632002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Die zdA-Verfügung kann nicht aufgehoben werden.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:spezifischefehlermeldung0632"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.1"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="StaatCodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>Country Codes</nameLang> + <nameKurz>Country Codes</nameKurz> + <nameTechnisch>Country-Codes</nameTechnisch> + <kennung>urn:xoev-de:kosit:codeliste:country-codes</kennung> + <beschreibung>Die Codeliste basiert auf der Staats- und Gebietssystematik des Statistischen Bundesamtes (DESTATIS) und dem Standard "Country codes" der International Organization for Standardization (ISO). Die vorliegende Liste enthält alle "officially assigned codes" (Alpha-2 und Numerisch) der ISO-Liste. Kurz- und Langnamen der aufgeführten Einträge wurden, sofern vorhanden, der DESTATIS-Liste entnommen. Zu den nicht in der DESTATIS-Liste geführten Codeeinträgen wurden die zugehörigen Namen der Deutschen Fassung der Norm entnommen.</beschreibung> + <herausgebernameLang>Koordinierungsstelle für IT-Standards</herausgebernameLang> + <herausgebernameKurz>KoSIT</herausgebernameKurz> + </codeliste> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von Staaten unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes. Genutzt wird hier die ISO-3166-1-Liste. Für den Schlüssel (code) wird die Spalte "ALPHA2" und für den beschreibenden Namen (name) die Spalte "Name des Landes" verwendet.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" type="xs:token" form="unqualified"/> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:kosit:codeliste:country-codes"/> + <xs:attribute name="listVersionID" type="xs:normalizedString" use="required"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="TransportwegCodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>Transportweg</nameLang> + <nameKurz>Transportweg</nameKurz> + <nameTechnisch>transportweg</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:transportweg</kennung> + <beschreibung>Die Werteliste der Transportwege.</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von Transportwegen unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Web Service</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Austauschverzeichnis</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Austauschdatenbank</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:transportweg"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="VertraulichkeitsstufeCodeType"> + <xs:annotation> + <xs:appinfo> + <codeliste> + <nameLang>Vertraulichkeitsstufe</nameLang> + <nameKurz>Vertraulichkeitsstufe</nameKurz> + <nameTechnisch>vertraulichkeitsstufe</nameTechnisch> + <kennung>urn:xoev-de:xdomea:codeliste:vertraulichkeitsstufe</kennung> + <beschreibung>Die Werteliste der Vertraulichkeitsstufen von Schriftgutobjekten nach Verschlusssachenanweisungen des Bundes und der Länder (VSA).</beschreibung> + <herausgebernameLang>AG xdomea des IT-Planungsrates</herausgebernameLang> + <herausgebernameKurz>ag-xdomea</herausgebernameKurz> + </codeliste> + <versionCodeliste> + <version>1.0</version> + <datumGueltigkeitAb>2016-01-01</datumGueltigkeitAb> + <versionCodelistenHandbuch>1.1</versionCodelistenHandbuch> + </versionCodeliste> + <codelistenspalten> + <code> + <spaltennameLang>Code</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>true</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>true</empfohleneCodeSpalte> + </code> + <beschreibung> + <spaltennameLang>Beschreibung</spaltennameLang> + <datentyp>string</datentyp> + <codeSpalte>false</codeSpalte> + <verwendung>required</verwendung> + <empfohleneCodeSpalte>false</empfohleneCodeSpalte> + </beschreibung> + </codelistenspalten> + <genutzteCodeSpalte>code</genutzteCodeSpalte> + </xs:appinfo> + <xs:documentation>Der Datentyp zur Werteliste von Vertraulichkeitsstufen unter Angabe weiterer Informationen zur konkreten Angabe eines Wertes.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xoev-code:Code"> + <xs:sequence> + <xs:element name="code" form="unqualified"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="001"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Geheim: Das Schriftgutobjekt ist als geheim eingestuft.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="002"> + <xs:annotation> + <xs:appinfo> + <beschreibung>NfD: Das Schriftgutobjekt ist als "nur für den Dienstgebrauch (nfD)" eingestuft.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="003"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Offen: Das Schriftgutobjekt ist nicht eingestuft.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="004"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Streng geheim: Das Schriftgutobjekt ist als streng geheim eingestuft.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="005"> + <xs:annotation> + <xs:appinfo> + <beschreibung>Vertraulich: Das Schriftgutobjekt ist als vertraulich eingestuft.</beschreibung> + </xs:appinfo> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:element> + <xs:element name="name" + type="xs:normalizedString" + form="unqualified" + minOccurs="0"/> + </xs:sequence> + <xs:attribute name="listURI" + type="xs:anyURI" + use="optional" + fixed="urn:xoev-de:xdomea:codeliste:vertraulichkeitsstufe"/> + <xs:attribute name="listVersionID" + type="xs:normalizedString" + use="optional" + fixed="1.0"/> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:simpleType name="stringDateinameType"> + <xs:annotation> + <xs:documentation>Der Datentyp zur Angabe eines Dateinamens.</xs:documentation> + </xs:annotation> + <xs:restriction base="xs:string"> + <xs:pattern value="[0-9|A-F|a-f]{8}-[0-9|A-F|a-f]{4}-[0-9|A-F|a-f]{4}-[0-9|A-F|a-f]{4}-[0-9|A-F|a-f]{12}[_]?.*[\.]?.*"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="stringUUIDType"> + <xs:annotation> + <xs:documentation>Der Datentyp zur Angabe einer UUID.</xs:documentation> + </xs:annotation> + <xs:restriction base="xs:string"> + <xs:pattern value="[0-9|A-F|a-f]{8}-[0-9|A-F|a-f]{4}-[0-9|A-F|a-f]{4}-[0-9|A-F|a-f]{4}-[0-9|A-F|a-f]{12}"/> + </xs:restriction> + </xs:simpleType> +</xs:schema> diff --git a/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-AbgabeDurchfuehren.xsd b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-AbgabeDurchfuehren.xsd new file mode 100644 index 0000000000000000000000000000000000000000..51499776bfdabc173a9e6dfea2096b3d267b25dc --- /dev/null +++ b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-AbgabeDurchfuehren.xsd @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xdomea="urn:xoev-de:xdomea:schema:3.0.0" + targetNamespace="urn:xoev-de:xdomea:schema:3.0.0" + version="3.0.0" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> + <xs:annotation> + <xs:appinfo> + <standard> + <nameLang>xdomea - XÖV-Standard für den IT-gestützten Austausch und die IT-gestützte Aussonderung behördlichen Schriftgutes</nameLang> + <nameKurz>xdomea</nameKurz> + <nameTechnisch>xdomea</nameTechnisch> + <kennung>urn:xoev-de:xdomea:kosit:standard:xdomea</kennung> + <beschreibung>xdomea ist der vom IT-Planungsrat verabschiedete verbindliche Standard für den Austausch von Akten, Vorgängen und Dokumenten im Kontext der Übermittlung, der Abgabe sowie der Aussonderung von Schriftgutobjekten (www.it-planungsrat.de, Beschluss 2017/39). Weiterhin kann xdomea für den Austausch zwischen Fachverfahren und DMS/VBS sowie für die Zwischenarchivierung genutzt werden. + +Um diese Anwendungsszenarien bestmöglich zu unterstützen, ist xdomea gemäß des XÖV-Rahmenwerkes nach dem Baukastenprinzip aufgebaut und bietet einzelne Nachrichten(gruppen) für die jeweiligen Prozesse an. + +Der Standard xdomea wird von der gleichnamigen Arbeitsgruppe des IT-Planungsrates weiterentwickelt und gepflegt. Der Betrieb des Standards erfolgt durch die Koordinierungsstelle für IT-Standards (KoSIT). +</beschreibung> + </standard> + <versionStandard> + <version>3.0.0</version> + <beschreibung>Die Version 3.0.0 ist durch den IT-Planungsrat beschlossen. Details zum Beschluss sowie zu den Fristen der Umsetzung sind der Veröffentlichung im Bundesanzeiger unter www.bundesanzeiger.de zu entnehmen.</beschreibung> + <versionXOEVProfil>1.7.2</versionXOEVProfil> + <versionXOEVHandbuch>2.3.1</versionXOEVHandbuch> + <versionXGenerator>3.0.1</versionXGenerator> + <versionModellierungswerkzeug>19.0</versionModellierungswerkzeug> + <nameModellierungswerkzeug>MagicDraw</nameModellierungswerkzeug> + </versionStandard> + <title>Abgabe durchführen</title> + </xs:appinfo> + </xs:annotation> + <xs:include schemaLocation="xdomea-Baukasten.xsd"/> + <xs:include schemaLocation="xdomea-Typen-AbgabeDurchfuehren.xsd"/> + <xs:element name="Abgabe.Abgabe.0401"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt den vollständigen Export von Schriftgutobjekten bei Zuständigkeitswechseln zwischen Behörden oder bei Systemwechseln.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkAbgabeType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Abgabe-Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Anschreiben" minOccurs="0" type="xdomea:DokumentType"> + <xs:annotation> + <xs:documentation>Ein Dokument, das dem Empfänger zur Erläuterung der Abgabe mitgegeben wird.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Schriftgutobjekt" maxOccurs="unbounded"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Bei der Abgabe müssen zu einem Schriftgutobjekt alle prozess- und aktenrelevanten Metadaten übergeben werden. Die Fristen und die Aussonderungsart werden bei der Abgabe zu einem Schriftgutobjekt mit übergeben. Die aufnehmende Behörde kann entscheiden, ob diese Informationen dann in das eigene System übernommen werden oder nicht.</implementationHint> + </xs:appinfo> + <xs:documentation>Ein Schriftgutobjekt (Akte, Vorgang oder Dokument) zu einer Abgabe.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:choice> + <xs:element name="Akte" type="xdomea:AkteType"> + <xs:annotation> + <xs:documentation>Eine Akte.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Vorgang" type="xdomea:VorgangType"> + <xs:annotation> + <xs:documentation>Ein Vorgang.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Dokument" type="xdomea:DokumentType"> + <xs:annotation> + <xs:documentation>Ein Dokument.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:choice> + </xs:complexType> + </xs:element> + <xs:element name="Aktenplan" minOccurs="0" type="xdomea:AktenplanType"> + <xs:annotation> + <xs:documentation>Der Aktenplan zu einer Abgabe enthält ein aufgabenbezogenes mehrstufiges Ordnungssystem mit einer hierarchischer Gliederung für das Bilden und Kennzeichnen von Akten und Vorgängen sowie das Zuordnen von Dokumenten.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Abgabe.ImportBestaetigen.0402"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die erfolgreiche oder nicht erfolgreiche Übernahme der Abgabe.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkBasisType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Importnachricht zu einer Abgabe.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="AbgegebenesObjekt" + maxOccurs="unbounded" + type="xdomea:ErfolgOderMisserfolgAbgabeType"> + <xs:annotation> + <xs:documentation>Die Information zum erfolgreichen oder nicht erfolgreichen Import eines Schriftgutobjekts zur Abgabe.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Abgabe.EmpfangBestaetigen.0403"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt den erfolgreichen Empfang der Abgabe.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkBasisType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Empfangsbestätigung.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> +</xs:schema> diff --git a/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-AktenplanAustauschen.xsd b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-AktenplanAustauschen.xsd new file mode 100644 index 0000000000000000000000000000000000000000..2b96a4c682119014aed547820d17e2c842d5ce76 --- /dev/null +++ b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-AktenplanAustauschen.xsd @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xdomea="urn:xoev-de:xdomea:schema:3.0.0" + targetNamespace="urn:xoev-de:xdomea:schema:3.0.0" + version="3.0.0" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> + <xs:annotation> + <xs:appinfo> + <standard> + <nameLang>xdomea - XÖV-Standard für den IT-gestützten Austausch und die IT-gestützte Aussonderung behördlichen Schriftgutes</nameLang> + <nameKurz>xdomea</nameKurz> + <nameTechnisch>xdomea</nameTechnisch> + <kennung>urn:xoev-de:xdomea:kosit:standard:xdomea</kennung> + <beschreibung>xdomea ist der vom IT-Planungsrat verabschiedete verbindliche Standard für den Austausch von Akten, Vorgängen und Dokumenten im Kontext der Übermittlung, der Abgabe sowie der Aussonderung von Schriftgutobjekten (www.it-planungsrat.de, Beschluss 2017/39). Weiterhin kann xdomea für den Austausch zwischen Fachverfahren und DMS/VBS sowie für die Zwischenarchivierung genutzt werden. + +Um diese Anwendungsszenarien bestmöglich zu unterstützen, ist xdomea gemäß des XÖV-Rahmenwerkes nach dem Baukastenprinzip aufgebaut und bietet einzelne Nachrichten(gruppen) für die jeweiligen Prozesse an. + +Der Standard xdomea wird von der gleichnamigen Arbeitsgruppe des IT-Planungsrates weiterentwickelt und gepflegt. Der Betrieb des Standards erfolgt durch die Koordinierungsstelle für IT-Standards (KoSIT). +</beschreibung> + </standard> + <versionStandard> + <version>3.0.0</version> + <beschreibung>Die Version 3.0.0 ist durch den IT-Planungsrat beschlossen. Details zum Beschluss sowie zu den Fristen der Umsetzung sind der Veröffentlichung im Bundesanzeiger unter www.bundesanzeiger.de zu entnehmen.</beschreibung> + <versionXOEVProfil>1.7.2</versionXOEVProfil> + <versionXOEVHandbuch>2.3.1</versionXOEVHandbuch> + <versionXGenerator>3.0.1</versionXGenerator> + <versionModellierungswerkzeug>19.0</versionModellierungswerkzeug> + <nameModellierungswerkzeug>MagicDraw</nameModellierungswerkzeug> + </versionStandard> + <title>Aktenplan austauschen</title> + </xs:appinfo> + </xs:annotation> + <xs:include schemaLocation="xdomea-Baukasten.xsd"/> + <xs:element name="Aktenplan.Aktenplan.0301"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Die austauschenden Behörden müssen die für den Aktenplan erforderliche Konfiguration abstimmen, wenn dieser übernommen werden soll.</implementationHint> + </xs:appinfo> + <xs:documentation>Die Nachricht beschreibt den Export eines Aktenplans zur Information oder Übernahme in ein anderes System.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" + type="xdomea:NkNichtFVDatenWeitereEmpfaengerMitEmpfangsbestaetigungType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Aktenplan-Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Aktenplan" type="xdomea:AktenplanType"> + <xs:annotation> + <xs:documentation>Der zu übergebende Aktenplan enthält ein aufgabenbezogenes mehrstufiges Ordnungssystem mit hierarchischer Gliederung für das Bilden und Kennzeichnen von Akten und Vorgängen sowie das Zuordnen von Dokumenten.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Aktenplan.EmpfangBestaetigen.0302"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt den erfolgreichen Empfang des Aktenplans.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkBasisType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Empfangsbestätigung.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> +</xs:schema> diff --git a/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-Archivsystem.xsd b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-Archivsystem.xsd new file mode 100644 index 0000000000000000000000000000000000000000..08946f4b970c317144764fd67fda24ae4f2ed87b --- /dev/null +++ b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-Archivsystem.xsd @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xdomea="urn:xoev-de:xdomea:schema:3.0.0" + targetNamespace="urn:xoev-de:xdomea:schema:3.0.0" + version="3.0.0" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> + <xs:annotation> + <xs:appinfo> + <standard> + <nameLang>xdomea - XÖV-Standard für den IT-gestützten Austausch und die IT-gestützte Aussonderung behördlichen Schriftgutes</nameLang> + <nameKurz>xdomea</nameKurz> + <nameTechnisch>xdomea</nameTechnisch> + <kennung>urn:xoev-de:xdomea:kosit:standard:xdomea</kennung> + <beschreibung>xdomea ist der vom IT-Planungsrat verabschiedete verbindliche Standard für den Austausch von Akten, Vorgängen und Dokumenten im Kontext der Übermittlung, der Abgabe sowie der Aussonderung von Schriftgutobjekten (www.it-planungsrat.de, Beschluss 2017/39). Weiterhin kann xdomea für den Austausch zwischen Fachverfahren und DMS/VBS sowie für die Zwischenarchivierung genutzt werden. + +Um diese Anwendungsszenarien bestmöglich zu unterstützen, ist xdomea gemäß des XÖV-Rahmenwerkes nach dem Baukastenprinzip aufgebaut und bietet einzelne Nachrichten(gruppen) für die jeweiligen Prozesse an. + +Der Standard xdomea wird von der gleichnamigen Arbeitsgruppe des IT-Planungsrates weiterentwickelt und gepflegt. Der Betrieb des Standards erfolgt durch die Koordinierungsstelle für IT-Standards (KoSIT). +</beschreibung> + </standard> + <versionStandard> + <version>3.0.0</version> + <beschreibung>Die Version 3.0.0 ist durch den IT-Planungsrat beschlossen. Details zum Beschluss sowie zu den Fristen der Umsetzung sind der Veröffentlichung im Bundesanzeiger unter www.bundesanzeiger.de zu entnehmen.</beschreibung> + <versionXOEVProfil>1.7.2</versionXOEVProfil> + <versionXOEVHandbuch>2.3.1</versionXOEVHandbuch> + <versionXGenerator>3.0.1</versionXGenerator> + <versionModellierungswerkzeug>19.0</versionModellierungswerkzeug> + <nameModellierungswerkzeug>MagicDraw</nameModellierungswerkzeug> + </versionStandard> + </xs:appinfo> + </xs:annotation> + <xs:include schemaLocation="xdomea-Nachrichten-AktenplanAustauschen.xsd"/> + <xs:include schemaLocation="xdomea-Nachrichten-AussonderungDurchfuehren.xsd"/> +</xs:schema> diff --git a/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-AussonderungDurchfuehren.xsd b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-AussonderungDurchfuehren.xsd new file mode 100644 index 0000000000000000000000000000000000000000..1ed82d2216a97067129fd87ad4400b097bb95737 --- /dev/null +++ b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-AussonderungDurchfuehren.xsd @@ -0,0 +1,324 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xdomea="urn:xoev-de:xdomea:schema:3.0.0" + targetNamespace="urn:xoev-de:xdomea:schema:3.0.0" + version="3.0.0" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> + <xs:annotation> + <xs:appinfo> + <standard> + <nameLang>xdomea - XÖV-Standard für den IT-gestützten Austausch und die IT-gestützte Aussonderung behördlichen Schriftgutes</nameLang> + <nameKurz>xdomea</nameKurz> + <nameTechnisch>xdomea</nameTechnisch> + <kennung>urn:xoev-de:xdomea:kosit:standard:xdomea</kennung> + <beschreibung>xdomea ist der vom IT-Planungsrat verabschiedete verbindliche Standard für den Austausch von Akten, Vorgängen und Dokumenten im Kontext der Übermittlung, der Abgabe sowie der Aussonderung von Schriftgutobjekten (www.it-planungsrat.de, Beschluss 2017/39). Weiterhin kann xdomea für den Austausch zwischen Fachverfahren und DMS/VBS sowie für die Zwischenarchivierung genutzt werden. + +Um diese Anwendungsszenarien bestmöglich zu unterstützen, ist xdomea gemäß des XÖV-Rahmenwerkes nach dem Baukastenprinzip aufgebaut und bietet einzelne Nachrichten(gruppen) für die jeweiligen Prozesse an. + +Der Standard xdomea wird von der gleichnamigen Arbeitsgruppe des IT-Planungsrates weiterentwickelt und gepflegt. Der Betrieb des Standards erfolgt durch die Koordinierungsstelle für IT-Standards (KoSIT). +</beschreibung> + </standard> + <versionStandard> + <version>3.0.0</version> + <beschreibung>Die Version 3.0.0 ist durch den IT-Planungsrat beschlossen. Details zum Beschluss sowie zu den Fristen der Umsetzung sind der Veröffentlichung im Bundesanzeiger unter www.bundesanzeiger.de zu entnehmen.</beschreibung> + <versionXOEVProfil>1.7.2</versionXOEVProfil> + <versionXOEVHandbuch>2.3.1</versionXOEVHandbuch> + <versionXGenerator>3.0.1</versionXGenerator> + <versionModellierungswerkzeug>19.0</versionModellierungswerkzeug> + <nameModellierungswerkzeug>MagicDraw</nameModellierungswerkzeug> + </versionStandard> + <title>Aussonderung durchführen</title> + </xs:appinfo> + </xs:annotation> + <xs:include schemaLocation="xdomea-Baukasten.xsd"/> + <xs:include schemaLocation="xdomea-Typen-AussonderungDurchfuehren.xsd"/> + <xs:element name="Aussonderung.Anbieteverzeichnis.0501"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt den Export von Metadaten zu Schriftgutobjekten, die dem zuständigen Archiv angeboten werden sollen.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" + type="xdomea:NkNichtFVDatenEinEmpfaengerMitEmpfangsbestaetigungType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Anbieteverzeichnis-Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Anschreiben" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:DokumentType"> + <xs:annotation> + <xs:documentation>Ein Dokument, in dem allgemeine Informationen zu den anzubietenden Schriftgutobjekten an das Archiv mitgegeben werden. Hier können auch Formblätter (z.B. Vorblatt zur Abgabe) mitgegeben werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Schriftgutobjekt" maxOccurs="unbounded"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Es werden im Rahmen des Versendens eines Anbieteverzeichnisses keine Primärdokumente übergeben. Die MetadatenAussonderung müssen zwingend übergeben werden.</implementationHint> + </xs:appinfo> + <xs:documentation>Ein Schriftgutobjekt (Akte, Vorgang oder Dokument) zu einem Anbieteverzeichnis.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:choice> + <xs:element name="Akte" type="xdomea:AkteType"> + <xs:annotation> + <xs:documentation>Eine Akte.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Vorgang" type="xdomea:VorgangType"> + <xs:annotation> + <xs:documentation>Ein Vorgang.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Dokument" type="xdomea:DokumentType"> + <xs:annotation> + <xs:documentation>Ein Dokument.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:choice> + </xs:complexType> + </xs:element> + <xs:element name="Aktenplan" minOccurs="0" type="xdomea:AktenplanType"> + <xs:annotation> + <xs:documentation>Der Aktenplan bildet ein aufgabenbezogenes mehrstufiges Ordnungssystem mit hierarchischer Gliederung für das Bilden und Kennzeichnen von Akten und Vorgängen sowie das Zuordnen von Dokumenten. Zur näheren Einordnung des Anbieteverzeichnisses kann der Aktenplan als Anlage mitgeliefert werden.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Aussonderung.Bewertungsverzeichnis.0502"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt den Export von Metadaten zu Schriftgutobjekten, die vom zuständigen Archiv zu einer Bewertung ausgewählt wurden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" + type="xdomea:NkNichtFVDatenEinEmpfaengerMitEmpfangsbestaetigungType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Bewertungsverzeichnis-Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="BewertetesObjekt" + maxOccurs="unbounded" + type="xdomea:RueckgabeparameterAnbietungType"> + <xs:annotation> + <xs:documentation>Die Information zu einem Schriftgutobjekt über die durch das Archiv erfolgte Bewertung im Anbieteverzeichnis.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Aussonderung.Aussonderung.0503"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt den Export von Schriftgutobjekten mit dem Ziel der Übergabe an das zuständige Archiv.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkAussonderungType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Aussonderungs-Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Anschreiben" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:DokumentType"> + <xs:annotation> + <xs:documentation>Ein Dokument, in dem allgemeine Informationen zu den auszusondernden Schriftgutobjekten an das Archiv mitgegeben werden können. Hier können auch Formblätter (z.B. "Vorblatt zur Abgabe" gemäß Registraturrichtlinie) mitgegeben werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Schriftgutobjekt" maxOccurs="unbounded"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Die Primärdokumente und MetadatenAussonderung müssen zwingend im Zuge einer Aussonderung übergeben werden.</implementationHint> + </xs:appinfo> + <xs:documentation>Ein Schriftgutobjekt (Akte, Vorgang oder Dokument) zu einer Aussonderung.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:choice> + <xs:element name="Akte" type="xdomea:AkteType"> + <xs:annotation> + <xs:documentation>Eine Akte.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Vorgang" type="xdomea:VorgangType"> + <xs:annotation> + <xs:documentation>Ein Vorgang.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Dokument" type="xdomea:DokumentType"> + <xs:annotation> + <xs:documentation>Ein Dokument.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:choice> + </xs:complexType> + </xs:element> + <xs:element name="Aktenplan" minOccurs="0" type="xdomea:AktenplanType"> + <xs:annotation> + <xs:documentation>Der Aktenplan zu einer Aussonderung enthält ein aufgabenbezogenes mehrstufiges Ordnungssystem mit hierarchischer Gliederung für das Bilden und Kennzeichnen von Akten und Vorgängen sowie das Zuordnen von Dokumenten.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Aussonderung.AnbietungEmpfangBestaetigen.0504"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt den erfolgreichen Empfang des Anbietverzeichnisses.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkBasisType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Empfangsbestätigung.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Aussonderung.BewertungEmpfangBestaetigen.0505"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt den erfolgreichen Empfang des Bewertungsverzeichnisses.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkBasisType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Empfangsbestätigung.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Aussonderung.AussonderungImportBestaetigen.0506"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die erfolgreiche oder nicht erfolgreiche Übernahme der Aussonderung.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkBasisType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Importnachricht zu einer Aussonderung.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="AusgesondertesSGO" + maxOccurs="unbounded" + type="xdomea:ErfolgOderMisserfolgAussonderungType"> + <xs:annotation> + <xs:documentation>Die Information zum erfolgreichen oder nicht erfolgreichen Import eines Schriftgutobjekts zur Aussonderung.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Aussonderung.AussonderungEmpfangBestaetigen.0507"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt den erfolgreichen Empfang der Aussonderung.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkBasisType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Empfangsbestätigung.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Aussonderung.AktenplanZurBewertung.0511"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt den Export eines Aktenplans zur Bewertung an ein Archiv nach Anfrage durch das Archiv.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" + type="xdomea:NkNichtFVDatenWeitereEmpfaengerMitEmpfangsbestaetigungType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Aktenplan-Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Aktenplan" type="xdomea:AktenplanBewertungskatalogType"> + <xs:annotation> + <xs:documentation>Der für die Bewertung zu übergebende Aktenplan enthält ein aufgabenbezogenes mehrstufiges Ordnungssystem mit hierarchischer Gliederung für das Bilden und Kennzeichnen von Akten und Vorgängen sowie das Zuordnen von Dokumenten.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Aussonderung.AktenplanZurBewertungEmpfangBestaetigen.0512"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt den erfolgreichen Empfang des Aktenplans zur Bewertung.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkBasisType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Empfangsbestätigung.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Aussonderung.Bewertungskatalog.0513"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt den Export eines archivisch bewerteten Aktenplans.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" + type="xdomea:NkNichtFVDatenWeitereEmpfaengerMitEmpfangsbestaetigungType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Bewertungskatalog-Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="BewerteteAktenplaneinheit" + maxOccurs="unbounded" + type="xdomea:AktenplaneinheitAktenplanBewertungskatalogType"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Voraussetzung für die Implementierung ist, dass das DMS / VBS die UUID, die es jeder Aktenplaneinheit in den Nachrichten zugeordnet hat, auch im System hinterlegt hat.</implementationHint> + </xs:appinfo> + <xs:documentation>Die bewertete Einheit eines Aktenplans. Eine Aktenplanheit entspricht z.B. einer Hauptgruppe, Obergruppe, Gruppe, Untergruppe oder Betreffseinheit.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Aussonderung.BewertungskatalogImportBestaetigen.0514"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die erfolgreiche oder nicht erfolgreiche Übernahme des Bewertungskataloges.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkBasisType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Importnachricht zu einem Bewertungskatalog.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="BewerteteAktenplaneinheit" + maxOccurs="unbounded" + type="xdomea:ErfolgOderMisserfolgBewertungskatalogType"> + <xs:annotation> + <xs:documentation>Die Information über den erfolgreichen oder nicht erfolgreichen Import des Wertes in "Aussonderungsart" oder "AussonderungsartKonfigurierbar" zu der jeweiligen Aktenplaneinheit.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Aussonderung.BewerteterAktenplanEmpfangBestaetigen.0515"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt den erfolgreichen Empfang des bewerteten Aktenplans.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkBasisType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Empfangsbestätigung.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> +</xs:schema> diff --git a/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-DMS.xsd b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-DMS.xsd new file mode 100644 index 0000000000000000000000000000000000000000..26526bcce64eb9f0cc087cb8f50ac048bc0b11d0 --- /dev/null +++ b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-DMS.xsd @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xdomea="urn:xoev-de:xdomea:schema:3.0.0" + targetNamespace="urn:xoev-de:xdomea:schema:3.0.0" + version="3.0.0" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> + <xs:annotation> + <xs:appinfo> + <standard> + <nameLang>xdomea - XÖV-Standard für den IT-gestützten Austausch und die IT-gestützte Aussonderung behördlichen Schriftgutes</nameLang> + <nameKurz>xdomea</nameKurz> + <nameTechnisch>xdomea</nameTechnisch> + <kennung>urn:xoev-de:xdomea:kosit:standard:xdomea</kennung> + <beschreibung>xdomea ist der vom IT-Planungsrat verabschiedete verbindliche Standard für den Austausch von Akten, Vorgängen und Dokumenten im Kontext der Übermittlung, der Abgabe sowie der Aussonderung von Schriftgutobjekten (www.it-planungsrat.de, Beschluss 2017/39). Weiterhin kann xdomea für den Austausch zwischen Fachverfahren und DMS/VBS sowie für die Zwischenarchivierung genutzt werden. + +Um diese Anwendungsszenarien bestmöglich zu unterstützen, ist xdomea gemäß des XÖV-Rahmenwerkes nach dem Baukastenprinzip aufgebaut und bietet einzelne Nachrichten(gruppen) für die jeweiligen Prozesse an. + +Der Standard xdomea wird von der gleichnamigen Arbeitsgruppe des IT-Planungsrates weiterentwickelt und gepflegt. Der Betrieb des Standards erfolgt durch die Koordinierungsstelle für IT-Standards (KoSIT). +</beschreibung> + </standard> + <versionStandard> + <version>3.0.0</version> + <beschreibung>Die Version 3.0.0 ist durch den IT-Planungsrat beschlossen. Details zum Beschluss sowie zu den Fristen der Umsetzung sind der Veröffentlichung im Bundesanzeiger unter www.bundesanzeiger.de zu entnehmen.</beschreibung> + <versionXOEVProfil>1.7.2</versionXOEVProfil> + <versionXOEVHandbuch>2.3.1</versionXOEVHandbuch> + <versionXGenerator>3.0.1</versionXGenerator> + <versionModellierungswerkzeug>19.0</versionModellierungswerkzeug> + <nameModellierungswerkzeug>MagicDraw</nameModellierungswerkzeug> + </versionStandard> + </xs:appinfo> + </xs:annotation> + <xs:include schemaLocation="xdomea-Nachrichten-AbgabeDurchfuehren.xsd"/> + <xs:include schemaLocation="xdomea-Nachrichten-AktenplanAustauschen.xsd"/> + <xs:include schemaLocation="xdomea-Nachrichten-AussonderungDurchfuehren.xsd"/> + <xs:include schemaLocation="xdomea-Nachrichten-InformationAustauschen.xsd"/> +</xs:schema> diff --git a/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-Fachverfahren.xsd b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-Fachverfahren.xsd new file mode 100644 index 0000000000000000000000000000000000000000..0f79de371787645c740f1f1ebb6e776fff4eb057 --- /dev/null +++ b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-Fachverfahren.xsd @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xdomea="urn:xoev-de:xdomea:schema:3.0.0" + targetNamespace="urn:xoev-de:xdomea:schema:3.0.0" + version="3.0.0" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> + <xs:annotation> + <xs:appinfo> + <standard> + <nameLang>xdomea - XÖV-Standard für den IT-gestützten Austausch und die IT-gestützte Aussonderung behördlichen Schriftgutes</nameLang> + <nameKurz>xdomea</nameKurz> + <nameTechnisch>xdomea</nameTechnisch> + <kennung>urn:xoev-de:xdomea:kosit:standard:xdomea</kennung> + <beschreibung>xdomea ist der vom IT-Planungsrat verabschiedete verbindliche Standard für den Austausch von Akten, Vorgängen und Dokumenten im Kontext der Übermittlung, der Abgabe sowie der Aussonderung von Schriftgutobjekten (www.it-planungsrat.de, Beschluss 2017/39). Weiterhin kann xdomea für den Austausch zwischen Fachverfahren und DMS/VBS sowie für die Zwischenarchivierung genutzt werden. + +Um diese Anwendungsszenarien bestmöglich zu unterstützen, ist xdomea gemäß des XÖV-Rahmenwerkes nach dem Baukastenprinzip aufgebaut und bietet einzelne Nachrichten(gruppen) für die jeweiligen Prozesse an. + +Der Standard xdomea wird von der gleichnamigen Arbeitsgruppe des IT-Planungsrates weiterentwickelt und gepflegt. Der Betrieb des Standards erfolgt durch die Koordinierungsstelle für IT-Standards (KoSIT). +</beschreibung> + </standard> + <versionStandard> + <version>3.0.0</version> + <beschreibung>Die Version 3.0.0 ist durch den IT-Planungsrat beschlossen. Details zum Beschluss sowie zu den Fristen der Umsetzung sind der Veröffentlichung im Bundesanzeiger unter www.bundesanzeiger.de zu entnehmen.</beschreibung> + <versionXOEVProfil>1.7.2</versionXOEVProfil> + <versionXOEVHandbuch>2.3.1</versionXOEVHandbuch> + <versionXGenerator>3.0.1</versionXGenerator> + <versionModellierungswerkzeug>19.0</versionModellierungswerkzeug> + <nameModellierungswerkzeug>MagicDraw</nameModellierungswerkzeug> + </versionStandard> + </xs:appinfo> + </xs:annotation> + <xs:include schemaLocation="xdomea-Nachrichten-FachverfahrensdatenAustauschen.xsd"/> +</xs:schema> diff --git a/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-FachverfahrensdatenAustauschen.xsd b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-FachverfahrensdatenAustauschen.xsd new file mode 100644 index 0000000000000000000000000000000000000000..b10277c5a5d5154b82aec91e604e15b8cfd18aff --- /dev/null +++ b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-FachverfahrensdatenAustauschen.xsd @@ -0,0 +1,692 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xdomea="urn:xoev-de:xdomea:schema:3.0.0" + targetNamespace="urn:xoev-de:xdomea:schema:3.0.0" + version="3.0.0" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> + <xs:annotation> + <xs:appinfo> + <standard> + <nameLang>xdomea - XÖV-Standard für den IT-gestützten Austausch und die IT-gestützte Aussonderung behördlichen Schriftgutes</nameLang> + <nameKurz>xdomea</nameKurz> + <nameTechnisch>xdomea</nameTechnisch> + <kennung>urn:xoev-de:xdomea:kosit:standard:xdomea</kennung> + <beschreibung>xdomea ist der vom IT-Planungsrat verabschiedete verbindliche Standard für den Austausch von Akten, Vorgängen und Dokumenten im Kontext der Übermittlung, der Abgabe sowie der Aussonderung von Schriftgutobjekten (www.it-planungsrat.de, Beschluss 2017/39). Weiterhin kann xdomea für den Austausch zwischen Fachverfahren und DMS/VBS sowie für die Zwischenarchivierung genutzt werden. + +Um diese Anwendungsszenarien bestmöglich zu unterstützen, ist xdomea gemäß des XÖV-Rahmenwerkes nach dem Baukastenprinzip aufgebaut und bietet einzelne Nachrichten(gruppen) für die jeweiligen Prozesse an. + +Der Standard xdomea wird von der gleichnamigen Arbeitsgruppe des IT-Planungsrates weiterentwickelt und gepflegt. Der Betrieb des Standards erfolgt durch die Koordinierungsstelle für IT-Standards (KoSIT). +</beschreibung> + </standard> + <versionStandard> + <version>3.0.0</version> + <beschreibung>Die Version 3.0.0 ist durch den IT-Planungsrat beschlossen. Details zum Beschluss sowie zu den Fristen der Umsetzung sind der Veröffentlichung im Bundesanzeiger unter www.bundesanzeiger.de zu entnehmen.</beschreibung> + <versionXOEVProfil>1.7.2</versionXOEVProfil> + <versionXOEVHandbuch>2.3.1</versionXOEVHandbuch> + <versionXGenerator>3.0.1</versionXGenerator> + <versionModellierungswerkzeug>19.0</versionModellierungswerkzeug> + <nameModellierungswerkzeug>MagicDraw</nameModellierungswerkzeug> + </versionStandard> + <title>Fachverfahrensdaten austauschen</title> + </xs:appinfo> + </xs:annotation> + <xs:include schemaLocation="xdomea-Baukasten.xsd"/> + <xs:include schemaLocation="xdomea-Typen-FachverfahrensdatenAustauschen.xsd"/> + <xs:element name="FVDaten.DokumentAktualisieren.0601"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Für die Aktualisierung eines Dokuments ist die in den Eingabeparametern übergebene UUID relevant. Die UUID im Element Identifikation des Typs DokumentType ist hierfür irrelevant.</implementationHint> + </xs:appinfo> + <xs:documentation>Die Nachricht beschreibt die Aktualisierung eines bereits im DMS vorhandenen Dokuments. Als Rückgabeparameter sollte die Bestätigung des erfolgreichen Aktualisierens mit der ID des Dokuments gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="DokumentZumAktualisieren" + maxOccurs="unbounded" + type="xdomea:DokumentZumAktualisierenType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem Dokument, das im DMS aktualisiert werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.SGOAnsehen.0602"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die Übergabe eines Schriftgutobjekts, das im DMS angezeigt werden soll. Als Rückgabeparameter sollte die Bestätigung des erfolgreichen Öffnens des Schriftgutobjekts zur Ansicht mit seiner ID gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SchriftgutobjektZumAnsehen" + type="xdomea:SchriftgutobjektZumAnsehenOderBearbeitenType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem Schriftgutobjekt, das angesehen werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.SGOBearbeiten.0603"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die Übergabe eines Schriftgutobjekts, das zur Bearbeitung geöffnet werden soll. Als Rückgabeparameter sollte die Bestätigung des erfolgreichen Öffnens des Schriftgutobjekts zur Bearbeitung mit seiner ID gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SchriftgutobjektZumBearbeiten" + type="xdomea:SchriftgutobjektZumAnsehenOderBearbeitenType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem Schriftgutobjekt, das bearbeitet werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.SGOErstellen.0604"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die Übergabe von neuen Schriftgutobjekten zur Erstellung im DMS. Als Rückgabeparameter sollte jeweils die Bestätigung des erfolgreichen Erstellens des Schriftgutobjekts mit seiner ID im DMS gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SchriftgutobjektZumErstellen" + maxOccurs="unbounded" + type="xdomea:SchriftgutobjektZumErstellenType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem neuen Schriftgutobjekt, das erstellt werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.SGOAblegen.0605"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Als Ergebnis wird immer ein neues Dokument mit einer neuen UUID im DMS angelegt. Daher ist die UUID im Element Identifikation im Typ DokumentType hier zu ignorieren.</implementationHint> + </xs:appinfo> + <xs:documentation>Die Nachricht beschreibt die Übergabe von neuen Schriftgutobjekten an das DMS zur Ablage. Als Rückgabeparameter sollte jeweils die Bestätigung des erfolgreichen Ablegens des Schriftgutobjekts mit seiner ID gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SchriftgutobjektZumAblegen" + maxOccurs="unbounded" + type="xdomea:SchriftgutobjektZumAblegenType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem Schriftgutobjekt, das abgelegt werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.SGODrucken.0606"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die Übergabe von zu druckenden Schriftgutobjekten. Als Rückgabeparameter sollte jeweils die Bestätigung des erfolgreichen Druckens des Schriftgutobjekts mit seiner ID gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SchriftgutobjektZumDrucken" + maxOccurs="unbounded" + type="xdomea:SchriftgutobjektZumDruckenType"> + <xs:annotation> + <xs:documentation>Die Informationen zum zu druckenden Schriftgutobjekt.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.ProtokolleintragErstellen.0607"> + <xs:annotation> + <xs:documentation>Die Nachricht ermöglicht die Erstellung eines Protokolleintrags zu einem Objekt im DMS. Als Rückgabeparameter sollte jeweils die Bestätigung des erfolgreichen Erstellens des Protokolleintrags mit der dazugehörigen Schriftgutobjekt-ID gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="ProtokolleintragZumErstellen" + maxOccurs="unbounded" + type="xdomea:ProtokolleintragZumErstellenType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem zu erstellenden Protokolleintrag.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.SGOSuchen.0608"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die Übergabe von Parametern zur Suche nach Schriftgutobjekten im DMS. Als Rückgabeparameter soll die Liste der Schriftgutobjekte mit ihren IDs gesendet werden, auf die die Suchparameter zutreffen.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SchriftgutobjektZumSuchen" + type="xdomea:SchriftgutobjektZumSuchenType"> + <xs:annotation> + <xs:documentation>Die Parameter zu einer Suche nach Schriftgutobjekten.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.MetadatenAnlegen.0609"> + <xs:annotation> + <xs:documentation>Die Nachricht ermöglicht das Anlegen eines Metadatums zu einem Objekt im DMS. Als Rückgabeparameter sollte die Bestätigung des erfolgreichen Anlegens der Metadaten mit den entsprechenden Namen und Werten sowie der ID und evtl. der Versionsnummer (nur für Dokumente) des Schriftgutobjekts gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="MetadatenZumAnlegen" + maxOccurs="unbounded" + type="xdomea:MetadatenZumBearbeitenType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem neuen Metadatum.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.MetadatenAktualisieren.0610"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die Aktualisierung eines bereits existierenden Metadatums. Als Rückgabeparameter sollte die Bestätigung des erfolgreichen Aktualisierens von Metadaten mit entsprechendem Namen und Wert sowie der ID und evtl. der Versionsnummer (nur für Dokumente) des Schriftgutobjekts gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="MetadatenZumAktualisieren" + maxOccurs="unbounded" + type="xdomea:MetadatenZumBearbeitenType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem zu aktualisierenden Metadatum.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.MetadatenAnsehen.0611"> + <xs:annotation> + <xs:documentation>Die Nachricht ermöglicht das Auslesen des Wertes zu einem Metadatum. Als Rückgabeparameter sollten die Namen und Werte der angeforderten Metadaten gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="MetadatenZumAnsehen" + maxOccurs="unbounded" + type="xdomea:MetadatenZumBearbeitenType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem Metadatum, das angesehen werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.MetadatenLoeschen.0612"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die Übergabe eines zu löschenden Metadatums. Als Rückgabeparameter sollte die Bestätigung des erfolgreichen Löschens der Metadaten mit den entsprechenden Namen und Werten sowie der ID und evtl. der Versionsnummer (nur für Dokumente) des Schriftgutobjekts gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="MetadatenZumLoeschen" + maxOccurs="unbounded" + type="xdomea:MetadatenZumBearbeitenType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem zu löschenden Metadatum.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.SGOLoeschenMarkieren.0613"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die Übergabe von Schriftgutobjekten, die im DMS zum Löschen markiert werden sollen (4-Augen-Löschen). Als Rückgabeparameter sollte jeweils die Bestätigung des erfolgreichen Markierens des Schriftgutobjekts zur Löschung mit seiner ID gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SchriftgutobjektZumLoeschenMarkieren" + maxOccurs="unbounded" + type="xdomea:SchriftgutobjektZumLoeschenType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem Schriftgutobjekt, das zum Löschen markiert werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.SGOLoeschmarkierungAufheben.0614"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die Übergabe von Schriftgutobjekten, für die die Löschmarkierung im DMS aufgehoben werden soll (4-Augen-Löschen). Als Rückgabeparameter sollte jeweils die Bestätigung des erfolgreichen Aufhebens der Löschmarkierung des Schriftgutobjekts mit seiner ID gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SchriftgutobjektZumLoeschmarkierungAufheben" + maxOccurs="unbounded" + type="xdomea:SchriftgutobjektZumLoeschenType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem Schriftgutobjekt, dessen Löschmarkierung aufgehoben werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.SGOEndgueltigLoeschen.0615"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die Übergabe von Schriftgutobjekten zur endgültigen Löschung im DMS. Als Rückgabeparameter sollte jeweils die Bestätigung des erfolgreichen endgültigen Löschens des Schriftgutobjekts mit seiner ID gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SchriftgutobjektZumEndgueltigLoeschen" + maxOccurs="unbounded" + type="xdomea:SchriftgutobjektZumLoeschenType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem Schriftgutobjekt, das endgültig gelöscht werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.SGOLoeschstatusAbfragen.0616"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die Übergabe von Schriftgutobjekten, zu denen der Löschstatus im DMS abgefragt werden soll. Als Rückgabeparameter sollte jeweils der Löschstatus des Schriftgutobjekts mit seiner ID gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SchriftgutobjektZumLoeschstatusAbfragen" + maxOccurs="unbounded" + type="xdomea:SchriftgutobjektZumLoeschstatusAbfragenType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem Schriftgutobjekt, dessen Löschstatus abgefragt werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.SGOUngueltigKennzeichnen.0617"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die Übergabe von Schriftgutobjekten, die im DMS als ungültig markiert werden sollen. Als Rückgabeparameter sollte jeweils die Bestätigung des erfolgreichen Ungültig-Markierens des Schriftgutobjekts mit seiner ID gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SchriftgutobjektZumUngueltigKennzeichnen" + maxOccurs="unbounded" + type="xdomea:SchriftgutobjektZumLoeschenType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem Schriftgutobjekt, das als ungültig gekennzeichnet werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.DatensatzLoeschen.0618"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die Übergabe eines im Fachverfahren vollständig gelöschten Datensatzes, um alle zugehörigen Objekte im DMS ebenfalls zu löschen. Als Rückgabeparameter sollte die Löschbestätigung zum Datensatz im DMS mit der Datensatz-ID im Fachverfahren gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="DatensatzZumLoeschen" + maxOccurs="unbounded" + type="xdomea:DatensatzZumLoeschenType"> + <xs:annotation> + <xs:documentation>Die Information zu dem im Fachverfahren gelöschten Datensatz, zu dem auch alle vorhandenen Objekte im DMS gelöscht werden sollen.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.BenachrichtigungAbrufen.0619"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die Abfrage eventuell bereitgestellter Daten (Benachrichtigungen) durch ein Fachverfahren. Die Bereitstellung von Daten (bspw. neuer Dokumente) erfolgt durch ein DMS, das die Daten zum Abruf für ein Fachverfahren zur Verfügung stellt. Als Rückgabeparameter sollten die im System vorliegenden Benachrichtigungen gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.VertretungAktivierenOderDeaktivieren.0620"> + <xs:annotation> + <xs:documentation>Diese Nachricht beschreibt die Übergabe von Informationen zum Aktivieren oder zum Deaktivieren einer Vertretung im DMS. Als Rückgabeparameter sollte die Liste von Vertretern (Benutzer/Rolle) mit ihrem Namen und ihrem Aktivierungsstatus gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="VertretungZumAktivierenOderDeaktivieren" + maxOccurs="unbounded" + type="xdomea:VertretungZumAktivierenOderDeaktivierenType"> + <xs:annotation> + <xs:documentation>Die Informationen zur Aktivierung oder zur Deaktivierung einer Vertretung.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.VertretungsstatusAbfragen.0621"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die Abfrage zu den verfügbaren bzw. aktiven Vertretungen eines Benutzers oder einer Rolle im DMS. Als Rückgabeparameter sollte die Liste von Vertretern (Benutzer/Rolle) mit ihrem Namen und ihrem Aktivierungsstatus gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="VertretungsstatusZumAbfragen" + maxOccurs="unbounded" + type="xdomea:VertretungsstatusZumAbfragenType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem Benutzer oder der Rolle, für den/die die Statusabfrage durchgeführt werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.ZustaendigkeitAendern.0622"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die Übergabe von Informationen bei dem Zuständigkeitswechsel eines Schriftgutobjekts im Fachverfahren, z.B. bei Widerspruchsverfahren, mit dem Ziel, die Zuständigkeit im DMS anzupassen. Als Rückgabeparameter sollte die Bestätigung des erfolgreichen Aktualisierens der Metadaten des Schriftgutobjekts mit ID des Schriftgutobjekts, alte und neue zuständige Stelle, alte und neue Aktenplaneinheit, alte und neue Akte sowie weitere geänderte Metadaten gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="ZustaendigkeitZumAendern" + maxOccurs="unbounded" + type="xdomea:ZustaendigkeitZumAendernType"> + <xs:annotation> + <xs:documentation>Die Informationen zu der bisherigen und neuen Zuständigkeit des Schriftgutobjekts.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.GesamtprotokollAblegen.0623"> + <xs:annotation> + <xs:documentation>Diese Nachricht ermöglicht es, alle aktenrelevanten Bearbeitungs- und Protokollinformationen aus einem Fachverfahren in einem DMS abzulegen. Die Nachricht ist immer mit der zdA-Verfügung zu übermitteln. Sie kann zudem manuell aus dem Fachverfahren angestoßen werden. Damit wird sichergestellt, dass im DMS die für die Nachvollziehbarkeit erforderliche vollständige elektronische Akte geführt wird. Als Rückgabeparameter sollte die Bestätigung des erfolgreichen Ablegens mit der dazugehörigen Schriftgutobjekt-ID gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="GesamtprotokollZumAblegen" + maxOccurs="unbounded" + type="xdomea:GesamtprotokollZumAblegenType"> + <xs:annotation> + <xs:documentation>Die Informationen zum Gesamtprotokoll, das an das DMS übermittelt werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.SGOZDAVerfuegen.0624"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die Übergabe von Schriftgutobjekten, die zu den Akten verfügt werden sollen. Als Rückgabeparameter sollten jeweils die Bestätigung des erfolgreichen zdA-Verfügens des Schriftgutobjekts mit seiner ID gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SchriftgutobjektZumZDAVerfuegen" + maxOccurs="unbounded" + type="xdomea:SchriftgutobjektZumZDAVerfuegenType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem Schriftgutobjekt, das zdA-verfügt werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.SystemstatusAbfragen.0625"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die Abfrage zum Systemstatus. Als Rückgabeparameter sollte die Liste von Systemstatus mit der SystemstatusID und dem dazugehörigen aktuellen Status gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SystemstatusZumAbfragen" + maxOccurs="unbounded" + type="xdomea:SystemstatusZumAbfragenType"> + <xs:annotation> + <xs:documentation>Die angeforderte Information zum Systemstatus.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.KonfigurationsparameterErstellen.0626"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt das Anlegen eines neuen Konfigurationsparameters. Als Rückgabeparameter sollte die Bestätigung des erfolgreichen Anlegens eines neuen Konfigurationsparameters mit entsprechendem Namen und Wert gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="KonfigurationsparameterZumErstellen" + type="xdomea:KonfigurationsparameterZumErstellenType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem neuen Konfigurationsparameter sowie zu dessen Ersteller.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.KonfigurationsparameterAktualisieren.0627"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die Übergabe eines bereits existierenden Konfigurationsparameters zur Aktualisierung. Als Rückgabeparameter sollte die Bestätigung des erfolgreichen Aktualisierens der Konfigurationsparameter mit entsprechendem Namen und Wert gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="KonfigurationsparameterZumAktualisieren" + maxOccurs="unbounded" + type="xdomea:FeldType"> + <xs:annotation> + <xs:documentation>Die Information zum zu aktualisierenden Konfigurationsparameter.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.KonfigurationsparameterAbrufen.0628"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt den Abruf eines Konfigurationsparameters. Als Rückgabeparameter sollten der Name (immer) sowie soweit vorhanden der Datentyp, die Beschreibung und der Wert des Konfigurationsparameters gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="KonfigurationsparameterZumAbrufen" + maxOccurs="unbounded" + type="xdomea:KonfigurationsparameterZumAbrufenType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem abzurufenden Konfigurationsparameter.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.EmpfangBestaetigen.0629"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt den erfolgreichen Empfang einer Fachverfahrensdaten-Nachricht.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Empfangsbestätigung.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.ImportBestaetigen.0630"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die erfolgreiche oder nicht erfolgreiche Übernahme von Daten.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkRueckmeldungFVDatenImportType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="ErfolgOderMisserfolg" type="xdomea:ErfolgOderMisserfolgDMSType"> + <xs:annotation> + <xs:documentation>Die Information über den erfolgreichen oder nicht erfolgreichen Import von Daten.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.PrimaerdokumentExportieren.0631"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt den Export von Primärdokumenten zu einem Schriftgutobjekt (Dokument) aus einem DMS in ein Fachverfahren. Als Rückgabeparameter sollte der Ablageort der Primärdokumente gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="DokumentZumExportieren" type="xdomea:DokumentZumExportierenType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem Dokument, dessen Primärdokumente exportiert werden sollen.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="FVDaten.SGOZDAAufheben.0632"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt das Aufheben der zdA-Verfügung eines Schriftgutobjekts. Als Rückgabeparameter sollte die Bestätigung des erfolgreichen Wiederauflebens mit der ID des Schriftgutobjekts gesendet werden.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SGOZumZDAAufheben" + maxOccurs="unbounded" + type="xdomea:SchriftgutobjektZumZDAAufhebenType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem Schriftgutobjekt, dessen zdA-Verfügung im DMS aufgehoben werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> +</xs:schema> diff --git a/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-GeschaeftsgangDurchfuehren.xsd b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-GeschaeftsgangDurchfuehren.xsd new file mode 100644 index 0000000000000000000000000000000000000000..fcdace56d29aab05ee84d2c87f37bd63aac43b5f --- /dev/null +++ b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-GeschaeftsgangDurchfuehren.xsd @@ -0,0 +1,138 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xdomea="urn:xoev-de:xdomea:schema:3.0.0" + targetNamespace="urn:xoev-de:xdomea:schema:3.0.0" + version="3.0.0" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> + <xs:annotation> + <xs:appinfo> + <standard> + <nameLang>xdomea - XÖV-Standard für den IT-gestützten Austausch und die IT-gestützte Aussonderung behördlichen Schriftgutes</nameLang> + <nameKurz>xdomea</nameKurz> + <nameTechnisch>xdomea</nameTechnisch> + <kennung>urn:xoev-de:xdomea:kosit:standard:xdomea</kennung> + <beschreibung>xdomea ist der vom IT-Planungsrat verabschiedete verbindliche Standard für den Austausch von Akten, Vorgängen und Dokumenten im Kontext der Übermittlung, der Abgabe sowie der Aussonderung von Schriftgutobjekten (www.it-planungsrat.de, Beschluss 2017/39). Weiterhin kann xdomea für den Austausch zwischen Fachverfahren und DMS/VBS sowie für die Zwischenarchivierung genutzt werden. + +Um diese Anwendungsszenarien bestmöglich zu unterstützen, ist xdomea gemäß des XÖV-Rahmenwerkes nach dem Baukastenprinzip aufgebaut und bietet einzelne Nachrichten(gruppen) für die jeweiligen Prozesse an. + +Der Standard xdomea wird von der gleichnamigen Arbeitsgruppe des IT-Planungsrates weiterentwickelt und gepflegt. Der Betrieb des Standards erfolgt durch die Koordinierungsstelle für IT-Standards (KoSIT). +</beschreibung> + </standard> + <versionStandard> + <version>3.0.0</version> + <beschreibung>Die Version 3.0.0 ist durch den IT-Planungsrat beschlossen. Details zum Beschluss sowie zu den Fristen der Umsetzung sind der Veröffentlichung im Bundesanzeiger unter www.bundesanzeiger.de zu entnehmen.</beschreibung> + <versionXOEVProfil>1.7.2</versionXOEVProfil> + <versionXOEVHandbuch>2.3.1</versionXOEVHandbuch> + <versionXGenerator>3.0.1</versionXGenerator> + <versionModellierungswerkzeug>19.0</versionModellierungswerkzeug> + <nameModellierungswerkzeug>MagicDraw</nameModellierungswerkzeug> + </versionStandard> + <title>Geschäftsgang durchführen</title> + </xs:appinfo> + </xs:annotation> + <xs:include schemaLocation="xdomea-Baukasten.xsd"/> + <xs:include schemaLocation="xdomea-Typen-GeschaeftsgangDurchfuehren.xsd"/> + <xs:element name="Geschaeftsgang.Geschaeftsgang.0201"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Nach Versand der Nachricht werden die im Hauptobjekt enthaltenen Dokumente gesperrt. Ausnahme bildet hier der Fall, dass die letzte Bearbeitung nicht durch den Initiator erfolgt: in diesem Fall werden die Dokumente im Hauptobjekt nicht gesperrt.</implementationHint> + </xs:appinfo> + <xs:documentation>Die Nachricht beschreibt den Export von Schriftgutobjekten - Hauptobjekt (Dokumente) und Anlagen (Akte, Vorgang, Dokument) - zur Bearbeitung durch externe Bearbeitungsstationen in einem anderen System.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkGeschaeftsgangType"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Der Empfänger ist eine Bearbeitungsstation im externen Geschäftsgang.</implementationHint> + </xs:appinfo> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Geschäftsgangs-Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Anschreiben" minOccurs="0" type="xdomea:DokumentType"> + <xs:annotation> + <xs:documentation>Ein Dokument, das dem Empfänger zur Erläuterung des externen Geschäftsgangs mitgegeben wird.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Hauptobjekt" type="xdomea:HauptobjektType"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Akten oder Vorgänge sind als Element im Hauptobjekt nicht erlaubt.</implementationHint> + </xs:appinfo> + <xs:documentation>Ein Container für die Dokumente, auf die sich die Beteiligungsschritte im externen Geschäftsgang beziehen.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="ExternerGeschaeftsgang" type="xdomea:GeschaeftsgangType"> + <xs:annotation> + <xs:documentation>Im externen Geschäftsgang werden die Verfügungen an externe Bearbeitungsstationen festgelegt.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Anlage" minOccurs="0" maxOccurs="unbounded"> + <xs:annotation> + <xs:documentation>Ein Schriftgutobjekt (Akte, Vorgang oder Dokument), das dem Hauptobjekt als Anlage beigefügt wird.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:choice> + <xs:element name="Akte" type="xdomea:AkteType"> + <xs:annotation> + <xs:documentation>Eine Akte.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Vorgang" type="xdomea:VorgangType"> + <xs:annotation> + <xs:documentation>Ein Vorgang.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Dokument" type="xdomea:DokumentType"> + <xs:annotation> + <xs:documentation>Ein Dokument.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:choice> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Geschaeftsgang.EmpfangBestaetigen.0202"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt den erfolgreichen Empfang des externen Geschäftsgangs.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkRueckmeldungGeschaeftsgangType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Empfangsbestätigung.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Geschaeftsgang.GeaendertenLaufwegMitteilen.0203"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die Information eines Geschäftsgang-Initiators über die Änderung des ursprünglichen Laufwegs, z.B. durch Hinzufügen oder Überspringen von Beteiligungsschritten.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkBasisType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Geschäftsgangs-Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="GeaenderterGeschaeftsgang" type="xdomea:GeschaeftsgangType"> + <xs:annotation> + <xs:documentation>Der komplette geänderte Geschäftsgang.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="GeaenderterBeteiligungsschritt" + maxOccurs="unbounded" + type="xdomea:GeaenderterBeteiligungsschrittType"> + <xs:annotation> + <xs:documentation>Informationen zu geänderten Beteiligungsschritten eines Geschäftsgangs.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> +</xs:schema> diff --git a/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-InformationAustauschen.xsd b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-InformationAustauschen.xsd new file mode 100644 index 0000000000000000000000000000000000000000..cc0a4bc5164054c367c0ebfb5870b7e8754ea493 --- /dev/null +++ b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-InformationAustauschen.xsd @@ -0,0 +1,96 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xdomea="urn:xoev-de:xdomea:schema:3.0.0" + targetNamespace="urn:xoev-de:xdomea:schema:3.0.0" + version="3.0.0" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> + <xs:annotation> + <xs:appinfo> + <standard> + <nameLang>xdomea - XÖV-Standard für den IT-gestützten Austausch und die IT-gestützte Aussonderung behördlichen Schriftgutes</nameLang> + <nameKurz>xdomea</nameKurz> + <nameTechnisch>xdomea</nameTechnisch> + <kennung>urn:xoev-de:xdomea:kosit:standard:xdomea</kennung> + <beschreibung>xdomea ist der vom IT-Planungsrat verabschiedete verbindliche Standard für den Austausch von Akten, Vorgängen und Dokumenten im Kontext der Übermittlung, der Abgabe sowie der Aussonderung von Schriftgutobjekten (www.it-planungsrat.de, Beschluss 2017/39). Weiterhin kann xdomea für den Austausch zwischen Fachverfahren und DMS/VBS sowie für die Zwischenarchivierung genutzt werden. + +Um diese Anwendungsszenarien bestmöglich zu unterstützen, ist xdomea gemäß des XÖV-Rahmenwerkes nach dem Baukastenprinzip aufgebaut und bietet einzelne Nachrichten(gruppen) für die jeweiligen Prozesse an. + +Der Standard xdomea wird von der gleichnamigen Arbeitsgruppe des IT-Planungsrates weiterentwickelt und gepflegt. Der Betrieb des Standards erfolgt durch die Koordinierungsstelle für IT-Standards (KoSIT). +</beschreibung> + </standard> + <versionStandard> + <version>3.0.0</version> + <beschreibung>Die Version 3.0.0 ist durch den IT-Planungsrat beschlossen. Details zum Beschluss sowie zu den Fristen der Umsetzung sind der Veröffentlichung im Bundesanzeiger unter www.bundesanzeiger.de zu entnehmen.</beschreibung> + <versionXOEVProfil>1.7.2</versionXOEVProfil> + <versionXOEVHandbuch>2.3.1</versionXOEVHandbuch> + <versionXGenerator>3.0.1</versionXGenerator> + <versionModellierungswerkzeug>19.0</versionModellierungswerkzeug> + <nameModellierungswerkzeug>MagicDraw</nameModellierungswerkzeug> + </versionStandard> + <title>Information austauschen</title> + </xs:appinfo> + </xs:annotation> + <xs:include schemaLocation="xdomea-Baukasten.xsd"/> + <xs:element name="Information.Information.0101"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt den Export von Schriftgutobjekten (Akte, Vorgang, Dokument) zur Information oder Übernahme in ein anderes System.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" + type="xdomea:NkNichtFVDatenWeitereEmpfaengerMitEmpfangsbestaetigungType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Informations-Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Anschreiben" minOccurs="0" type="xdomea:DokumentType"> + <xs:annotation> + <xs:documentation>Ein Dokument, das dem Empfänger zur Erläuterung der Information mitgegeben wird.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Schriftgutobjekt" maxOccurs="unbounded"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Beim Zusammenstellen der Nachricht wird entschieden, welche prozess- und aktenrelevanten Metadaten zu dem Schriftgutobjekt übergeben werden.</implementationHint> + </xs:appinfo> + <xs:documentation>Ein Schriftgutobjekt (Akte, Vorgang oder Dokument), das mit der Informations-Nachricht an ein anderes System gesandt wird.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:choice> + <xs:element name="Akte" type="xdomea:AkteType"> + <xs:annotation> + <xs:documentation>Eine Akte.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Vorgang" type="xdomea:VorgangType"> + <xs:annotation> + <xs:documentation>Ein Vorgang.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Dokument" type="xdomea:DokumentType"> + <xs:annotation> + <xs:documentation>Ein Dokument.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:choice> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Information.EmpfangBestaetigen.0102"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt den erfolgreichen Empfang der Information.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkBasisType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Empfangsbestätigung.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> +</xs:schema> diff --git a/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-VBS.xsd b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-VBS.xsd new file mode 100644 index 0000000000000000000000000000000000000000..913db2eed8c8da05b8a4e13f2054a8e658ccde20 --- /dev/null +++ b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-VBS.xsd @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xdomea="urn:xoev-de:xdomea:schema:3.0.0" + targetNamespace="urn:xoev-de:xdomea:schema:3.0.0" + version="3.0.0" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> + <xs:annotation> + <xs:appinfo> + <standard> + <nameLang>xdomea - XÖV-Standard für den IT-gestützten Austausch und die IT-gestützte Aussonderung behördlichen Schriftgutes</nameLang> + <nameKurz>xdomea</nameKurz> + <nameTechnisch>xdomea</nameTechnisch> + <kennung>urn:xoev-de:xdomea:kosit:standard:xdomea</kennung> + <beschreibung>xdomea ist der vom IT-Planungsrat verabschiedete verbindliche Standard für den Austausch von Akten, Vorgängen und Dokumenten im Kontext der Übermittlung, der Abgabe sowie der Aussonderung von Schriftgutobjekten (www.it-planungsrat.de, Beschluss 2017/39). Weiterhin kann xdomea für den Austausch zwischen Fachverfahren und DMS/VBS sowie für die Zwischenarchivierung genutzt werden. + +Um diese Anwendungsszenarien bestmöglich zu unterstützen, ist xdomea gemäß des XÖV-Rahmenwerkes nach dem Baukastenprinzip aufgebaut und bietet einzelne Nachrichten(gruppen) für die jeweiligen Prozesse an. + +Der Standard xdomea wird von der gleichnamigen Arbeitsgruppe des IT-Planungsrates weiterentwickelt und gepflegt. Der Betrieb des Standards erfolgt durch die Koordinierungsstelle für IT-Standards (KoSIT). +</beschreibung> + </standard> + <versionStandard> + <version>3.0.0</version> + <beschreibung>Die Version 3.0.0 ist durch den IT-Planungsrat beschlossen. Details zum Beschluss sowie zu den Fristen der Umsetzung sind der Veröffentlichung im Bundesanzeiger unter www.bundesanzeiger.de zu entnehmen.</beschreibung> + <versionXOEVProfil>1.7.2</versionXOEVProfil> + <versionXOEVHandbuch>2.3.1</versionXOEVHandbuch> + <versionXGenerator>3.0.1</versionXGenerator> + <versionModellierungswerkzeug>19.0</versionModellierungswerkzeug> + <nameModellierungswerkzeug>MagicDraw</nameModellierungswerkzeug> + </versionStandard> + </xs:appinfo> + </xs:annotation> + <xs:include schemaLocation="xdomea-Nachrichten-AbgabeDurchfuehren.xsd"/> + <xs:include schemaLocation="xdomea-Nachrichten-AktenplanAustauschen.xsd"/> + <xs:include schemaLocation="xdomea-Nachrichten-AussonderungDurchfuehren.xsd"/> + <xs:include schemaLocation="xdomea-Nachrichten-GeschaeftsgangDurchfuehren.xsd"/> + <xs:include schemaLocation="xdomea-Nachrichten-InformationAustauschen.xsd"/> +</xs:schema> diff --git a/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-ZwischenarchivierungDurchfuehren.xsd b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-ZwischenarchivierungDurchfuehren.xsd new file mode 100644 index 0000000000000000000000000000000000000000..37dca150e412c956ce035310d285f9ecf0aec94b --- /dev/null +++ b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-ZwischenarchivierungDurchfuehren.xsd @@ -0,0 +1,315 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xdomea="urn:xoev-de:xdomea:schema:3.0.0" + targetNamespace="urn:xoev-de:xdomea:schema:3.0.0" + version="3.0.0" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> + <xs:annotation> + <xs:appinfo> + <standard> + <nameLang>xdomea - XÖV-Standard für den IT-gestützten Austausch und die IT-gestützte Aussonderung behördlichen Schriftgutes</nameLang> + <nameKurz>xdomea</nameKurz> + <nameTechnisch>xdomea</nameTechnisch> + <kennung>urn:xoev-de:xdomea:kosit:standard:xdomea</kennung> + <beschreibung>xdomea ist der vom IT-Planungsrat verabschiedete verbindliche Standard für den Austausch von Akten, Vorgängen und Dokumenten im Kontext der Übermittlung, der Abgabe sowie der Aussonderung von Schriftgutobjekten (www.it-planungsrat.de, Beschluss 2017/39). Weiterhin kann xdomea für den Austausch zwischen Fachverfahren und DMS/VBS sowie für die Zwischenarchivierung genutzt werden. + +Um diese Anwendungsszenarien bestmöglich zu unterstützen, ist xdomea gemäß des XÖV-Rahmenwerkes nach dem Baukastenprinzip aufgebaut und bietet einzelne Nachrichten(gruppen) für die jeweiligen Prozesse an. + +Der Standard xdomea wird von der gleichnamigen Arbeitsgruppe des IT-Planungsrates weiterentwickelt und gepflegt. Der Betrieb des Standards erfolgt durch die Koordinierungsstelle für IT-Standards (KoSIT). +</beschreibung> + </standard> + <versionStandard> + <version>3.0.0</version> + <beschreibung>Die Version 3.0.0 ist durch den IT-Planungsrat beschlossen. Details zum Beschluss sowie zu den Fristen der Umsetzung sind der Veröffentlichung im Bundesanzeiger unter www.bundesanzeiger.de zu entnehmen.</beschreibung> + <versionXOEVProfil>1.7.2</versionXOEVProfil> + <versionXOEVHandbuch>2.3.1</versionXOEVHandbuch> + <versionXGenerator>3.0.1</versionXGenerator> + <versionModellierungswerkzeug>19.0</versionModellierungswerkzeug> + <nameModellierungswerkzeug>MagicDraw</nameModellierungswerkzeug> + </versionStandard> + <title>Zwischenarchivierung durchführen</title> + </xs:appinfo> + </xs:annotation> + <xs:include schemaLocation="xdomea-Baukasten.xsd"/> + <xs:include schemaLocation="xdomea-Typen-ZwischenarchivierungDurchfuehren.xsd"/> + <xs:element name="Zwischenarchivierung.Auslagerung.0701"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt den vollständigen Export von Schriftgutobjekten zur Auslagerung an ein Zwischenarchiv.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkZwischenarchivierungType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Auslagerungs-Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Anschreiben" minOccurs="0" type="xdomea:DokumentType"> + <xs:annotation> + <xs:documentation>Ein Dokument, das dem Empfänger zur Erläuterung der Auslagerung mitgegeben wird.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Schriftgutobjekt" maxOccurs="unbounded"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Bei der Auslagerung müssen zu einem Schriftgutobjekt alle prozess- und aktenrelevanten Metadaten übergeben werden. Die Fristen und die Aussonderungsart werden bei der Auslagerung zu einem Schriftgutobjekt mit übergeben.</implementationHint> + </xs:appinfo> + <xs:documentation>Ein Schriftgutobjekt (Akte, Vorgang oder Dokument) zu einer Auslagerung.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:choice> + <xs:element name="Akte" type="xdomea:AkteType"> + <xs:annotation> + <xs:documentation>Eine Akte.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Vorgang" type="xdomea:VorgangType"> + <xs:annotation> + <xs:documentation>Ein Vorgang.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Dokument" type="xdomea:DokumentType"> + <xs:annotation> + <xs:documentation>Ein Dokument.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:choice> + </xs:complexType> + </xs:element> + <xs:element name="Aktenplan" minOccurs="0" type="xdomea:AktenplanType"> + <xs:annotation> + <xs:documentation>Der Aktenplan zu einer Auslagerung enthält ein aufgabenbezogenes mehrstufiges Ordnungssystem mit einer hierarchischer Gliederung für das Bilden und Kennzeichnen von Akten und Vorgängen sowie das Zuordnen von Dokumenten.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Zwischenarchivierung.AuslagerungEmpfangBestaetigen.0702"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt den erfolgreichen Empfang der Auslagerung.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkBasisType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Empfangsbestätigung.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Zwischenarchivierung.AuslagerungImportBestaetigen.0703"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die erfolgreiche oder nicht erfolgreiche Übernahme der Auslagerung.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkBasisType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Importnachricht zu einer Auslagerung.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="AusgelagertesObjekt" + maxOccurs="unbounded" + type="xdomea:ErfolgOderMisserfolgZwischenarchivierungType"> + <xs:annotation> + <xs:documentation>Die Information zum erfolgreichen oder nicht erfolgreichen Import eines Schriftgutobjekts zur Auslagerung.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Zwischenarchivierung.RueckleiheAnforderung.0711"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die Anforderung zur Rückleihe (nur lesender Zugriff) von ausgelagerten Schriftgutobjekten durch die zuständige Verwaltung.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkBasisType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Rückleihe-Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="RueckzuleihendesObjekt" + maxOccurs="unbounded" + type="xdomea:stringUUIDType"> + <xs:annotation> + <xs:documentation>Das Identifikationsmerkmal zu einem Schriftgutobjekt, das zurückgeliehen werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Zwischenarchivierung.RueckleiheUebergabe.0712"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die durchgeführte Rückleihe (nur lesender Zugriff) von Schriftgutobjekten als Übergabe von einem Zwischenarchiv an ein DMS/VBS.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkZwischenarchivierungType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Rückleihe-Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Anschreiben" minOccurs="0" type="xdomea:DokumentType"> + <xs:annotation> + <xs:documentation>Ein Dokument, das dem Empfänger zur Erläuterung der Rückleihe mitgegeben wird.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Schriftgutobjekt" maxOccurs="unbounded"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Bei der Rückleihe müssen zu einem Schriftgutobjekt alle prozess- und aktenrelevanten Metadaten übergeben werden. Die aufnehmende Behörde übernimmt das Schriftgutobjekt als Kopie in das eigene System. Das Original verbleibt im Zwischenarchiv.</implementationHint> + </xs:appinfo> + <xs:documentation>Ein Schriftgutobjekt (Akte, Vorgang oder Dokument) zu einer durchgeführten Rückleihe.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:choice> + <xs:element name="Akte" type="xdomea:AkteType"> + <xs:annotation> + <xs:documentation>Eine Akte.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Vorgang" type="xdomea:VorgangType"> + <xs:annotation> + <xs:documentation>Ein Vorgang.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Dokument" type="xdomea:DokumentType"> + <xs:annotation> + <xs:documentation>Ein Dokument.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:choice> + </xs:complexType> + </xs:element> + <xs:element name="Aktenplan" minOccurs="0" type="xdomea:AktenplanType"> + <xs:annotation> + <xs:documentation>Der Aktenplan zu einer Rückleihe enthält ein aufgabenbezogenes mehrstufiges Ordnungssystem mit einer hierarchischer Gliederung für das Bilden und Kennzeichnen von Akten und Vorgängen sowie das Zuordnen von Dokumenten.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Zwischenarchivierung.RueckleiheEmpfangBestaetigen.0713"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt den erfolgreichen Empfang der Rückleihe.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkBasisType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Empfangsbestätigung.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Zwischenarchivierung.RueckuebertragungAnforderung.0721"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die Anforderung zur Rückübertragung (lesender und schreibender Zugriff) von ausgelagerten Schriftgutobjekten durch die zuständige Verwaltung.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkBasisType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Rückübertragungs-Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="RueckzuuebertragendesObjekt" + maxOccurs="unbounded" + type="xdomea:stringUUIDType"> + <xs:annotation> + <xs:documentation>Das Identifikationsmerkmal zu einem Schriftgutobjekt, das zurückübertragen werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Zwischenarchivierung.RueckuebertragungUebergabe.0722"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die vollständige Rückübertragung (lesender und schreibender Zugriff) von Schriftgutobjekten als Übergabe von einem Zwischenarchiv an ein DMS/VBS.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkZwischenarchivierungType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Rückübertragungs-Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Anschreiben" minOccurs="0" type="xdomea:DokumentType"> + <xs:annotation> + <xs:documentation>Ein Dokument, das dem Empfänger zur Erläuterung der Rückübertragung mitgegeben wird.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Schriftgutobjekt" maxOccurs="unbounded"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Bei der Rückübertragung müssen zu einem Schriftgutobjekt alle prozess- und aktenrelevanten Metadaten übergeben werden. Die Fristen und die Aussonderungsart werden bei der Rückübertragung zu einem Schriftgutobjekt mit übergeben. Die aufnehmende Behörde übernimmt das rückübertragene Schriftgutobjekt in ihr System. Das Schriftgutobjekt wird anschließend im Zwischenarchiv gelöscht.</implementationHint> + </xs:appinfo> + <xs:documentation>Ein Schriftgutobjekt (Akte, Vorgang oder Dokument) zu einer durchgeführten Rückübertragung.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:choice> + <xs:element name="Akte" type="xdomea:AkteType"> + <xs:annotation> + <xs:documentation>Eine Akte.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Vorgang" type="xdomea:VorgangType"> + <xs:annotation> + <xs:documentation>Ein Vorgang.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Dokument" type="xdomea:DokumentType"> + <xs:annotation> + <xs:documentation>Ein Dokument.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:choice> + </xs:complexType> + </xs:element> + <xs:element name="Aktenplan" minOccurs="0" type="xdomea:AktenplanType"> + <xs:annotation> + <xs:documentation>Der Aktenplan zu einer Rückübertragung enthält ein aufgabenbezogenes mehrstufiges Ordnungssystem mit einer hierarchischer Gliederung für das Bilden und Kennzeichnen von Akten und Vorgängen sowie das Zuordnen von Dokumenten.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Zwischenarchivierung.RueckuebertragungImportBestaetigen.0723"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt die erfolgreiche oder nicht erfolgreiche Übernahme der Rückübertragung.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkBasisType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Importnachricht zu einer Rückübertragung.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="RueckuebertragenesObjekt" + maxOccurs="unbounded" + type="xdomea:ErfolgOderMisserfolgZwischenarchivierungType"> + <xs:annotation> + <xs:documentation>Die Information zum erfolgreichen oder nicht erfolgreichen Import eines Schriftgutobjekts zur Rueckuebertragung.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Zwischenarchivierung.RueckuebertragungEmpfangBestaetigen.0724"> + <xs:annotation> + <xs:documentation>Die Nachricht beschreibt den erfolgreichen Empfang der Rückübertragung.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Kopf" type="xdomea:NkBasisType"> + <xs:annotation> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Empfangsbestätigung.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> +</xs:schema> diff --git a/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-Zwischenarchivsystem.xsd b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-Zwischenarchivsystem.xsd new file mode 100644 index 0000000000000000000000000000000000000000..eebc19d5b789cfb58b7b2aa122b5144de23fad93 --- /dev/null +++ b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Nachrichten-Zwischenarchivsystem.xsd @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xdomea="urn:xoev-de:xdomea:schema:3.0.0" + targetNamespace="urn:xoev-de:xdomea:schema:3.0.0" + version="3.0.0" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> + <xs:annotation> + <xs:appinfo> + <standard> + <nameLang>xdomea - XÖV-Standard für den IT-gestützten Austausch und die IT-gestützte Aussonderung behördlichen Schriftgutes</nameLang> + <nameKurz>xdomea</nameKurz> + <nameTechnisch>xdomea</nameTechnisch> + <kennung>urn:xoev-de:xdomea:kosit:standard:xdomea</kennung> + <beschreibung>xdomea ist der vom IT-Planungsrat verabschiedete verbindliche Standard für den Austausch von Akten, Vorgängen und Dokumenten im Kontext der Übermittlung, der Abgabe sowie der Aussonderung von Schriftgutobjekten (www.it-planungsrat.de, Beschluss 2017/39). Weiterhin kann xdomea für den Austausch zwischen Fachverfahren und DMS/VBS sowie für die Zwischenarchivierung genutzt werden. + +Um diese Anwendungsszenarien bestmöglich zu unterstützen, ist xdomea gemäß des XÖV-Rahmenwerkes nach dem Baukastenprinzip aufgebaut und bietet einzelne Nachrichten(gruppen) für die jeweiligen Prozesse an. + +Der Standard xdomea wird von der gleichnamigen Arbeitsgruppe des IT-Planungsrates weiterentwickelt und gepflegt. Der Betrieb des Standards erfolgt durch die Koordinierungsstelle für IT-Standards (KoSIT). +</beschreibung> + </standard> + <versionStandard> + <version>3.0.0</version> + <beschreibung>Die Version 3.0.0 ist durch den IT-Planungsrat beschlossen. Details zum Beschluss sowie zu den Fristen der Umsetzung sind der Veröffentlichung im Bundesanzeiger unter www.bundesanzeiger.de zu entnehmen.</beschreibung> + <versionXOEVProfil>1.7.2</versionXOEVProfil> + <versionXOEVHandbuch>2.3.1</versionXOEVHandbuch> + <versionXGenerator>3.0.1</versionXGenerator> + <versionModellierungswerkzeug>19.0</versionModellierungswerkzeug> + <nameModellierungswerkzeug>MagicDraw</nameModellierungswerkzeug> + </versionStandard> + </xs:appinfo> + </xs:annotation> + <xs:include schemaLocation="xdomea-Nachrichten-ZwischenarchivierungDurchfuehren.xsd"/> +</xs:schema> diff --git a/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Typen-AbgabeDurchfuehren.xsd b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Typen-AbgabeDurchfuehren.xsd new file mode 100644 index 0000000000000000000000000000000000000000..0b9e7a335c364ff7ac019f5a98991a9588d0f491 --- /dev/null +++ b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Typen-AbgabeDurchfuehren.xsd @@ -0,0 +1,97 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xdomea="urn:xoev-de:xdomea:schema:3.0.0" + targetNamespace="urn:xoev-de:xdomea:schema:3.0.0" + version="3.0.0" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> + <xs:annotation> + <xs:appinfo> + <standard> + <nameLang>xdomea - XÖV-Standard für den IT-gestützten Austausch und die IT-gestützte Aussonderung behördlichen Schriftgutes</nameLang> + <nameKurz>xdomea</nameKurz> + <nameTechnisch>xdomea</nameTechnisch> + <kennung>urn:xoev-de:xdomea:kosit:standard:xdomea</kennung> + <beschreibung>xdomea ist der vom IT-Planungsrat verabschiedete verbindliche Standard für den Austausch von Akten, Vorgängen und Dokumenten im Kontext der Übermittlung, der Abgabe sowie der Aussonderung von Schriftgutobjekten (www.it-planungsrat.de, Beschluss 2017/39). Weiterhin kann xdomea für den Austausch zwischen Fachverfahren und DMS/VBS sowie für die Zwischenarchivierung genutzt werden. + +Um diese Anwendungsszenarien bestmöglich zu unterstützen, ist xdomea gemäß des XÖV-Rahmenwerkes nach dem Baukastenprinzip aufgebaut und bietet einzelne Nachrichten(gruppen) für die jeweiligen Prozesse an. + +Der Standard xdomea wird von der gleichnamigen Arbeitsgruppe des IT-Planungsrates weiterentwickelt und gepflegt. Der Betrieb des Standards erfolgt durch die Koordinierungsstelle für IT-Standards (KoSIT). +</beschreibung> + </standard> + <versionStandard> + <version>3.0.0</version> + <beschreibung>Die Version 3.0.0 ist durch den IT-Planungsrat beschlossen. Details zum Beschluss sowie zu den Fristen der Umsetzung sind der Veröffentlichung im Bundesanzeiger unter www.bundesanzeiger.de zu entnehmen.</beschreibung> + <versionXOEVProfil>1.7.2</versionXOEVProfil> + <versionXOEVHandbuch>2.3.1</versionXOEVHandbuch> + <versionXGenerator>3.0.1</versionXGenerator> + <versionModellierungswerkzeug>19.0</versionModellierungswerkzeug> + <nameModellierungswerkzeug>MagicDraw</nameModellierungswerkzeug> + </versionStandard> + </xs:appinfo> + </xs:annotation> + <xs:include schemaLocation="xdomea-Baukasten.xsd"/> + <xs:complexType name="ErfolgOderMisserfolgAbgabeType"> + <xs:annotation> + <xs:appinfo> + <title>ErfolgOderMisserfolgAbgabe</title> + </xs:appinfo> + <xs:documentation>Die Information zum erfolgreichen oder nicht erfolgreichen Import eines abzugebenden Schriftgutobjektes.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="IDSGO" type="xdomea:stringUUIDType"> + <xs:annotation> + <xs:documentation>Die ID des Schriftgutobjekts, das abgegeben werden sollte.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Erfolgreich" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Die Kennzeichnung des erfolgreichen oder nicht erfolgreichen Imports zu einem abzugebenden Schriftgutobjekt. Der erfolgreiche Import wird mit 1 und der nicht erfolgreiche Import mit 0 gekennzeichnet.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Fehlermeldung" + minOccurs="0" + maxOccurs="unbounded" + type="xs:string"> + <xs:annotation> + <xs:documentation>Die Information in Form eines Freitextes, aus welchem Grund der Import zum abzugebenden Schriftgutobjekt nicht erfolgreich war.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="FehlermeldungCode" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:SonstigeFehlermeldungCodeType"> + <xs:annotation> + <xs:documentation>Die Information in Form eines Codes, aus welchem Grund der Import zum abzugebenden Schriftgutobjekt nicht erfolgreich war.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="NkAbgabeType"> + <xs:annotation> + <xs:appinfo> + <title>NkAbgabe</title> + </xs:appinfo> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger einer Nachricht, bei der es sich um eine Abgabe handelt.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:extension base="xdomea:NkNichtFVDatenWeitereEmpfaengerType"> + <xs:sequence> + <xs:element name="Importbestaetigung" fixed="1" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Die Angabe, dass eine Importbestätigung vom Empfänger der Nachricht erwünscht wird.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Empfangsbestaetigung" type="xs:boolean"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Für die Umsetzung in den Systemen wird empfohlen, sofern kein anderer Wert hinterlegt wurde, als Standardwert den Wert 0 für "keine Empfangsbestätigung senden" anzugeben.</implementationHint> + </xs:appinfo> + <xs:documentation>Die Angabe, ob vom Empfänger der Nachricht eine Empfangsbestätigung erwünscht wird. Eine erwünschte Empfangsbestätigung wird mit 1 gekennzeichnet. Wird keine Empfangsbestätigung gewünscht, so wird dies mit 0 gekennzeichnet.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> +</xs:schema> diff --git a/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Typen-AussonderungDurchfuehren.xsd b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Typen-AussonderungDurchfuehren.xsd new file mode 100644 index 0000000000000000000000000000000000000000..434d076a81bdb44f0dd9f85672767c26d0d06d05 --- /dev/null +++ b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Typen-AussonderungDurchfuehren.xsd @@ -0,0 +1,237 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xdomea="urn:xoev-de:xdomea:schema:3.0.0" + targetNamespace="urn:xoev-de:xdomea:schema:3.0.0" + version="3.0.0" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> + <xs:annotation> + <xs:appinfo> + <standard> + <nameLang>xdomea - XÖV-Standard für den IT-gestützten Austausch und die IT-gestützte Aussonderung behördlichen Schriftgutes</nameLang> + <nameKurz>xdomea</nameKurz> + <nameTechnisch>xdomea</nameTechnisch> + <kennung>urn:xoev-de:xdomea:kosit:standard:xdomea</kennung> + <beschreibung>xdomea ist der vom IT-Planungsrat verabschiedete verbindliche Standard für den Austausch von Akten, Vorgängen und Dokumenten im Kontext der Übermittlung, der Abgabe sowie der Aussonderung von Schriftgutobjekten (www.it-planungsrat.de, Beschluss 2017/39). Weiterhin kann xdomea für den Austausch zwischen Fachverfahren und DMS/VBS sowie für die Zwischenarchivierung genutzt werden. + +Um diese Anwendungsszenarien bestmöglich zu unterstützen, ist xdomea gemäß des XÖV-Rahmenwerkes nach dem Baukastenprinzip aufgebaut und bietet einzelne Nachrichten(gruppen) für die jeweiligen Prozesse an. + +Der Standard xdomea wird von der gleichnamigen Arbeitsgruppe des IT-Planungsrates weiterentwickelt und gepflegt. Der Betrieb des Standards erfolgt durch die Koordinierungsstelle für IT-Standards (KoSIT). +</beschreibung> + </standard> + <versionStandard> + <version>3.0.0</version> + <beschreibung>Die Version 3.0.0 ist durch den IT-Planungsrat beschlossen. Details zum Beschluss sowie zu den Fristen der Umsetzung sind der Veröffentlichung im Bundesanzeiger unter www.bundesanzeiger.de zu entnehmen.</beschreibung> + <versionXOEVProfil>1.7.2</versionXOEVProfil> + <versionXOEVHandbuch>2.3.1</versionXOEVHandbuch> + <versionXGenerator>3.0.1</versionXGenerator> + <versionModellierungswerkzeug>19.0</versionModellierungswerkzeug> + <nameModellierungswerkzeug>MagicDraw</nameModellierungswerkzeug> + </versionStandard> + </xs:appinfo> + </xs:annotation> + <xs:include schemaLocation="xdomea-Baukasten.xsd"/> + <xs:complexType name="AktenplanBewertungskatalogType"> + <xs:annotation> + <xs:appinfo> + <title>AktenplanBewertungskatalog</title> + </xs:appinfo> + <xs:documentation>Der Aktenplan enthält ein aufgabenbezogenes mehrstufiges Ordnungssystem mit einer hierarchischen Gliederung für das Bilden und Kennzeichnen von Akten und Vorgängen sowie das Zuordnen von Dokumenten.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="ID" type="xdomea:stringUUIDType"> + <xs:annotation> + <xs:documentation>Die UUID des Aktenplans.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Bezeichnung" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Name des Aktenplans.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Typ" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Typ des Aktenplans, z.B. Teilaktenplan.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Version" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Version des Aktenplans.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Einheit" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:AktenplaneinheitAktenplanBewertungskatalogType"> + <xs:annotation> + <xs:documentation>Die Einheit eines Aktenplans, die Auskunft über die hierarchische Strukturierung eines Aktenplans gibt. Eine Aktenplanheit entspricht z.B. einer Hauptgruppe, Obergruppe, Gruppe, Untergruppe oder Betreffseinheit.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Gueltigkeit" minOccurs="0" type="xdomea:ZeitraumType"> + <xs:annotation> + <xs:documentation>Die Gültigkeit des Aktenplans mit Beginn und Ende.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Aktenplandatei" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:FormatType"> + <xs:annotation> + <xs:documentation>Die Datei zum Aktenplan als Primärdokument.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="AktenplaneinheitAktenplanBewertungskatalogType"> + <xs:annotation> + <xs:appinfo> + <title>AktenplaneinheitAktenplanBewertungskatalog</title> + </xs:appinfo> + <xs:documentation>Eine Aktenplaneinheit gibt Auskunft über die hierarchische Strukturierung eines Aktenplans. Eine Aktenplanheit entspricht z.B. einer Hauptgruppe, Obergruppe, Gruppe, Untergruppe oder Betreffseinheit.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="ID" type="xdomea:stringUUIDType"> + <xs:annotation> + <xs:documentation>Die UUID der Aktenplaneinheit.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Aussonderungsart" type="xdomea:AussonderungsartType"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Die Aussonderungsart vererbt sich auf alle unter einer Hierarchiestufe angelegten Schriftgutobjekte.</implementationHint> + </xs:appinfo> + <xs:documentation>Die Aussonderungsart gibt das Ergebnis der archivischen Bewertung an. Die Aussonderungsart wird vom Aktenplan (zweistufiges Aussonderungsverfahren) auf zugehörige Akten und Vorgänge vererbt.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="ErfolgOderMisserfolgAussonderungType"> + <xs:annotation> + <xs:appinfo> + <title>ErfolgOderMisserfolgAussonderung</title> + </xs:appinfo> + <xs:documentation>Die Information zum erfolgreichen oder nicht erfolgreichen Import eines auszusondernden Schriftgutobjekts.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="IDSGO" type="xdomea:stringUUIDType"> + <xs:annotation> + <xs:documentation>Die ID des Schriftgutobjekts, das ausgesondert werden sollte.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Erfolgreich" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Die Kennzeichnung des erfolgreichen oder nicht erfolgreichen Imports der Aussonderung zu einem Schriftgutobjekt. Der erfolgreiche Import wird mit 1 und der nicht erfolgreiche Import mit 0 gekennzeichnet.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Fehlermeldung" + minOccurs="0" + maxOccurs="unbounded" + type="xs:string"> + <xs:annotation> + <xs:documentation>Erläuterung des Grundes als Freitext für den nicht erfolgreichen Import einer Aussonderung zu einem Schriftgutobjekt.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="FehlermeldungCode" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:SonstigeFehlermeldungCodeType"> + <xs:annotation> + <xs:documentation>Erläuterung des Grundes als Code für den nicht erfolgreichen Import einer Aussonderung zu einem Schriftgutobjekt.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Archivkennung" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die ID, unter der das ausgesonderte Schriftgutobjekt im Archiv verwahrt wird. Für den Fall, dass "Erfolgreich" positiv belegt ist und von der aussondernden Behörde die Rückgabe der Archivkennungen gewünscht ist ("RueckmeldungArchivkennung" ist positiv belegt), können durch das archivierende System die Archivkennungen zu den einzelnen Schriftgutobjekt übergeben werden.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="ErfolgOderMisserfolgBewertungskatalogType"> + <xs:annotation> + <xs:appinfo> + <title>ErfolgOderMisserfolgBewertungskatalog</title> + </xs:appinfo> + <xs:documentation>Die Information zum erfolgreichen oder nicht erfolgreichen Import einer zu bewertenden Aktenplaneinheit.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="ID" type="xdomea:stringUUIDType"> + <xs:annotation> + <xs:documentation>Die ID der Aktenplaneinheit, die bewertet werden sollte.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Erfolgreich" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Die Kennzeichnung des erfolgreichen oder nicht erfolgreichen Imports der Bewertung zu einer Aktenplaneinheit. Der erfolgreiche Import wird mit 1 und der nicht erfolgreiche Import mit 0 gekennzeichnet.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Fehlermeldung" + minOccurs="0" + maxOccurs="unbounded" + type="xs:string"> + <xs:annotation> + <xs:documentation>Erläuterung des Grundes als Freitext für den nicht erfolgreichen Import einer Bewertung zu einer Aktenplaneinheit.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="FehlermeldungCode" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:SonstigeFehlermeldungCodeType"> + <xs:annotation> + <xs:documentation>Erläuterung des Grundes als Code für den nicht erfolgreichen Import einer Bewertung zu einer Aktenplaneinheit.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="NkAussonderungType"> + <xs:annotation> + <xs:appinfo> + <title>NkAussonderung</title> + </xs:appinfo> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger einer Nachricht, bei der es sich um die konkrete Aussonderung handelt.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:extension base="xdomea:NkBasisType"> + <xs:sequence> + <xs:element name="Importbestaetigung" fixed="1" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Die Angabe, dass eine Importbestätigung vom Empfänger der Nachricht erwünscht wird.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="RueckmeldungArchivkennung" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Die Angabe, ob die Rückübermittlung der Archivsignaturen vom Empfänger erwünscht wird. Sollen die Archivsignaturen übermittelt werden, so ist der Wert 1 anzugeben. Sollen keine Archivsignaturen übermittelt werden, so ist der Wert 0 anzugeben.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Empfangsbestaetigung" type="xs:boolean"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Für die Umsetzung in den Systemen wird empfohlen, sofern kein anderer Wert hinterlegt wurde, als Standardwert den Wert 0 für "keine Empfangsbestätigung senden" anzugeben.</implementationHint> + </xs:appinfo> + <xs:documentation>Die Angabe, ob vom Empfänger der Nachricht eine Empfangsbestätigung erwünscht wird. Eine erwünschte Empfangsbestätigung wird mit 1 gekennzeichnet. Wird keine Empfangsbestätigung gewünscht, so wird dies mit 0 gekennzeichnet.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="RueckgabeparameterAnbietungType"> + <xs:annotation> + <xs:appinfo> + <title>RueckgabeparameterAnbietung</title> + </xs:appinfo> + <xs:documentation>Die Rückmeldung des Archivs zu einem zur Bewertung übergegebenen Schriftgutobjekt zur Steuerung des weiteren Aussonderungsprozesses.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="ID" type="xdomea:stringUUIDType"> + <xs:annotation> + <xs:documentation>Die UUID des angebotenen Schriftgutobjektes, in der Regel die eines Vorgangs.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Aussonderungsart" type="xdomea:AussonderungsartType"> + <xs:annotation> + <xs:documentation>Die Beschreibung des Bewertungsergebnisses für ein angebotenes Schriftgutobjekt.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> +</xs:schema> diff --git a/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Typen-FachverfahrensdatenAustauschen.xsd b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Typen-FachverfahrensdatenAustauschen.xsd new file mode 100644 index 0000000000000000000000000000000000000000..118adb112c056b51430e34c9f4d08916fff1e8f4 --- /dev/null +++ b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Typen-FachverfahrensdatenAustauschen.xsd @@ -0,0 +1,1392 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xdomea="urn:xoev-de:xdomea:schema:3.0.0" + targetNamespace="urn:xoev-de:xdomea:schema:3.0.0" + version="3.0.0" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> + <xs:annotation> + <xs:appinfo> + <standard> + <nameLang>xdomea - XÖV-Standard für den IT-gestützten Austausch und die IT-gestützte Aussonderung behördlichen Schriftgutes</nameLang> + <nameKurz>xdomea</nameKurz> + <nameTechnisch>xdomea</nameTechnisch> + <kennung>urn:xoev-de:xdomea:kosit:standard:xdomea</kennung> + <beschreibung>xdomea ist der vom IT-Planungsrat verabschiedete verbindliche Standard für den Austausch von Akten, Vorgängen und Dokumenten im Kontext der Übermittlung, der Abgabe sowie der Aussonderung von Schriftgutobjekten (www.it-planungsrat.de, Beschluss 2017/39). Weiterhin kann xdomea für den Austausch zwischen Fachverfahren und DMS/VBS sowie für die Zwischenarchivierung genutzt werden. + +Um diese Anwendungsszenarien bestmöglich zu unterstützen, ist xdomea gemäß des XÖV-Rahmenwerkes nach dem Baukastenprinzip aufgebaut und bietet einzelne Nachrichten(gruppen) für die jeweiligen Prozesse an. + +Der Standard xdomea wird von der gleichnamigen Arbeitsgruppe des IT-Planungsrates weiterentwickelt und gepflegt. Der Betrieb des Standards erfolgt durch die Koordinierungsstelle für IT-Standards (KoSIT). +</beschreibung> + </standard> + <versionStandard> + <version>3.0.0</version> + <beschreibung>Die Version 3.0.0 ist durch den IT-Planungsrat beschlossen. Details zum Beschluss sowie zu den Fristen der Umsetzung sind der Veröffentlichung im Bundesanzeiger unter www.bundesanzeiger.de zu entnehmen.</beschreibung> + <versionXOEVProfil>1.7.2</versionXOEVProfil> + <versionXOEVHandbuch>2.3.1</versionXOEVHandbuch> + <versionXGenerator>3.0.1</versionXGenerator> + <versionModellierungswerkzeug>19.0</versionModellierungswerkzeug> + <nameModellierungswerkzeug>MagicDraw</nameModellierungswerkzeug> + </versionStandard> + </xs:appinfo> + </xs:annotation> + <xs:include schemaLocation="xdomea-Baukasten.xsd"/> + <xs:complexType name="BearbeitungFVType"> + <xs:annotation> + <xs:appinfo> + <title>BearbeitungFV</title> + </xs:appinfo> + <xs:documentation>BearbeitungFV enthält Angaben zur Bearbeitung eines Schriftgutobjekts mit der Möglichkeit, den Bearbeiter, den Bearbeitungszeitpunkt und eine Notiz mitzugeben.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Bearbeiter" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Person, die die Bearbeitung vorgenommen hat. Wird die Bearbeitung automatisch durch das System und nicht manuell durch eine Person vorgenommen, so ist das entsprechende System anzugeben.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Datum" type="xs:date"> + <xs:annotation> + <xs:documentation>Das Datum der zu protokollierenden Bearbeitung.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Uhrzeit" minOccurs="0" type="xs:time"> + <xs:annotation> + <xs:documentation>Der Zeitpunkt der zu protokollierenden Bearbeitung.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Notiz" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Anmerkung, die Aufschluss über die durchgeführte(n) Aktion(en) während einer Bearbeitung gibt.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="DatensatzZumLoeschenType"> + <xs:annotation> + <xs:appinfo> + <title>DatensatzZumLoeschen</title> + </xs:appinfo> + <xs:documentation>DatensatzZumLoeschen enthält Informationen zu einem FV-Datensatz, zu dem die entsprechenden Objekte im DMS gelöscht werden sollen. Wird die Nachricht im Stapelbetrieb übergeben, so erfolgt hier zusätzlich die Übergabe der Nummer im Stapel zu jedem angegebenen FV-Datensatz.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="NummerImStapel" minOccurs="0" type="xs:unsignedInt"> + <xs:annotation> + <xs:documentation>Die Nummer des übergebenen Elements im Stapel. Anhand dieser Nummer können im Rückmeldestapel die Rückmeldungen den einzelnen Elementen im Stapel zugeordnet werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="FachverfahrenDatensatzID" type="xs:string"> + <xs:annotation> + <xs:documentation>Die ID des Datensatzes im Fachverfahren.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="DokumentZumAktualisierenType"> + <xs:annotation> + <xs:appinfo> + <title>DokumentZumAktualisieren</title> + </xs:appinfo> + <xs:documentation>DokumentZumAktualisieren enthält Informationen zu einem Dokument (z.B. Ablageort), dessen Daten im empfangenden System aktualisiert werden sollen. Wird die Nachricht im Stapelbetrieb übergeben, so erfolgt hier zusätzlich die Übergabe der Nummer im Stapel zu jedem angegebenen Dokument.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="NummerImStapel" minOccurs="0" type="xs:unsignedInt"> + <xs:annotation> + <xs:documentation>Die Nummer des übergebenen Elements im Stapel. Anhand dieser Nummer können im Rückmeldestapel die Rückmeldungen den einzelnen Elementen im Stapel zugeordnet werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="IDDokument" type="xs:string"> + <xs:annotation> + <xs:documentation>ID des zu aktualisierenden Dokumentes im DMS, die dem Fachverfahren beim Anlegen des Dokuments vom DMS mitgeteilt wurde.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Ablageort" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Ablageort des Schriftgutobjekts, das im DMS abgelegt werden soll. Die Primärdokumente zu Dokumenten finden sich in Dateien, die durch Primaerdokument.Dateiname spezifiziert werden. In Abhängigkeit des Konfigurationsparameters Datenaustauschart kann dieser Parameter unterschiedliche Werte annehmen: Übergabe über ein freigegebenes Verzeichnis: Name des Verzeichnisses. Übergabe per WebDAV und http(s): URL. Übergabe über eine Datenbank: der Parameter bleibt leer (bzw. wird ignoriert).</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="NeueVersionErstellen" minOccurs="0" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Über NeueVersionErstellen kann die Erzeugung einer neuen Version erzwungen werden. Wird kein Wert für diesen Parameter oder der Wert 0 angegeben, so wird keine neue Version erzeugt. Soll die Erzeugung einer neuen Version über diesen Parameter erzwungen werden, so ist der Wert 1 anzugeben.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Dokument" type="xdomea:DokumentType"> + <xs:annotation> + <xs:documentation>Das Dokument, das aktualisiert werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="DokumentZumExportierenType"> + <xs:annotation> + <xs:appinfo> + <title>DokumentZumExportieren</title> + </xs:appinfo> + <xs:documentation>DokumentZumExportieren enthält Informationen zu den Primärdokumenten eines Schriftgutobjekts (Dokument), die in einem DMS abgelegt wurden und in das empfangende Fachverfahren exportiert werden sollen.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="IDSGO" type="xdomea:stringUUIDType"> + <xs:annotation> + <xs:documentation>Die ID des Schriftgutobjekts im DMS, zu dem Primärdokumente exportiert werden sollen.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Versionsnummer" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Wird keine Versionsnummer übergeben, so wird der aktuelle Stand des Dokuments exportiert.</implementationHint> + </xs:appinfo> + <xs:documentation>Die Versionsnummer des Dokuments.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="ErfolgOderMisserfolgDMSType"> + <xs:annotation> + <xs:appinfo> + <title>ErfolgOderMisserfolgDMS</title> + <implementationHint>Es ist durch die Implementierer darauf zu achten, dass Rückmeldungen auf der Nachrichtenebene mit denen auf der Parameterebene in Einklang stehen und ihnen nicht widersprechen.</implementationHint> + </xs:appinfo> + <xs:documentation>Die Information zum erfolgreichen oder nicht erfolgreichen Import von Daten.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Rueckmeldung" maxOccurs="unbounded"> + <xs:annotation> + <xs:documentation>Die Beschreibung der Rückmeldungsart, die zu dem Import der empfangenen Daten an das sendende System zurückübermittelt wird.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:choice> + <xs:element name="AllgemeineRueckmeldung" + type="xdomea:AllgemeineRueckmeldungCodeType"> + <xs:annotation> + <xs:documentation>Eine allgemeine Rückmeldung, z.B. Verbindungsabbruch, Übertragungsfehler.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0601" + type="xdomea:SpezifischeFehlermeldung0601CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0601.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0602" + type="xdomea:SpezifischeFehlermeldung0602CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0602.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0603" + type="xdomea:SpezifischeFehlermeldung0603CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0603.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0604" + type="xdomea:SpezifischeFehlermeldung0604CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0604.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0605" + type="xdomea:SpezifischeFehlermeldung0605CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0605.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0606" + type="xdomea:SpezifischeFehlermeldung0606CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0606.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0607" + type="xdomea:SpezifischeFehlermeldung0607CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0607.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0608" + type="xdomea:SpezifischeFehlermeldung0608CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0608.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0609" + type="xdomea:SpezifischeFehlermeldung0609CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0609.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0610" + type="xdomea:SpezifischeFehlermeldung0610CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0610.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0611" + type="xdomea:SpezifischeFehlermeldung0611CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0611.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0612" + type="xdomea:SpezifischeFehlermeldung0612CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0612.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0613" + type="xdomea:SpezifischeFehlermeldung0613CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0613.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0614" + type="xdomea:SpezifischeFehlermeldung0614CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0614.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0615" + type="xdomea:SpezifischeFehlermeldung0615CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0615.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0616" + type="xdomea:SpezifischeFehlermeldung0616CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0616.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0617" + type="xdomea:SpezifischeFehlermeldung0617CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0617.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0618" + type="xdomea:SpezifischeFehlermeldung0618CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0618.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0619" + type="xdomea:SpezifischeFehlermeldung0619CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0619.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0620" + type="xdomea:SpezifischeFehlermeldung0620CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0620.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0621" + type="xdomea:SpezifischeFehlermeldung0621CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0621.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0622" + type="xdomea:SpezifischeFehlermeldung0622CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0622.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0623" + type="xdomea:SpezifischeFehlermeldung0623CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0623.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0624" + type="xdomea:SpezifischeFehlermeldung0624CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0624.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0625" + type="xdomea:SpezifischeFehlermeldung0625CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0625.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0626" + type="xdomea:SpezifischeFehlermeldung0626CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0626.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0627" + type="xdomea:SpezifischeFehlermeldung0627CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0627.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0628" + type="xdomea:SpezifischeFehlermeldung0628CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0628.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0631" + type="xdomea:SpezifischeFehlermeldung0631CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0631.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0632" + type="xdomea:SpezifischeFehlermeldung0632CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0632.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SonstigeFehlermeldung" type="xs:string"> + <xs:annotation> + <xs:documentation>Eine sonstige, nicht näher definierte Fehlermeldung, die als Freitext formuliert werden kann.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SonstigeFehlermeldungCode" + type="xdomea:SonstigeFehlermeldungCodeType"> + <xs:annotation> + <xs:documentation>Eine sonstige, nicht näher in xdomea definierte Fehlermeldung, die als Code angegeben werden kann.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:choice> + </xs:complexType> + </xs:element> + <xs:element name="Rueckgabeparameter" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:RueckgabeparameterFVDatenType"> + <xs:annotation> + <xs:documentation>Die Beschreibung der Daten, die bei einem erfolgreichen oder nicht erfolgreichen Import der empfangenen Daten an das sendende System zurückübermittelt werden.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="GesamtprotokollZumAblegenType"> + <xs:annotation> + <xs:appinfo> + <title>GesamtprotokollZumAblegen</title> + </xs:appinfo> + <xs:documentation>GesamtprotokollZumAblegen beschreibt alle aktenrelevanten Bearbeitungs- und Protokollinformationen zu einem Schriftgutobjekt, die aus einem Fachverfahren in einem DMS abzulegen sind. Wird die Nachricht im Stapelbetrieb übergeben, so erfolgt hier zusätzlich die Übergabe der Nummer im Stapel zu jedem angegebenen Gesamtprotokoll.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="NummerImStapel" minOccurs="0" type="xs:unsignedInt"> + <xs:annotation> + <xs:documentation>Die Nummer des übergebenen Elements im Stapel. Anhand dieser Nummer können im Rückmeldestapel die Rückmeldungen den einzelnen Elementen im Stapel zugeordnet werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="IDSGO" type="xdomea:stringUUIDType"> + <xs:annotation> + <xs:documentation>Die ID des Schriftgutobjektes im DMS.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Ablageort" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Ablageort des Schriftgutobjekts, das im DMS abgelegt werden soll. Die Primärdokumente zu Dokumenten finden sich in Dateien, die durch Primaerdokument.Dateiname spezifiziert werden. In Abhängigkeit des Konfigurationsparameters Datenaustauschart kann dieser Parameter unterschiedliche Werte annehmen: Übergabe über ein freigegebenes Verzeichnis: Name des Verzeichnisses. Übergabe per WebDAV und http(s): URL. Übergabe über eine Datenbank: der Parameter bleibt leer (bzw. wird ignoriert).</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Dokument" minOccurs="0" type="xdomea:DokumentType"> + <xs:annotation> + <xs:documentation>Das Gesamtprotokoll als Dokument.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Geschaeftsgang" + minOccurs="0" + type="xdomea:GeschaeftsgangType"> + <xs:annotation> + <xs:documentation>Die Bearbeitungsinformationen im Rahmen eines Geschäftsgangs zu dem Schriftgutobjekt.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="HistorienProtokollInformation" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:HistorienProtokollInformationType"> + <xs:annotation> + <xs:documentation>Die Bearbeitungs- und Protokollinformationen eines Schriftgutobjekts.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="KonfigurationsparameterType"> + <xs:annotation> + <xs:appinfo> + <title>Konfigurationsparameter</title> + </xs:appinfo> + <xs:documentation>Ein Parameter zur Konfiguration eines anderen Systems.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Parameter" type="xdomea:KonfigurationsparameterCodeType"> + <xs:annotation> + <xs:documentation>Der Name des Konfigurationsparameters.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Datentyp" minOccurs="0" type="xdomea:DatentypCodeType"> + <xs:annotation> + <xs:documentation>Der Datentyp des Konfigurationsparameters.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Wert" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Für einen zu erstellenden Konfigurationsparameter muss der Wert zwingend übergeben werden.</implementationHint> + </xs:appinfo> + <xs:documentation>Der Wert des Konfigurationsparameters.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:choice> + <xs:element name="WertOffen" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Wert ist nicht näher definiert und kann als Freitext übermittelt werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Transportweg" type="xdomea:TransportwegCodeType"> + <xs:annotation> + <xs:documentation>Es handelt sich bei dem Wert des Konfigurationsparameters um einen Transportweg.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Datenaustauschart" type="xdomea:DatenaustauschartCodeType"> + <xs:annotation> + <xs:documentation>Es handelt sich bei dem Wert des Konfigurationsparameters um eine Datenaustauschart.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="KomprimierterDatenaustausch" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Es handelt sich bei dem Wert des Konfigurationsparameters um die Aussage zum komprimierten Datenaustausch. Findet eine Komprimierung der Daten statt, so ist der Wert 1 anzugeben. Findet keine Datenkomprimierung statt, so ist der Wert 0 anzugeben.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Kompressionsverfahren" + type="xdomea:KompressionsverfahrenCodeType"> + <xs:annotation> + <xs:documentation>Es handelt sich bei dem Wert des Konfigurationsparameters um ein Kompressionsverfahren.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Standardablage" type="xdomea:StandardablageType"> + <xs:annotation> + <xs:documentation>Es handelt sich bei dem Wert des Konfigurationsparameters um Angaben zur Standardablage.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:choice> + </xs:complexType> + </xs:element> + <xs:element name="Gruppe" type="xdomea:KonfigurationsparameterGruppeCodeType"> + <xs:annotation> + <xs:documentation>Die Gruppe von Parametern, zu der der Konfigurationsparameter gehört.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="KonfigurationsparameterZumAbrufenType"> + <xs:annotation> + <xs:appinfo> + <title>KonfigurationsparameterZumAbrufen</title> + </xs:appinfo> + <xs:documentation>Der Name eines Konfigurationsparameters, der abgerufen werden soll.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:restriction base="xdomea:FeldType"> + <xs:sequence> + <xs:element name="Name" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Name des Feldes.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:restriction> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="KonfigurationsparameterZumErstellenType"> + <xs:annotation> + <xs:appinfo> + <title>KonfigurationsparameterZumErstellen</title> + <implementationHint>Je nach Anwendungsfall ist mindestens eines der Elemente Konfigurationsparameter bzw. DefinierterKonfigurationsparameter mit Daten zu befüllen.</implementationHint> + </xs:appinfo> + <xs:documentation>Die Zusammenfassung von Konfigurationsparametern, die durch einen Benutzer oder eine Rolle erstellt werden sollen.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="BenutzerOderRolle" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Benutzer oder die Rolle, der/die den/die Konfigurationsparameter erstellt hat.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="DefinierterKonfigurationsparameter" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:KonfigurationsparameterType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem (den) zu erstellenden Konfigurationsparameter(n), die bereits näher klassifiziert sind.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Konfigurationsparameter" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:FeldType"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Für einen zu erstellenden Konfigurationsparameter muss der Wert zwingend übergeben werden.</implementationHint> + </xs:appinfo> + <xs:documentation>Die Informationen zu dem (den) zu erstellenden Konfigurationsparameter(n).</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="MetadatenZumBearbeitenType"> + <xs:annotation> + <xs:appinfo> + <title>MetadatenZumBearbeiten</title> + </xs:appinfo> + <xs:documentation>Die Zusammenfassung von Metadaten, die zu einem Schriftgutobjekt bearbeitet werden sollen. Wird die Nachricht im Stapelbetrieb übergeben, so erfolgt hier zusätzlich die Übergabe der Nummer im Stapel zu jedem angegebenen Metadatum.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="NummerImStapel" minOccurs="0" type="xs:unsignedInt"> + <xs:annotation> + <xs:documentation>Die Nummer des übergebenen Elements im Stapel. Anhand dieser Nummer können im Rückmeldestapel die Rückmeldungen den einzelnen Elementen im Stapel zugeordnet werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="IDSGO" type="xdomea:stringUUIDType"> + <xs:annotation> + <xs:documentation>Die ID des Schriftgutobjekts im DMS, zu dem die übergegebenen Metadaten bearbeitet werden sollen.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Metadatum" maxOccurs="unbounded" type="xdomea:FeldType"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Für ein anzulegendes Metadatum müssen der Datentyp und der Wert zwingend übergeben werden. Für ein zu aktualisierendes Metadatum muss der Wert zwingend übergeben werden. Die Beschreibung und der Datentyp sollten nicht übergeben werden, da sie meist nicht geändert werden.</implementationHint> + </xs:appinfo> + <xs:documentation>Die Informationen zu einem zu bearbeitenden Metadatum, das nicht in xdomea vordefiniert ist.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="NkKeineRueckmeldungFVDatenType"> + <xs:annotation> + <xs:appinfo> + <title>NkKeineRueckmeldungFVDaten</title> + </xs:appinfo> + <xs:documentation>Der Kopf für Nachrichten von einem Fachverfahren zu einem DMS bzw. zu einem Fachverfahren enthält allgemeine Informationen für die Bereitstellung der Nachricht sowie für den Empfänger der Nachricht selbst.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:extension base="xdomea:NkFVDatenType"> + <xs:sequence> + <xs:element name="WeiteresEmpfangendesSystem" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:SystemType"> + <xs:annotation> + <xs:documentation>Die Informationen zu dem System, das ebenfalls die Daten erhalten soll.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Empfangsbestaetigung" type="xs:boolean"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Für die Umsetzung in den Systemen wird empfohlen, sofern kein anderer Wert hinterlegt wurde, als Standardwert den Wert 0 für "keine Empfangsbestätigung senden" anzugeben.</implementationHint> + </xs:appinfo> + <xs:documentation>Die Angabe, ob vom Empfänger der Nachricht eine Empfangsbestätigung erwünscht wird. Eine erwünschte Empfangsbestätigung wird mit 1 gekennzeichnet. Wird keine Empfangsbestätigung gewünscht, so wird dies mit 0 gekennzeichnet.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Importbestaetigung" fixed="1" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Die Angabe, dass eine Importbestätigung vom Empfänger der Nachricht erwünscht wird.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Erstellerkennung" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Benutzerkennung des Nachrichtenerstellers.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="ErstellerRolle" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Rolle des Nachrichtenerstellers.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Stapel" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Stapel gibt an, ob die Nachricht mehrere Objekte in der Stapelverarbeitung oder ein Objekt in der Einzelverarbeitung übergibt. Soll eine Stapelverarbeitung erfolgen, so ist der Wert 1 anzugeben. Soll eine Einzelverarbeitung erfolgen, so ist der Wert 0 anzugeben.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Stapellaenge" minOccurs="0" type="xs:unsignedInt"> + <xs:annotation> + <xs:documentation>Die Länge des Stapels.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="DMSSessionID" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die DMS-Session-ID wird verwendet, um den Benutzer bzw. die Rolle gegenüber dem DMS zu authentifizieren. Sie wird bei der Anmeldung im DMS erzeugt und wird nach einer konfigurierbaren Zeit der Inaktivität ungültig.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="NkRueckmeldungFVDatenImportType"> + <xs:annotation> + <xs:appinfo> + <title>NkRueckmeldungFVDatenImport</title> + </xs:appinfo> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen zu einer Rückmeldung eines Datenimports.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:extension base="xdomea:NkFVDatenType"> + <xs:sequence> + <xs:element name="FVSessionID" type="xs:string"> + <xs:annotation> + <xs:documentation>Die FV-Session-ID wird verwendet, um den Benutzer bzw. die Rolle aus dem DMS gegenüber dem Fachverfahren zu authentifizieren. Sie wird bei der Anmeldung im Fachverfahren erzeugt und wird nach einer konfigurierbaren Zeit der Inaktivität ungültig.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="ProtokolleintragZumErstellenType"> + <xs:annotation> + <xs:appinfo> + <title>ProtokolleintragZumErstellen</title> + </xs:appinfo> + <xs:documentation>ProtokolleintragZumErstellen enthält Informationen zu einem Protokolleintrag i. S. eines Funktionsprotokolls, der zu einem Schriftgutobjekt erstellt wird. Wird die Nachricht im Stapelbetrieb übergeben, so erfolgt hier zusätzlich die Übergabe der Nummer im Stapel zu jedem angegebenen Protokolleintrag.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="NummerImStapel" minOccurs="0" type="xs:unsignedInt"> + <xs:annotation> + <xs:documentation>Die Nummer des übergebenen Elements im Stapel. Anhand dieser Nummer können im Rückmeldestapel die Rückmeldungen den einzelnen Elementen im Stapel zugeordnet werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="IDSGO" type="xdomea:stringUUIDType"> + <xs:annotation> + <xs:documentation>Die ID des Schriftgutobjekts im DMS, zu dem ein Protokolleintrag erstellt werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Protokolleintrag" type="xdomea:BearbeitungFVType"> + <xs:annotation> + <xs:documentation>Der Protokolleintrag zu dem Schriftgutobjekt.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="RueckgabeparameterFVDatenType"> + <xs:annotation> + <xs:appinfo> + <title>RueckgabeparameterFVDaten</title> + </xs:appinfo> + <xs:documentation>Die Rückmeldung des DMS zu den gelieferten Daten des Fachverfahrens.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="NummerImStapel" minOccurs="0" type="xs:unsignedInt"> + <xs:annotation> + <xs:documentation>Die Nummer des übergebenen Elements im Stapel. Anhand dieser Nummer können im Rückmeldestapel die Rückmeldungen den einzelnen Elementen im Stapel zugeordnet werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="IDSGO" minOccurs="0" type="xdomea:stringUUIDType"> + <xs:annotation> + <xs:documentation>Die ID des Schriftgutobjekts im DMS, zu dem die Rückmeldung erfolgt.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Parameter"> + <xs:annotation> + <xs:documentation>Die Informationen zum Parameterwert.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:choice> + <xs:element name="AllgemeinerRueckgabeparameter" type="xdomea:FeldType"> + <xs:annotation> + <xs:documentation>Es handelt sich bei dem Wert um einen allgemeinen, nicht näher im Standard definierten Rückgabeparameterwert.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="ZumLoeschenMarkiert" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Es handelt sich bei dem Wert um eine Löschmarkierung. Wurde ein Objekt zum Löschen markiert, so wird der Wert 1 angegeben. Wurde kein Objekt zum Löschen markiert, so wird der Wert 0 angegeben.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Vertretungsstatus" + maxOccurs="unbounded" + type="xdomea:RueckgabeparameterVertretungsstatusType"> + <xs:annotation> + <xs:documentation>Es handelt sich bei dem Wert um Angaben zu einem Vertretungsstatus.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Ablageort" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Ablageort des Schriftgutobjekts</xs:documentation> + </xs:annotation> + </xs:element> + </xs:choice> + </xs:complexType> + </xs:element> + <xs:element name="Erfolgreich" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Die Kennzeichnung des erfolgreichen oder nicht erfolgreichen Imports eines Datenelements. Der erfolgreiche Import wird mit 1 und der nicht erfolgreiche Import mit 0 gekennzeichnet.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Rueckmeldung" minOccurs="0" maxOccurs="unbounded"> + <xs:annotation> + <xs:documentation>Die Rückmeldung enthält weiterführende Informationen zu dem Import eines Datenelements, z.B. eine spezifische Fehlermeldung.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:choice> + <xs:element name="SpezifischeFehlermeldung0601" + type="xdomea:SpezifischeFehlermeldung0601CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0601.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0602" + type="xdomea:SpezifischeFehlermeldung0602CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0602.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0603" + type="xdomea:SpezifischeFehlermeldung0603CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0603.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0604" + type="xdomea:SpezifischeFehlermeldung0604CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0604.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0605" + type="xdomea:SpezifischeFehlermeldung0605CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0605.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0606" + type="xdomea:SpezifischeFehlermeldung0606CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0606.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0607" + type="xdomea:SpezifischeFehlermeldung0607CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0607.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0608" + type="xdomea:SpezifischeFehlermeldung0608CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0608.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0609" + type="xdomea:SpezifischeFehlermeldung0609CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0609.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0610" + type="xdomea:SpezifischeFehlermeldung0610CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0610.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0611" + type="xdomea:SpezifischeFehlermeldung0611CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0611.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0612" + type="xdomea:SpezifischeFehlermeldung0612CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0612.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0613" + type="xdomea:SpezifischeFehlermeldung0613CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0613.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0614" + type="xdomea:SpezifischeFehlermeldung0614CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0614.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0615" + type="xdomea:SpezifischeFehlermeldung0615CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0615.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0616" + type="xdomea:SpezifischeFehlermeldung0616CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0616.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0617" + type="xdomea:SpezifischeFehlermeldung0617CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0617.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0618" + type="xdomea:SpezifischeFehlermeldung0618CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0618.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0619" + type="xdomea:SpezifischeFehlermeldung0619CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0619.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0620" + type="xdomea:SpezifischeFehlermeldung0620CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0620.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0621" + type="xdomea:SpezifischeFehlermeldung0621CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0621.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0622" + type="xdomea:SpezifischeFehlermeldung0622CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0622.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0623" + type="xdomea:SpezifischeFehlermeldung0623CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0623.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0624" + type="xdomea:SpezifischeFehlermeldung0624CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0624.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0625" + type="xdomea:SpezifischeFehlermeldung0625CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0625.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0626" + type="xdomea:SpezifischeFehlermeldung0626CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0626.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0627" + type="xdomea:SpezifischeFehlermeldung0627CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0627.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0628" + type="xdomea:SpezifischeFehlermeldung0628CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0628.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0631" + type="xdomea:SpezifischeFehlermeldung0631CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0631.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SpezifischeFehlermeldung0632" + type="xdomea:SpezifischeFehlermeldung0632CodeType"> + <xs:annotation> + <xs:documentation>Eine spezifische Fehlermeldung für die Nachricht 0632.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SonstigeFehlermeldung" type="xs:string"> + <xs:annotation> + <xs:documentation>Eine sonstige, nicht näher definierte Fehlermeldung, die als Freitext formuliert werden kann.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SonstigeFehlermeldungCode" + type="xdomea:SonstigeFehlermeldungCodeType"> + <xs:annotation> + <xs:documentation>Eine sonstige, nicht näher in xdomea definierte Fehlermeldung, die als Code angegeben werden kann.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:choice> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="RueckgabeparameterVertretungsstatusType"> + <xs:annotation> + <xs:appinfo> + <title>RueckgabeparameterVertretungsstatus</title> + </xs:appinfo> + <xs:documentation>Informationen, die Angaben eines Rückgabeparameters zu einem Vertretungsstatus näher beschreiben.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="BenutzerOderRolle" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Benutzer oder die Rolle, für den/die der Vertretungsstatus abgefragt wird.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="VertretungAktiv" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Der Status zur Vertretung, der abgefragt wird. Für aktive Vertretungen ist der Wert 1 anzugeben, für inaktive der Wert 0.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="SchriftgutobjektZumAblegenOderErstellenType"> + <xs:annotation> + <xs:appinfo> + <title>SchriftgutobjektZumAblegenOderErstellen</title> + </xs:appinfo> + <xs:documentation>SchriftgutobjektZumAblegenOderErstellen enthält Informationen zu einem Schriftgutobjekt, das in einem Fachverfahren erstellt wurde und im empfangenden DMS abgelegt oder erstellt werden soll. Wird die Nachricht im Stapelbetrieb übergeben, so erfolgt hier zusätzlich die Übergabe der Nummer im Stapel zu jedem angegebenen Schriftgutobjekt.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="NummerImStapel" minOccurs="0" type="xs:unsignedInt"> + <xs:annotation> + <xs:documentation>Die Nummer des übergebenen Elements im Stapel. Anhand dieser Nummer können im Rückmeldestapel die Rückmeldungen den einzelnen Elementen im Stapel zugeordnet werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="FachverfahrenObjektID" type="xs:string"> + <xs:annotation> + <xs:documentation>Die ID des Schriftgutobjektes im Fachverfahren.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="IDContainer" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die ID des übergeordneten Schriftgutobjekts, in dem das Schriftgutobjekt erstellt werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Schriftgutobjekt"> + <xs:annotation> + <xs:documentation>Das Schriftgutobjekt, das abgelegt oder erstellt werden soll.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:choice> + <xs:element name="Akte" type="xdomea:AkteType"> + <xs:annotation> + <xs:documentation>Eine Akte.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Vorgang" type="xdomea:VorgangType"> + <xs:annotation> + <xs:documentation>Ein Vorgang.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Dokument" type="xdomea:DokumentType"> + <xs:annotation> + <xs:documentation>Ein Dokument.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:choice> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="SchriftgutobjektZumAblegenType"> + <xs:annotation> + <xs:appinfo> + <title>SchriftgutobjektZumAblegen</title> + </xs:appinfo> + <xs:documentation>SchriftgutobjektZumAblegen enthält Informationen zu einem Schriftgutobjekt, das in einem Fachverfahren erstellt wurde und im empfangenden DMS abgelegt werden soll.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:extension base="xdomea:SchriftgutobjektZumAblegenOderErstellenType"> + <xs:sequence> + <xs:element name="Ablageort" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Sollte als Austauschart nicht Datenbank oder XML-Datenstrom angegeben sein, so muss für den Ablageort zwingend ein Wert angegeben werden.</implementationHint> + </xs:appinfo> + <xs:documentation>Der Ablageort des Schriftgutobjekts, das im DMS abgelegt werden soll. Die Primärdokumente zu Dokumenten finden sich in Dateien, die durch Primaerdokument.Dateiname spezifiziert werden. In Abhängigkeit des Konfigurationsparameters Datenaustauschart kann dieser Parameter unterschiedliche Werte annehmen: Übergabe über ein freigegebenes Verzeichnis: Name des Verzeichnisses. Übergabe per WebDAV und http(s): URL. Übergabe über eine Datenbank: der Parameter bleibt leer (bzw. wird ignoriert).</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SchriftgutobjektZumAnsehenOderBearbeitenType"> + <xs:annotation> + <xs:appinfo> + <title>SchriftgutobjektZumAnsehenOderBearbeiten</title> + </xs:appinfo> + <xs:documentation>SchriftgutobjektZumAnsehenOderBearbeiten enthält Informationen zu einem Schriftgutobjekt, das in einem Fachverfahren erstellt wurde und im empfangenden DMS angesehen oder bearbeitet werden soll.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="IDSGO" type="xdomea:stringUUIDType"> + <xs:annotation> + <xs:documentation>Die ID des Schriftgutobjekts im DMS, das angesehen oder bearbeitet werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Versionsnummer" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Die Versionsnummer kann nur für Dokumente angegeben werden - für Akte und Vorgang ist dies nicht möglich.</implementationHint> + </xs:appinfo> + <xs:documentation>Die Versionsnummer des Dokuments.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Client" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Neben der Benennung des Clients z.B. über eine IP-Adresse können auch Daten zur Identifizierung von Terminalserversitzungen angegeben werden.</implementationHint> + </xs:appinfo> + <xs:documentation>Der Client, auf dem das Schriftgutobjekt zu öffnen ist.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="SchriftgutobjektZumDruckenType"> + <xs:annotation> + <xs:appinfo> + <title>SchriftgutobjektZumDrucken</title> + </xs:appinfo> + <xs:documentation>SchriftgutobjektZumDrucken enthält Informationen zu einem Schriftgutobjekt, das in einem Fachverfahren erstellt wurde und gedruckt werden soll. Wird die Nachricht im Stapelbetrieb übergeben, so erfolgt hier zusätzlich die Übergabe der Nummer im Stapel zu jedem angegebenen Schriftgutobjekt.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="NummerImStapel" minOccurs="0" type="xs:unsignedInt"> + <xs:annotation> + <xs:documentation>Die Nummer des übergebenen Elements im Stapel. Anhand dieser Nummer können im Rückmeldestapel die Rückmeldungen den einzelnen Elementen im Stapel zugeordnet werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="IDSGO" type="xdomea:stringUUIDType"> + <xs:annotation> + <xs:documentation>Die ID des Schriftgutobjekts im DMS, das gedruckt werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Drucker" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Name des Druckers. Wird kein Druckername angegeben, so wird der Druck auf dem Standarddrucker des Clients ausgegeben.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="MetadatenDrucken" type="xs:boolean"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Für die Umsetzung in den Systemen wird empfohlen, sofern kein anderer Wert hinterlegt wurde, als Standardwert den Wert 0 für "keine Metadaten drucken" anzugeben.</implementationHint> + </xs:appinfo> + <xs:documentation>MetadatenDrucken legt fest, ob zu einem Schriftgutobjekt auch die Metadaten ausgedruckt werden sollen. Soll auch ein Druck der Metadaten zu Schriftgutobjekten stattfinden, so ist der Wert 1 anzugeben. Soll kein Druck der Metadaten zu Schriftgutobjekten stattfinden, so ist der Wert 0 anzugeben.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="PrimaerdokumentDrucken" type="xs:boolean"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Für die Umsetzung in den Systemen wird empfohlen, sofern kein anderer Wert hinterlegt wurde, als Standardwert den Wert 0 für "kein Primärdokument drucken" anzugeben.</implementationHint> + </xs:appinfo> + <xs:documentation>PrimaerdokumentDrucken legt fest, ob die Primärdokumente zu dem Schriftgutobjekt gedruckt werden. Sollen die Primärdokumente zu dem Schriftgutobjekt gedruckt werden, so ist der Wert 1 anzugeben. Soll kein Druck der Primärdokumente zum Schriftgutobjekt stattfinden, so ist der Wert 0 anzugeben.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="UnterSGODrucken" type="xs:boolean"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Für die Umsetzung in den Systemen wird empfohlen, sofern kein anderer Wert hinterlegt wurde, als Standardwert den Wert 0 für "kein untergeordnetes Schriftgutobjekt drucken" anzugeben.</implementationHint> + </xs:appinfo> + <xs:documentation>UnterSGODrucken legt fest, ob sich innerhalb des übergegebenen Schriftgutobjekts befindliche Schriftgutobjekte gedruckt werden sollen, z.B. eine Akte mit ihren Vorgängen und Dokumenten. Sollen die untergeordneten Schriftgutobjekte gedruckt werden, so ist der Wert 1 anzugeben. Soll kein Druck der untergeordneten Schriftgutobjekte erfolgen, so ist der Wert 0 anzugeben.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="UnterSGOTyp" + minOccurs="0" + maxOccurs="unbounded" + type="xs:string"> + <xs:annotation> + <xs:documentation>UnterSGOTyp legt fest, dass nur die Schriftgutobjekte eines angegebenen Typs gedruckt werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Versionsnummer" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Die Versionsnummer kann nur für Dokumente angegeben werden - für Akte und Vorgang ist dies nicht möglich.</implementationHint> + </xs:appinfo> + <xs:documentation>Die Versionsnummer des Dokuments.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Client" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Neben der Benennung des Clients z.B. über eine IP-Adresse können auch Daten zur Identifizierung von Terminalserversitzungen angegeben werden.</implementationHint> + </xs:appinfo> + <xs:documentation>Der Client, von dem aus das Schriftgutobjekt gedruckt wird.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="SchriftgutobjektZumErstellenType"> + <xs:annotation> + <xs:appinfo> + <title>SchriftgutobjektZumErstellen</title> + </xs:appinfo> + <xs:documentation>SchriftgutobjektZumErstellen enthält Informationen zu einem Schriftgutobjekt, das in einem Fachverfahren erzeugt wurde und im empfangenden DMS erstellt werden soll.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:extension base="xdomea:SchriftgutobjektZumAblegenOderErstellenType"> + <xs:sequence> + <xs:element name="SGOOeffnen" minOccurs="0" type="xs:boolean"> + <xs:annotation> + <xs:documentation>SGOOeffnen legt fest, ob das Schriftgutobjekt nach der Erstellung in dem DMS mit einer externen Applikation oder mit dem DMS z.B. zur weiteren Bearbeitung geöffnet werden soll. Soll das Schriftgutobjekt geöffnet werden, so ist der Wert 1 anzugeben. Soll das Schriftgutobjekt nicht geöffnet werden, so ist der Wert 0 anzugeben.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Client" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Das Schriftgutobjekt wird auf dem spezifizierten Client geöffnet, wenn der Client angegeben ist und der Parameter "SGOOeffnen" positiv belegt ist. Neben der Benennung des Clients z.B. über eine IP-Adresse können auch Daten zur Identifizierung von Terminalserversitzungen angegeben werden.</implementationHint> + </xs:appinfo> + <xs:documentation>Der Client, auf dem das Schriftgutobjekt zu öffnen ist.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SchriftgutobjektZumLoeschenType"> + <xs:annotation> + <xs:appinfo> + <title>SchriftgutobjektZumLoeschen</title> + </xs:appinfo> + <xs:documentation>SchriftgutobjektZumLoeschen enthält Informationen zu einem Schriftgutobjekt, das im DMS gelöscht bzw. dessen Löschmarkierung aufgehoben werden soll. Wird die Nachricht im Stapelbetrieb übergeben, so erfolgt hier zusätzlich die Übergabe der Nummer im Stapel zu jedem angegebenen Schriftgutobjekt.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="NummerImStapel" minOccurs="0" type="xs:unsignedInt"> + <xs:annotation> + <xs:documentation>Die Nummer des übergebenen Elements im Stapel. Anhand dieser Nummer können im Rückmeldestapel die Rückmeldungen den einzelnen Elementen im Stapel zugeordnet werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="IDSGO" type="xdomea:stringUUIDType"> + <xs:annotation> + <xs:documentation>Die ID des Schriftgutobjekts im DMS.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="SchriftgutobjektZumLoeschstatusAbfragenType"> + <xs:annotation> + <xs:appinfo> + <title>SchriftgutobjektZumLoeschstatusAbfragen</title> + </xs:appinfo> + <xs:documentation>SchriftgutobjektZumLoeschStatusAbfragen enthält Informationen zu einem Schriftgutobjekt, dessen Löschstatus im DMS abgefragt werden soll.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="NummerImStapel" minOccurs="0" type="xs:unsignedInt"> + <xs:annotation> + <xs:documentation>Die Nummer des übergebenen Elements im Stapel. Anhand dieser Nummer können im Rückmeldestapel die Rückmeldungen den einzelnen Elementen im Stapel zugeordnet werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="IDSGO" type="xdomea:stringUUIDType"> + <xs:annotation> + <xs:documentation>Die ID des Schriftgutobjekts im DMS, dessen Löschtstatus abgefragt werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="SchriftgutobjektZumSuchenType"> + <xs:annotation> + <xs:appinfo> + <title>SchriftgutobjektZumSuchen</title> + </xs:appinfo> + <xs:documentation>SchriftgutobjektZumSuchen enthält Informationen zur Suche nach Schriftgutobjekten im DMS.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Suchbegriffe" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Suchbegriffe sind Kriterien, mit deren Hilfe im DMS nach Schriftgutobjekten gesucht wird. Sie werden über eine UND-Verknüpfung ausgewertet.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Volltext" type="xs:boolean"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Für die Umsetzung in den Systemen wird empfohlen, sofern kein anderer Wert hinterlegt wurde, als Standardwert den Wert 1 für "Volltextsuche durchführen" anzugeben.</implementationHint> + </xs:appinfo> + <xs:documentation>Volltext legt fest, ob die Suche auch in den Primärdokumenten der Schriftgutobjekte durchgeführt werden soll. Soll die Suche auch in den Primärdokumenten durchgeführt werden, so ist der Wert 1 anzugeben. Soll eine solche Suche in den Primärdokumenten nicht erfolgen, so ist der Wert 0 anzugeben.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Metadaten" type="xs:boolean"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Für die Umsetzung in den Systemen wird empfohlen, sofern kein anderer Wert hinterlegt wurde, als Standardwert den Wert 1 für "Metadaten durchsuchen" anzugeben.</implementationHint> + </xs:appinfo> + <xs:documentation>Metadaten legt fest, ob die Suche auch in den Metadaten der Schriftgutobjekte durchgeführt werden soll. Soll eine Suche auch in den Metadaten der Schriftgutobjekte stattfinden, so ist der Wert 1 anzugeben. Soll keine Suche in den Metadaten der Schriftgutobjekte stattfinden, so ist der Wert 0 anzugeben.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="SchriftgutobjektZumZDAAufhebenType"> + <xs:annotation> + <xs:appinfo> + <title>SchriftgutobjektZumZDAAufheben</title> + </xs:appinfo> + <xs:documentation>SGOZumZDAAufheben enthält Informationen zu einem Schriftgutobjekt, dessen Daten im empfangenden System wiederaufleben sollen. Wird die Nachricht im Stapelbetrieb übergeben, so erfolgt hier zusätzlich die Übergabe der Nummer im Stapel zu jedem angegebenen Schriftgutobjekt.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="NummerImStapel" minOccurs="0" type="xs:unsignedInt"> + <xs:annotation> + <xs:documentation>Die Nummer des übergebenen Elements im Stapel. Anhand dieser Nummer können im Rückmeldestapel die Rückmeldungen den einzelnen Elementen im Stapel zugeordnet werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="IDSGO" type="xdomea:stringUUIDType"> + <xs:annotation> + <xs:documentation>Die ID des Schriftgutobjektes, dessen zdA-Verfügung aufgehoben werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="SchriftgutobjektZumZDAVerfuegenType"> + <xs:annotation> + <xs:appinfo> + <title>SchriftgutobjektZumZDAVerfuegen</title> + </xs:appinfo> + <xs:documentation>SchriftgutobjektZumZDAVerfuegen enthält Informationen zu einem Schriftgutobjekt, das im DMS zdA-verfügt werden soll. Wird die Nachricht im Stapelbetrieb übergeben, so erfolgt hier zusätzlich die Übergabe der Nummer im Stapel zu jedem angegebenen Schriftgutobjekt.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="NummerImStapel" minOccurs="0" type="xs:unsignedInt"> + <xs:annotation> + <xs:documentation>Die Nummer des übergebenen Elements im Stapel. Anhand dieser Nummer können im Rückmeldestapel die Rückmeldungen den einzelnen Elementen im Stapel zugeordnet werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="IDSGO" type="xdomea:stringUUIDType"> + <xs:annotation> + <xs:documentation>Die ID des Schriftgutobjekts im DMS, das zdA-verfügt werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="StandardablageType"> + <xs:annotation> + <xs:appinfo> + <title>Standardablage</title> + </xs:appinfo> + <xs:documentation>Standardablage beschreibt Informationen, an denen routinemäßig für einen bestimmten Benutzer oder eine bestimmte Rolle Daten abgelegt werden.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Ablageort" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Standard-Ablageort. In Abhängigkeit des Konfigurationsparameters Datenaustauschart kann dieser Parameter unterschiedliche Werte annehmen: Übergabe über ein freigegebenes Verzeichnis: Name des Verzeichnisses. Übergabe per WebDAV und http(s): URL. Übergabe über eine Datenbank: der Parameter bleibt leer (bzw. wird ignoriert).</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="BenutzerOderRolle" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Benutzer oder die Rolle, dem/der der Ablageort zugewiesen wird.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="SystemstatusZumAbfragenType"> + <xs:annotation> + <xs:appinfo> + <title>SystemstatusZumAbfragen</title> + </xs:appinfo> + <xs:documentation>SystemstatusZumAbfragen enthält Informationen zu einer Statusabfrage des empfangenden Systems.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="SystemstatusID" type="xs:integer"> + <xs:annotation> + <xs:documentation>Die ID der Systemstatus-Information, die abgefragt werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="VertretungZumAktivierenOderDeaktivierenType"> + <xs:annotation> + <xs:appinfo> + <title>VertretungZumAktivierenOderDeaktivieren</title> + </xs:appinfo> + <xs:documentation>VertretungZumAktivierenOderDeaktivieren enthält Informationen zu einer Vertretung, die aktiviert oder deaktiviert werden soll.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="ZuVertretender" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Benutzer oder die Rolle, für den/die die Vertretung aktiviert bzw. deaktiviert werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Vertreter" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Benutzer oder die Rolle, der/die die Vertretung übernehmen bzw. wieder abgeben soll.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Aktivieren" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Aktivieren bestimmt, ob eine Vertretung aktiviert oder deaktiviert werden soll. Hat Aktivieren den Wert 1, so wird die Vertretung aktiviert. Hat Aktivieren den Wert 0, so wird die Vertretung deaktiviert.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="VertretungsstatusZumAbfragenType"> + <xs:annotation> + <xs:appinfo> + <title>VertretungsstatusZumAbfragen</title> + </xs:appinfo> + <xs:documentation>VertretungsstatusZumAbfragen enthält Informationen zur Abfrage des Vertretungsstatus eines Benutzers oder einer Rolle.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="BenutzerOderRolle" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Benutzer oder die Rolle, für den/die der Vertretungsstatus abgefragt wird.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="ZustaendigkeitZumAendernType"> + <xs:annotation> + <xs:appinfo> + <title>ZustaendigkeitZumAendern</title> + </xs:appinfo> + <xs:documentation>ZustaendigkeitZumAendern enthält Informationen zur Zuständigkeitsänderung eines Schriftgutobjekts. Wird die Nachricht im Stapelbetrieb übergeben, so erfolgt hier zusätzlich die Übergabe der Nummer im Stapel zu jedem angegebenen Schriftgutobjekt.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="NummerImStapel" minOccurs="0" type="xs:unsignedInt"> + <xs:annotation> + <xs:documentation>Die Nummer des übergebenen Elements im Stapel. Anhand dieser Nummer können im Rückmeldestapel die Rückmeldungen den einzelnen Elementen im Stapel zugeordnet werden.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="IDSGO" type="xdomea:stringUUIDType"> + <xs:annotation> + <xs:documentation>Die ID des Schriftgutobjekts im DMS, für das die Zuständigkeit angepasst werden soll.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="JetztZustaendig" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Benutzer oder die Rolle, welcher/welche nach der Zuständigkeitsänderung für das Schriftgutobjekt zuständig ist.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="BisherZustaendig" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Der Benutzer oder die Rolle, welcher/welche bisher für das Schriftgutobjekt zuständig war.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="AufnehmendAktenplaneinheitKennzeichen" + minOccurs="0" + type="xs:string"> + <xs:annotation> + <xs:documentation>Das Kennzeichen des übergeordneten Schriftgutobjekts, zu dem das von der Zuständigkeitsänderung betroffene Schriftgutobjekt nach der Änderung gehört.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="AufnehmendID" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die ID des übergeordneten Schriftgutobjekts, zu dem das Schriftgutobjekt nach der Zuständigkeitsänderung gehört.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="AbgebendAktenplaneinheitKennzeichen" + minOccurs="0" + type="xs:string"> + <xs:annotation> + <xs:documentation>Das Kennzeichen des übergeordneten Schriftgutobjekts, zu dem das von der Zuständigkeitsänderung betroffene Schriftgutobjekt vor der Änderung gehörte.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="AbgebendID" minOccurs="0" type="xs:string"> + <xs:annotation> + <xs:documentation>Die ID des übergeordneten Schriftgutobjekts, zu dem das Schriftgutobjekt vor der Zuständigkeitsänderung gehörte.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Metadatum" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:FeldType"> + <xs:annotation> + <xs:documentation>Ein im Rahmen der Zuständigkeitsänderung angepasstes Metadatum zu dem Schriftgutobjekt.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> +</xs:schema> diff --git a/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Typen-GeschaeftsgangDurchfuehren.xsd b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Typen-GeschaeftsgangDurchfuehren.xsd new file mode 100644 index 0000000000000000000000000000000000000000..fd1061cd1022fdfd11e1006b365c6f9ce0b90657 --- /dev/null +++ b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Typen-GeschaeftsgangDurchfuehren.xsd @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xdomea="urn:xoev-de:xdomea:schema:3.0.0" + targetNamespace="urn:xoev-de:xdomea:schema:3.0.0" + version="3.0.0" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> + <xs:annotation> + <xs:appinfo> + <standard> + <nameLang>xdomea - XÖV-Standard für den IT-gestützten Austausch und die IT-gestützte Aussonderung behördlichen Schriftgutes</nameLang> + <nameKurz>xdomea</nameKurz> + <nameTechnisch>xdomea</nameTechnisch> + <kennung>urn:xoev-de:xdomea:kosit:standard:xdomea</kennung> + <beschreibung>xdomea ist der vom IT-Planungsrat verabschiedete verbindliche Standard für den Austausch von Akten, Vorgängen und Dokumenten im Kontext der Übermittlung, der Abgabe sowie der Aussonderung von Schriftgutobjekten (www.it-planungsrat.de, Beschluss 2017/39). Weiterhin kann xdomea für den Austausch zwischen Fachverfahren und DMS/VBS sowie für die Zwischenarchivierung genutzt werden. + +Um diese Anwendungsszenarien bestmöglich zu unterstützen, ist xdomea gemäß des XÖV-Rahmenwerkes nach dem Baukastenprinzip aufgebaut und bietet einzelne Nachrichten(gruppen) für die jeweiligen Prozesse an. + +Der Standard xdomea wird von der gleichnamigen Arbeitsgruppe des IT-Planungsrates weiterentwickelt und gepflegt. Der Betrieb des Standards erfolgt durch die Koordinierungsstelle für IT-Standards (KoSIT). +</beschreibung> + </standard> + <versionStandard> + <version>3.0.0</version> + <beschreibung>Die Version 3.0.0 ist durch den IT-Planungsrat beschlossen. Details zum Beschluss sowie zu den Fristen der Umsetzung sind der Veröffentlichung im Bundesanzeiger unter www.bundesanzeiger.de zu entnehmen.</beschreibung> + <versionXOEVProfil>1.7.2</versionXOEVProfil> + <versionXOEVHandbuch>2.3.1</versionXOEVHandbuch> + <versionXGenerator>3.0.1</versionXGenerator> + <versionModellierungswerkzeug>19.0</versionModellierungswerkzeug> + <nameModellierungswerkzeug>MagicDraw</nameModellierungswerkzeug> + </versionStandard> + </xs:appinfo> + </xs:annotation> + <xs:include schemaLocation="xdomea-Baukasten.xsd"/> + <xs:complexType name="GeaenderterBeteiligungsschrittType"> + <xs:annotation> + <xs:appinfo> + <title>GeaenderterBeteiligungsschritt</title> + </xs:appinfo> + <xs:documentation>Informationen zu einem geänderten Beteiligungsschritt eines Geschäftsgangs. Geändert kann in diesem Zusammenhang neu erstellt bzw. übersprungen heißen.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Nummer" type="xs:string"> + <xs:annotation> + <xs:documentation>Die Nummer des Beteiligungsschrittes innerhalb der fortlaufenden Nummerierung im Geschäftsgang. Die Nummerierung ist innerhalb eines xdomea-Geschäftsgangsobjekts eindeutig. Werden in den xdomea-Geschäftsgang neue Bearbeitungsschritte eingefügt, werden dementsprechend die Nummern der nachfolgenden Beteiligungsschritte verändert. Beteiligungsschritte, die abgeschlossen sind, sind unveränderlich.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Aenderungsart"> + <xs:annotation> + <xs:documentation>Die Änderungsart eines Beteiligungsschrittes.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:choice> + <xs:element name="Neu" fixed="1" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Der Beteiligungsschritt wurde dem Laufweg eines Geschäftsgangs neu hinzugefügt.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Uebersprungen" fixed="1" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Der Beteiligungsschritt wird in dem Laufweg als übersprungen markiert, d.h. der Schritt bleibt im Geschäftsgang erhalten, wird jedoch nicht mehr aktiv beteiligt.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:choice> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="HauptobjektType"> + <xs:annotation> + <xs:appinfo> + <title>Hauptobjekt</title> + <implementationHint>Akten oder Vorgänge sind als Element im Hauptobjekt nicht erlaubt.</implementationHint> + </xs:appinfo> + <xs:documentation>Ein Container für die Dokumente, auf die sich die Beteiligungsschritte im externen Geschäftsgang beziehen.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Dokument" maxOccurs="unbounded" type="xdomea:DokumentType"> + <xs:annotation> + <xs:documentation>Ein in der Geschäftsgangs-Nachricht enthaltenes Dokument, auf das sich die Verfügungen im externen Geschäftsgang beziehen.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="NkGeschaeftsgangType"> + <xs:annotation> + <xs:appinfo> + <title>NkGeschaeftsgang</title> + </xs:appinfo> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger einer Nachricht, bei der es sich um einen Geschäftsgang handelt.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:extension base="xdomea:NkBasisType"> + <xs:sequence> + <xs:element name="EmpfangsbestaetigungAnInitiator" type="xs:boolean"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Für die Umsetzung in den Systemen wird empfohlen, sofern kein anderer Wert hinterlegt wurde, als Standardwert den Wert 0 für "keine Empfangsbestätigung senden" anzugeben.</implementationHint> + </xs:appinfo> + <xs:documentation>Die Angabe, ob vom Empfänger der Nachricht eine Empfangsbestätigung für den Initiator des Geschäftsgangs erwünscht wird. Eine erwünschte Empfangsbestätigung wird mit 1 gekennzeichnet. Wird keine Empfangsbestätigung gewünscht, so wird dies mit 0 gekennzeichnet.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="EmpfangsbestaetigungAnVorgaenger" type="xs:boolean"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Für die Umsetzung in den Systemen wird empfohlen, sofern kein anderer Wert hinterlegt wurde, als Standardwert den Wert 0 für "keine Empfangsbestätigung senden" anzugeben.</implementationHint> + </xs:appinfo> + <xs:documentation>Die Angabe, ob vom Empfänger der Nachricht eine Empfangsbestätigung für den Absender der Nachricht erwünscht wird. Eine erwünschte Empfangsbestätigung wird mit 1 gekennzeichnet. Wird keine Empfangsbestätigung gewünscht, so wird dies mit 0 gekennzeichnet.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="NkRueckmeldungGeschaeftsgangType"> + <xs:annotation> + <xs:appinfo> + <title>NkRueckmeldungGeschaeftsgang</title> + </xs:appinfo> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger der Empfangs-/Importnachricht zu einer in Beziehung stehenden Nachricht, die durch den Empfänger versendet wurde und sich auf einen Geschäftsgang bezieht.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:extension base="xdomea:NkBasisType"> + <xs:sequence> + <xs:element name="WeitererEmpfaenger" minOccurs="0" type="xdomea:KontaktType"> + <xs:annotation> + <xs:documentation>Der weitere Empfänger der Nachricht.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> +</xs:schema> diff --git a/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Typen-ZwischenarchivierungDurchfuehren.xsd b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Typen-ZwischenarchivierungDurchfuehren.xsd new file mode 100644 index 0000000000000000000000000000000000000000..6795daa0473e4f35f553446de65fd93d452a31ab --- /dev/null +++ b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea-Typen-ZwischenarchivierungDurchfuehren.xsd @@ -0,0 +1,97 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xdomea="urn:xoev-de:xdomea:schema:3.0.0" + targetNamespace="urn:xoev-de:xdomea:schema:3.0.0" + version="3.0.0" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> + <xs:annotation> + <xs:appinfo> + <standard> + <nameLang>xdomea - XÖV-Standard für den IT-gestützten Austausch und die IT-gestützte Aussonderung behördlichen Schriftgutes</nameLang> + <nameKurz>xdomea</nameKurz> + <nameTechnisch>xdomea</nameTechnisch> + <kennung>urn:xoev-de:xdomea:kosit:standard:xdomea</kennung> + <beschreibung>xdomea ist der vom IT-Planungsrat verabschiedete verbindliche Standard für den Austausch von Akten, Vorgängen und Dokumenten im Kontext der Übermittlung, der Abgabe sowie der Aussonderung von Schriftgutobjekten (www.it-planungsrat.de, Beschluss 2017/39). Weiterhin kann xdomea für den Austausch zwischen Fachverfahren und DMS/VBS sowie für die Zwischenarchivierung genutzt werden. + +Um diese Anwendungsszenarien bestmöglich zu unterstützen, ist xdomea gemäß des XÖV-Rahmenwerkes nach dem Baukastenprinzip aufgebaut und bietet einzelne Nachrichten(gruppen) für die jeweiligen Prozesse an. + +Der Standard xdomea wird von der gleichnamigen Arbeitsgruppe des IT-Planungsrates weiterentwickelt und gepflegt. Der Betrieb des Standards erfolgt durch die Koordinierungsstelle für IT-Standards (KoSIT). +</beschreibung> + </standard> + <versionStandard> + <version>3.0.0</version> + <beschreibung>Die Version 3.0.0 ist durch den IT-Planungsrat beschlossen. Details zum Beschluss sowie zu den Fristen der Umsetzung sind der Veröffentlichung im Bundesanzeiger unter www.bundesanzeiger.de zu entnehmen.</beschreibung> + <versionXOEVProfil>1.7.2</versionXOEVProfil> + <versionXOEVHandbuch>2.3.1</versionXOEVHandbuch> + <versionXGenerator>3.0.1</versionXGenerator> + <versionModellierungswerkzeug>19.0</versionModellierungswerkzeug> + <nameModellierungswerkzeug>MagicDraw</nameModellierungswerkzeug> + </versionStandard> + </xs:appinfo> + </xs:annotation> + <xs:include schemaLocation="xdomea-Baukasten.xsd"/> + <xs:complexType name="ErfolgOderMisserfolgZwischenarchivierungType"> + <xs:annotation> + <xs:appinfo> + <title>ErfolgOderMisserfolgZwischenarchivierung</title> + </xs:appinfo> + <xs:documentation>Die Information zum erfolgreichen oder nicht erfolgreichen Import eines auszulagernden Schriftgutobjektes.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="IDSGO" type="xdomea:stringUUIDType"> + <xs:annotation> + <xs:documentation>Die ID des Schriftgutobjekts, das ausgelagert werden sollte.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Erfolgreich" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Die Kennzeichnung des erfolgreichen oder nicht erfolgreichen Imports zu einem auszulagernden Schriftgutobjekt. Der erfolgreiche Import wird mit 1 und der nicht erfolgreiche Import mit 0 gekennzeichnet.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Fehlermeldung" + minOccurs="0" + maxOccurs="unbounded" + type="xs:string"> + <xs:annotation> + <xs:documentation>Die Information in Form eines Freitextes, aus welchem Grund der Import zum auszulagernden Schriftgutobjekt nicht erfolgreich war.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="FehlermeldungCode" + minOccurs="0" + maxOccurs="unbounded" + type="xdomea:SonstigeFehlermeldungCodeType"> + <xs:annotation> + <xs:documentation>Die Information in Form eines Codes, aus welchem Grund der Import zum auszulagernden Schriftgutobjekt nicht erfolgreich war.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="NkZwischenarchivierungType"> + <xs:annotation> + <xs:appinfo> + <title>NkAuslagerung</title> + </xs:appinfo> + <xs:documentation>Der Kopf der Nachricht enthält allgemeine Informationen für den Empfänger einer Nachricht, bei der es sich um eine Auslagerung handelt.</xs:documentation> + </xs:annotation> + <xs:complexContent> + <xs:extension base="xdomea:NkNichtFVDatenWeitereEmpfaengerType"> + <xs:sequence> + <xs:element name="Importbestaetigung" fixed="1" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Die Angabe, dass eine Importbestätigung vom Empfänger der Nachricht erwünscht wird.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Empfangsbestaetigung" type="xs:boolean"> + <xs:annotation> + <xs:appinfo> + <implementationHint>Für die Umsetzung in den Systemen wird empfohlen, sofern kein anderer Wert hinterlegt wurde, als Standardwert den Wert 0 für "keine Empfangsbestätigung senden" anzugeben.</implementationHint> + </xs:appinfo> + <xs:documentation>Die Angabe, ob vom Empfänger der Nachricht eine Empfangsbestätigung erwünscht wird. Eine erwünschte Empfangsbestätigung wird mit 1 gekennzeichnet. Wird keine Empfangsbestätigung gewünscht, so wird dies mit 0 gekennzeichnet.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> +</xs:schema> diff --git a/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea.xsd b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea.xsd new file mode 100644 index 0000000000000000000000000000000000000000..79642b4d3e9408ec090a03553c981549909010fc --- /dev/null +++ b/alfa-xdomea/src/main/resources/xdomea_3-0-0_XML-Schemata/xdomea.xsd @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + targetNamespace="urn:xoev-de:xdomea:schema:3.0.0" + version="3.0.0" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> + <xs:include schemaLocation="xdomea-Baukasten.xsd"/> + <xs:include schemaLocation="xdomea-Datentypen.xsd"/> + <xs:include schemaLocation="xdomea-Nachrichten-AbgabeDurchfuehren.xsd"/> + <xs:include schemaLocation="xdomea-Nachrichten-AktenplanAustauschen.xsd"/> + <xs:include schemaLocation="xdomea-Nachrichten-Archivsystem.xsd"/> + <xs:include schemaLocation="xdomea-Nachrichten-AussonderungDurchfuehren.xsd"/> + <xs:include schemaLocation="xdomea-Nachrichten-DMS.xsd"/> + <xs:include schemaLocation="xdomea-Nachrichten-Fachverfahren.xsd"/> + <xs:include schemaLocation="xdomea-Nachrichten-FachverfahrensdatenAustauschen.xsd"/> + <xs:include schemaLocation="xdomea-Nachrichten-GeschaeftsgangDurchfuehren.xsd"/> + <xs:include schemaLocation="xdomea-Nachrichten-InformationAustauschen.xsd"/> + <xs:include schemaLocation="xdomea-Nachrichten-VBS.xsd"/> + <xs:include schemaLocation="xdomea-Nachrichten-ZwischenarchivierungDurchfuehren.xsd"/> + <xs:include schemaLocation="xdomea-Nachrichten-Zwischenarchivsystem.xsd"/> + <xs:include schemaLocation="xdomea-Typen-AbgabeDurchfuehren.xsd"/> + <xs:include schemaLocation="xdomea-Typen-AussonderungDurchfuehren.xsd"/> + <xs:include schemaLocation="xdomea-Typen-FachverfahrensdatenAustauschen.xsd"/> + <xs:include schemaLocation="xdomea-Typen-GeschaeftsgangDurchfuehren.xsd"/> + <xs:include schemaLocation="xdomea-Typen-ZwischenarchivierungDurchfuehren.xsd"/> +</xs:schema> diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/bescheid/BescheidExportDataTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/bescheid/BescheidExportDataTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..e731e4838f28f5056d77210640b33845c7f4ef1b --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/bescheid/BescheidExportDataTestFactory.java @@ -0,0 +1,24 @@ +package de.ozgcloud.alfa.bescheid; + +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.file.OzgFileTestFactory; +import de.ozgcloud.alfa.export.DokumentTypeTestFactory; +import de.xoev.xdomea.DokumentType; + +public class BescheidExportDataTestFactory { + + public static final DokumentType DOKUMENT_TYPE = DokumentTypeTestFactory.create(); + public static final OzgFile ATTACHMENT = OzgFileTestFactory.createWithUniqueId(); + public static final OzgFile DOCUMENT = OzgFileTestFactory.createWithUniqueId(); + + public static BescheidExportData create() { + return createBuilder().build(); + } + + public static BescheidExportData.BescheidExportDataBuilder createBuilder() { + return BescheidExportData.builder() + .dokumentType(DOKUMENT_TYPE) + .file(DOCUMENT) + .file(ATTACHMENT); + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/bescheid/BescheidExportInputTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/bescheid/BescheidExportInputTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..fbee5d69b45774fcfac881ab2f4550284704c447 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/bescheid/BescheidExportInputTestFactory.java @@ -0,0 +1,26 @@ +package de.ozgcloud.alfa.bescheid; + +import java.util.List; + +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.file.OzgFileTestFactory; +import de.ozgcloud.alfa.vorgang.ZustaendigeStelleTestFactory; + +public class BescheidExportInputTestFactory { + + public final static Bescheid BESCHEID = BescheidTestFactory.create(); + public final static String ORGANISATIONSEINHEITEN_ID = ZustaendigeStelleTestFactory.ORGANISATIONSEINHEITEN_ID; + public final static List<OzgFile> FILES = List.of(OzgFileTestFactory.createWithUniqueId()); + + public static BescheidExportInput create() { + return createBuilder().build(); + } + + public static BescheidExportInput.BescheidExportInputBuilder createBuilder() { + return BescheidExportInput.builder() + .bescheid(BESCHEID) + .organisationseinheitenId(ORGANISATIONSEINHEITEN_ID) + .files(FILES); + } + +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/bescheid/DokumentTypeBuilderTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/bescheid/DokumentTypeBuilderTest.java new file mode 100644 index 0000000000000000000000000000000000000000..55e271e0050a302b0890245d0ca1bdc9f5adaa93 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/bescheid/DokumentTypeBuilderTest.java @@ -0,0 +1,293 @@ +package de.ozgcloud.alfa.bescheid; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.List; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Spy; + +import com.thedeanda.lorem.LoremIpsum; + +import de.ozgcloud.alfa.common.AnlageDokumentTypeBuilder; +import de.ozgcloud.alfa.common.AnlageDokumentTypeTestFactory; +import de.ozgcloud.alfa.common.DateConverter; +import de.ozgcloud.alfa.common.HistorienProtokollInformationTypeTestFactory; +import de.ozgcloud.alfa.common.IdentifikationObjektTypeBuilder; +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.file.OzgFileTestFactory; +import de.ozgcloud.alfa.common.user.UserProfileTestFactory; +import de.ozgcloud.alfa.export.AllgemeineMetadatenTypeTestFactory; +import de.ozgcloud.alfa.export.IdentifikationObjektTypeTestFactory; +import de.ozgcloud.alfa.vorgang.ZustaendigeStelleTestFactory; +import de.xoev.xdomea.AllgemeineMetadatenType; +import de.xoev.xdomea.AnlageDokumentType; +import de.xoev.xdomea.HistorienProtokollInformationType; +import de.xoev.xdomea.IdentifikationObjektType; + +class DokumentTypeBuilderTest { + private final String fullName = UserProfileTestFactory.FULLNAME; + private final Bescheid bescheid = BescheidTestFactory.create(); + private final OzgFile document = OzgFileTestFactory.createWithUniqueId(); + + @Spy + private final DokumentTypeBuilder builder = DokumentTypeBuilder.builder() + .withBescheid(bescheid) + .withOrganisationseinheitenId(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEITEN_ID) + .withFullName(fullName) + .withFiles(List.of(document)); + + @Nested + class TestBuild { + private static final String TYP = "Bescheid"; + + private MockedStatic<IdentifikationObjektTypeBuilder> identifikationObjektTypeBuilderMockedStatic; + @Mock + private IdentifikationObjektTypeBuilder identifikationObjektTypeBuilder; + private final IdentifikationObjektType identifikationObjektType = IdentifikationObjektTypeTestFactory.create(); + + private final HistorienProtokollInformationType historienProtokollInformation = HistorienProtokollInformationTypeTestFactory.create(); + private final AllgemeineMetadatenType metadatenType = AllgemeineMetadatenTypeTestFactory.create(); + private final AnlageDokumentType anlageDokumentDocument = AnlageDokumentTypeTestFactory.create(); + + @BeforeEach + void setUp() { + identifikationObjektTypeBuilderMockedStatic = mockStatic(IdentifikationObjektTypeBuilder.class); + identifikationObjektTypeBuilderMockedStatic.when(IdentifikationObjektTypeBuilder::builder).thenReturn(identifikationObjektTypeBuilder); + when(identifikationObjektTypeBuilder.withObjectID(BescheidTestFactory.ID)).thenReturn(identifikationObjektTypeBuilder); + when(identifikationObjektTypeBuilder.build()).thenReturn(identifikationObjektType); + doReturn(anlageDokumentDocument).when(builder).createAnlage(document); + } + + @AfterEach + void tearDown() { + identifikationObjektTypeBuilderMockedStatic.close(); + } + + @Test + void shouldSetObjectId() { + builder.build(); + + verify(identifikationObjektTypeBuilder).withObjectID(bescheid.getId()); + } + + @Test + void shouldBuildIdentifikationObjectType() { + builder.build(); + + verify(identifikationObjektTypeBuilder).build(); + } + + @Test + void shouldHaveIdentifikation() { + var dokument = builder.build(); + + assertThat(dokument.getIdentifikation()).isEqualTo(identifikationObjektType); + } + + @Test + void shouldHaveTyp() { + var dokument = builder.build(); + + assertThat(dokument.getTyp()).isEqualTo(TYP); + } + + @Test + void shouldHaveBezugWithBetreff() { + var subject = LoremIpsum.getInstance().getWords(5); + builder.withBescheid(BescheidTestFactory.createBuilder().nachrichtSubject(subject).build()); + + var dokument = builder.build(); + + assertThat(dokument.getBezug()).isEqualTo(subject); + } + + @Test + void shouldHaveEmptyBezug() { + builder.withBescheid(BescheidTestFactory.createBuilder().nachrichtSubject(null).build()); + + var dokument = builder.build(); + + assertThat(dokument.getBezug()).isEmpty(); + } + + @Test + void shouldHaveMetadaten() { + doReturn(metadatenType).when(builder).createAllgemeineMetadaten(); + + var dokument = builder.build(); + + assertThat(dokument.getAllgemeineMetadaten()).isEqualTo(metadatenType); + } + + @Test + void shouldHaveHistorienProtokollInformation() { + doReturn(historienProtokollInformation).when(builder).createHistorienProtokollInformation(); + + var dokument = builder.build(); + + assertThat(dokument.getHistorienProtokollInformation()).containsExactly(historienProtokollInformation); + } + + @Nested + class TestWithoutAnlage { + @Test + void shouldHaveNoAnlage() { + var dokument = builder.build(); + + assertThat(dokument.getAnlage()).containsExactly(anlageDokumentDocument); + } + + } + + @Nested + class TestWithOneAnlage { + private final AnlageDokumentType anlageDokumentAttachment = AnlageDokumentTypeTestFactory.create(); + private final OzgFile attachment = OzgFileTestFactory.createWithUniqueId(); + + @Test + void shouldHaveOneAnlage() { + builder.withFiles(List.of(document, attachment)); + doReturn(anlageDokumentAttachment).when(builder).createAnlage(attachment); + + var dokument = builder.build(); + + assertThat(dokument.getAnlage()).containsExactly(anlageDokumentDocument, anlageDokumentAttachment); + } + } + } + + @Nested + class TestCreateAllgemeineMetadaten { + private final static String GENEHMIGT = "Bescheid wurde genehmigt."; + private final static String ABGELEHNT = "Bescheid wurde abgelehnt."; + + @Test + void shouldHaveBemerkungGenehmigt() { + builder.withBescheid(BescheidTestFactory.createBuilder().bewilligt(true).build()); + + var metadaten = builder.createAllgemeineMetadaten(); + + assertThat(metadaten.getBemerkung()).isEqualTo(GENEHMIGT); + } + + @Test + void shouldHaveBemerkungAbgelehnt() { + builder.withBescheid(BescheidTestFactory.createBuilder().bewilligt(false).build()); + + var metadaten = builder.createAllgemeineMetadaten(); + + assertThat(metadaten.getBemerkung()).isEqualTo(ABGELEHNT); + } + } + + @Nested + class TestCreateHistorienProtokollInformation { + private final static String GESPEICHERT = "Bescheid gespeichert"; + private final static String GESENDET = "Bescheid an Antragsteller gesendet"; + + @Test + void shouldHaveMetadatumName() { + var text = LoremIpsum.getInstance().getHtmlParagraphs(1, 1); + builder.withBescheid(BescheidTestFactory.createBuilder().nachrichtText(text).build()); + + var protokollInfo = builder.createHistorienProtokollInformation(); + + assertThat(protokollInfo.getMetadatumName()).isEqualTo(text); + } + + @Test + void shouldHaveEmptyMetadatumName() { + builder.withBescheid(BescheidTestFactory.createBuilder().nachrichtText(null).build()); + + var protokollInfo = builder.createHistorienProtokollInformation(); + + assertThat(protokollInfo.getMetadatumName()).isEmpty(); + } + + @Test + void shouldHaveAkteur() { + var protokollInfo = builder.createHistorienProtokollInformation(); + + assertThat(protokollInfo.getAkteur()).isEqualTo(fullName + "; " + ZustaendigeStelleTestFactory.ORGANISATIONSEINHEITEN_ID); + } + + @Test + void shouldHaveDatumUhrzeit() { + var protokollInfo = builder.createHistorienProtokollInformation(); + + assertThat(protokollInfo.getDatumUhrzeit()).isEqualTo(DateConverter.toXmlGregorianCalendar(SentInfoTestFactory.SENT_AT)); + } + + @Test + void shouldHaveGespeichertInAktion() { + builder.withBescheid(BescheidTestFactory.createBuilder().sendBy(SendBy.MANUAL).build()); + + var protokollInfo = builder.createHistorienProtokollInformation(); + + assertThat(protokollInfo.getAktion()).isEqualTo(GESPEICHERT); + } + + @Test + void shouldHaveGesendetInAktion() { + builder.withBescheid(BescheidTestFactory.createBuilder().sendBy(SendBy.NACHRICHT).build()); + + var protokollInfo = builder.createHistorienProtokollInformation(); + + assertThat(protokollInfo.getAktion()).isEqualTo(GESENDET); + } + } + + @Nested + class TestCreateAnlage { + private MockedStatic<AnlageDokumentTypeBuilder> anlageDokumentTypeBuilderMockedStatic; + @Mock + private AnlageDokumentTypeBuilder anlageDokumentTypeBuilder; + private final AnlageDokumentType expectedAnlage = AnlageDokumentTypeTestFactory.create(); + private final OzgFile attachment = OzgFileTestFactory.createWithUniqueId(); + + @BeforeEach + void setUp() { + anlageDokumentTypeBuilderMockedStatic = mockStatic(AnlageDokumentTypeBuilder.class); + anlageDokumentTypeBuilderMockedStatic.when(AnlageDokumentTypeBuilder::builder).thenReturn(anlageDokumentTypeBuilder); + when(anlageDokumentTypeBuilder.withOzgFile(attachment)).thenReturn(anlageDokumentTypeBuilder); + when(anlageDokumentTypeBuilder.build()).thenReturn(expectedAnlage); + } + + @AfterEach + void tearDown() { + anlageDokumentTypeBuilderMockedStatic.close(); + } + + @Test + void shouldSetOzgFile() { + callCreateAnlage(); + + verify(anlageDokumentTypeBuilder).withOzgFile(attachment); + } + + @Test + void shouldBuildAnlageDokumentType() { + callCreateAnlage(); + + verify(anlageDokumentTypeBuilder).build(); + } + + @Test + void shouldReturnBuiltAnlage() { + var resultAnlage = callCreateAnlage(); + + assertThat(resultAnlage).isEqualTo(expectedAnlage); + } + + private AnlageDokumentType callCreateAnlage() { + return builder.createAnlage(attachment); + } + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/bescheid/ExportBescheidServiceTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/bescheid/ExportBescheidServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..c502ffde25714570e0897df946cf97c6cd72bc6f --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/bescheid/ExportBescheidServiceTest.java @@ -0,0 +1,419 @@ +package de.ozgcloud.alfa.bescheid; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.List; +import java.util.stream.Stream; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Spy; + +import de.ozgcloud.alfa.bescheid.BescheidExportData.BescheidExportDataBuilder; +import de.ozgcloud.alfa.common.binaryfile.BinaryFileService; +import de.ozgcloud.alfa.common.binaryfile.FileId; +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.file.OzgFileTestFactory; +import de.ozgcloud.alfa.common.user.UserProfile; +import de.ozgcloud.alfa.common.user.UserProfileTestFactory; +import de.ozgcloud.alfa.common.user.UserService; +import de.ozgcloud.alfa.export.DokumentTypeTestFactory; +import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; +import de.ozgcloud.alfa.vorgang.VorgangWithEingang; +import de.ozgcloud.alfa.vorgang.VorgangWithEingangTestFactory; +import de.xoev.xdomea.DokumentType; + +class ExportBescheidServiceTest { + + @InjectMocks + @Spy + private ExportBescheidService service; + + @Mock + private BescheidService bescheidService; + + @Mock + private BinaryFileService binaryFileService; + + @Mock + private DocumentService documentService; + + @Mock + private UserService userService; + + @Nested + class TestCreateExportData { + private final VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); + private final Bescheid bescheid = BescheidTestFactory.create(); + private final BescheidExportData exportData = BescheidExportDataTestFactory.create(); + private final BescheidExportInput input = BescheidExportInputTestFactory.create(); + + private MockedStatic<BescheidExportData> bescheidExportDataMockedStatic; + @Mock + private BescheidExportDataBuilder exportDataBuilder; + + @BeforeEach + void setUpMocks() { + bescheidExportDataMockedStatic = mockStatic(BescheidExportData.class); + bescheidExportDataMockedStatic.when(BescheidExportData::builder).thenReturn(exportDataBuilder); + + doReturn(Stream.of(bescheid)).when(service).getBescheids(vorgang.getId()); + when(exportDataBuilder.build()).thenReturn(exportData); + doReturn(input).when(service).createBescheidExportInput(bescheid, vorgang); + doNothing().when(service).addBescheidExportData(input, exportDataBuilder); + } + + @AfterEach + void tearDown() { + bescheidExportDataMockedStatic.close(); + } + + @Test + void shouldGetBescheids() { + callService(); + + verify(service).getBescheids(vorgang.getId()); + } + + @Test + void shouldCreateInputData() { + callService(); + + verify(service).createBescheidExportInput(bescheid, vorgang); + } + + @Test + void shouldAddInputToBuilder() { + callService(); + + verify(service).addBescheidExportData(input, exportDataBuilder); + } + + @Test + void shouldBuildExportData() { + callService(); + + verify(exportDataBuilder).build(); + } + + @Test + void shouldReturnBuiltExportData() { + var result = callService(); + + assertThat(result).isEqualTo(exportData); + } + + private BescheidExportData callService() { + return service.createExportData(vorgang); + } + } + + @Nested + class TestGetBescheids { + private final String vorgangId = VorgangHeaderTestFactory.ID; + private final Bescheid bescheid = BescheidTestFactory.createBuilder().status(BescheidStatus.SENT).build(); + private final Bescheid bescheidDraft = BescheidTestFactory.createBuilder().status(BescheidStatus.DRAFT).build(); + + @Test + void shouldCallBescheidService() { + callService(); + + verify(bescheidService).findByVorgangIdSorted(vorgangId); + } + + @Test + void shouldReturnBescheids() { + when(bescheidService.findByVorgangIdSorted(vorgangId)).thenReturn(Stream.of(bescheid)); + + var resultBescheids = callService(); + + assertThat(resultBescheids).containsExactly(bescheid); + } + + @Test + void shouldNotReturnDrafts() { + when(bescheidService.findByVorgangIdSorted(vorgangId)).thenReturn(Stream.of(bescheid, bescheidDraft)); + + var resultBescheids = callService(); + + assertThat(resultBescheids).containsExactly(bescheid); + } + + private Stream<Bescheid> callService() { + return service.getBescheids(vorgangId); + } + } + + @Nested + class TestCreateBescheidExportInput { + private final VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); + private final Bescheid bescheid = BescheidTestFactory.create(); + private final OzgFile document = OzgFileTestFactory.createWithUniqueId(); + private final OzgFile attachment = OzgFileTestFactory.createWithUniqueId(); + + @BeforeEach + void setUpMocks() { + doReturn(Stream.of(attachment)).when(service).getAttachments(bescheid); + doReturn(document).when(service).getDocument(bescheid); + } + + @Test + void shouldCallGetAttachents() { + callService(); + + verify(service).getAttachments(bescheid); + } + + @Test + void shouldCallGetDocument() { + callService(); + + verify(service).getDocument(bescheid); + } + + @Test + void shouldReturnInputData() { + var resultInput = callService(); + + assertThat(resultInput).usingRecursiveComparison() + .isEqualTo(BescheidExportInputTestFactory.createBuilder().files(List.of(document, attachment)).build()); + } + + private BescheidExportInput callService() { + return service.createBescheidExportInput(bescheid, vorgang); + } + } + + @Nested + class TestGetDocument { + private final Bescheid bescheid = BescheidTestFactory.create(); + private final Document document = DocumentTestFactory.create(); + private final OzgFile ozgDocument = OzgFileTestFactory.create(); + + @BeforeEach + void setUpMock() { + when(documentService.getDocument(bescheid.getBescheidDocument())).thenReturn(document); + } + + @Test + void shouldCallDocumentService() { + callService(); + + verify(documentService).getDocument(bescheid.getBescheidDocument()); + } + + @Test + void shouldCallBinaryFileService() { + callService(); + + verify(binaryFileService).getFile(DocumentTestFactory.FILE_ID); + } + + @Test + void shouldReturnOzgFile() { + when(binaryFileService.getFile(DocumentTestFactory.FILE_ID)).thenReturn(ozgDocument); + + var resultDocument = callService(); + + assertThat(resultDocument).isEqualTo(ozgDocument); + } + + private OzgFile callService() { + return service.getDocument(bescheid); + } + } + + @Nested + class TestGetAttachments { + private final Bescheid bescheid = BescheidTestFactory.create(); + private final List<FileId> fileIds = BescheidTestFactory.ATTACHMENTS; + + @Test + void shouldCallBinaryFileServiceGetFile() { + service.getAttachments(bescheid); + + verify(binaryFileService).getFiles(fileIds); + } + + @Test + void shouldReturnGottenOzgFiles() { + var expectedOzgFile = OzgFileTestFactory.createWithUniqueId(); + when(binaryFileService.getFiles(fileIds)).thenReturn(Stream.of(expectedOzgFile)); + + var resultOzgFiles = service.getAttachments(bescheid); + + assertThat(resultOzgFiles).containsExactly(expectedOzgFile); + } + } + + @Nested + class TestAddBescheidExportData { + private final List<OzgFile> files = BescheidExportInputTestFactory.FILES; + private final DokumentType dokumentType = DokumentTypeTestFactory.create(); + private final BescheidExportInput exportInput = BescheidExportInputTestFactory.create(); + + @Mock + private BescheidExportDataBuilder exportDataBuilder; + + @BeforeEach + void setUpMocks() { + doReturn(dokumentType).when(service).buildDokumentType(exportInput); + when(exportDataBuilder.dokumentType(dokumentType)).thenReturn(exportDataBuilder); + } + + @Test + void shouldAddAttachmentsToBuilder() { + callService(); + + verify(exportDataBuilder).files(files); + } + + @Test + void shouldBuildDokumentType() { + callService(); + + verify(service).buildDokumentType(exportInput); + } + + @Test + void shouldAddDokumentTypeToBuilder() { + callService(); + + verify(exportDataBuilder).dokumentType(dokumentType); + } + + private void callService() { + service.addBescheidExportData(exportInput, exportDataBuilder); + } + } + + @Nested + class TestBuildDokumentType { + private final BescheidExportInput exportInput = BescheidExportInputTestFactory.create(); + private final Bescheid bescheid = BescheidExportInputTestFactory.BESCHEID; + private final List<OzgFile> files = BescheidExportInputTestFactory.FILES; + private final String fullName = UserProfileTestFactory.FULLNAME; + + private MockedStatic<DokumentTypeBuilder> dokumentTypeBuilderMockedStatic; + @Mock + private DokumentTypeBuilder dokumentTypeBuilder; + + @BeforeEach + void setUp() { + dokumentTypeBuilderMockedStatic = mockStatic(DokumentTypeBuilder.class); + dokumentTypeBuilderMockedStatic.when(DokumentTypeBuilder::builder).thenReturn(dokumentTypeBuilder); + + when(dokumentTypeBuilder.withBescheid(bescheid)).thenReturn(dokumentTypeBuilder); + when(dokumentTypeBuilder.withFiles(files)).thenReturn(dokumentTypeBuilder); + when(dokumentTypeBuilder.withFullName(fullName)).thenReturn(dokumentTypeBuilder); + when(dokumentTypeBuilder.withOrganisationseinheitenId(BescheidExportInputTestFactory.ORGANISATIONSEINHEITEN_ID)) + .thenReturn(dokumentTypeBuilder); + + doReturn(fullName).when(service).getFullName(bescheid); + } + + @AfterEach + void tearDown() { + dokumentTypeBuilderMockedStatic.close(); + } + + @Test + void shouldCallBuilder() { + callService(); + + dokumentTypeBuilderMockedStatic.verify(DokumentTypeBuilder::builder); + } + + @Test + void shouldBuildWithBescheid() { + callService(); + + verify(dokumentTypeBuilder).withBescheid(bescheid); + } + + @Test + void shouldBuildWithOzgFiles() { + callService(); + + verify(dokumentTypeBuilder).withFiles(files); + } + + @Test + void shouldGetFullName() { + callService(); + + verify(service).getFullName(bescheid); + } + + @Test + void shouldBuildWithFullName() { + callService(); + + verify(dokumentTypeBuilder).withFullName(fullName); + } + + @Test + void shouldBuildWithOrganisationseinheitenId() { + callService(); + + verify(dokumentTypeBuilder).withOrganisationseinheitenId(BescheidExportInputTestFactory.ORGANISATIONSEINHEITEN_ID); + } + + @Test + void shouldBuild() { + callService(); + + verify(dokumentTypeBuilder).build(); + } + + @Test + void shouldReturnBuiltDokumentType() { + var expectedDokumentType = DokumentTypeTestFactory.create(); + when(dokumentTypeBuilder.build()).thenReturn(expectedDokumentType); + + var resultDokumentType = callService(); + + assertThat(resultDokumentType).isEqualTo(expectedDokumentType); + } + + private DokumentType callService() { + return service.buildDokumentType(exportInput); + } + } + + @Nested + class TestGetFullName { + private final Bescheid bescheid = BescheidTestFactory.create(); + private final UserProfile userProfile = UserProfileTestFactory.create(); + private final String expectedFullName = UserProfileTestFactory.FULLNAME; + + @BeforeEach + void mockUserService() { + when(userService.getById(SentInfoTestFactory.SENT_BY)).thenReturn(userProfile); + } + + @Test + void shouldCallUserServiceGetbyId() { + callService(); + + verify(userService).getById(SentInfoTestFactory.SENT_BY); + } + + @Test + void shouldReturnOptionalOfUserProfile() { + var fullName = callService(); + + assertThat(fullName).isEqualTo(expectedFullName); + } + + private String callService() { + return service.getFullName(bescheid); + } + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/AnlageDokumentTypeBuilderTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/AnlageDokumentTypeBuilderTest.java new file mode 100644 index 0000000000000000000000000000000000000000..de772e2c7761a3135c5699ed06045d216c3a1b19 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/AnlageDokumentTypeBuilderTest.java @@ -0,0 +1,110 @@ +package de.ozgcloud.alfa.common; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.time.ZonedDateTime; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Spy; + +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.file.OzgFileTestFactory; +import de.ozgcloud.alfa.export.IdentifikationObjektTypeTestFactory; +import de.xoev.xdomea.IdentifikationObjektType; +import de.xoev.xdomea.VersionType; + +class AnlageDokumentTypeBuilderTest { + + private final OzgFile ozgFile = OzgFileTestFactory.create(); + private final static ZonedDateTime CREATED_AT = ZonedDateTime.now(); + @Spy + private AnlageDokumentTypeBuilder builder = AnlageDokumentTypeBuilder.builder().withOzgFile(ozgFile).withCreatedAt(CREATED_AT); + + @Nested + class TestBuild { + private MockedStatic<IdentifikationObjektTypeBuilder> identifikationObjektTypeBuilderMockedStatic; + @Mock + private IdentifikationObjektTypeBuilder identifikationObjektTypeBuilder; + private final IdentifikationObjektType identifikationObjektType = IdentifikationObjektTypeTestFactory.create(); + + private MockedStatic<VersionTypeBuilder> versionTypeBuilderMockedStatic; + @Mock + private VersionTypeBuilder versionTypeBuilder; + private final VersionType version = VersionTypeTestFactory.create(); + + @BeforeEach + void setUp() { + identifikationObjektTypeBuilderMockedStatic = mockStatic(IdentifikationObjektTypeBuilder.class); + identifikationObjektTypeBuilderMockedStatic.when(IdentifikationObjektTypeBuilder::builder).thenReturn(identifikationObjektTypeBuilder); + when(identifikationObjektTypeBuilder.withObjectID(OzgFileTestFactory.ID.toString())).thenReturn(identifikationObjektTypeBuilder); + when(identifikationObjektTypeBuilder.build()).thenReturn(identifikationObjektType); + + versionTypeBuilderMockedStatic = mockStatic(VersionTypeBuilder.class); + versionTypeBuilderMockedStatic.when(VersionTypeBuilder::builder).thenReturn(versionTypeBuilder); + when(versionTypeBuilder.withCreatedAt(CREATED_AT)).thenReturn(versionTypeBuilder); + when(versionTypeBuilder.withOzgFile(ozgFile)).thenReturn(versionTypeBuilder); + when(versionTypeBuilder.build()).thenReturn(version); + } + + @AfterEach + void tearDown() { + identifikationObjektTypeBuilderMockedStatic.close(); + versionTypeBuilderMockedStatic.close(); + } + + @Test + void shouldSetObjectId() { + builder.build(); + + verify(identifikationObjektTypeBuilder).withObjectID(ozgFile.getId().toString()); + } + + @Test + void shouldBuildIdentifikationObjectType() { + builder.build(); + + verify(identifikationObjektTypeBuilder).build(); + } + + @Test + void shouldHaveIdentifikation() { + var anlage = builder.build(); + + assertThat(anlage.getIdentifikation()).isEqualTo(identifikationObjektType); + } + + @Test + void shouldSetCreatedAt() { + builder.build(); + + verify(versionTypeBuilder).withCreatedAt(CREATED_AT); + } + + @Test + void shouldSetOzgFile() { + builder.build(); + + verify(versionTypeBuilder).withOzgFile(ozgFile); + } + + @Test + void shouldBuildVersionType() { + builder.build(); + + verify(versionTypeBuilder).build(); + } + + @Test + void shouldHaveVersion() { + var anlage = builder.build(); + + assertThat(anlage.getVersion()).contains(version); + } + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/AnlageDokumentTypeTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/AnlageDokumentTypeTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..f932ea1d538e812148824460da9a0dd9bae5e494 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/AnlageDokumentTypeTestFactory.java @@ -0,0 +1,11 @@ +package de.ozgcloud.alfa.common; + +import de.xoev.xdomea.AnlageDokumentType; + +public class AnlageDokumentTypeTestFactory { + + public static AnlageDokumentType create() { + return new AnlageDokumentType(); + } + +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/DateConverterTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/DateConverterTest.java new file mode 100644 index 0000000000000000000000000000000000000000..d6673fc2325d7ef87fed22b5d7c920812308d5b0 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/DateConverterTest.java @@ -0,0 +1,88 @@ +package de.ozgcloud.alfa.common; + +import static org.assertj.core.api.Assertions.*; + +import java.time.ZonedDateTime; +import java.util.Optional; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +import de.ozgcloud.common.errorhandling.TechnicalException; + +class DateConverterTest { + + @Nested + class TestConvertGermanFormatToISO { + + private static final int YEAR = 2023; + private static final int MONTH = 2; + private static final int DAY = 14; + + private static final String DATE = String.format("%s.%s%s.%s", DAY, 0, MONTH, YEAR); + + @Test + void shouldConvert() { + var converted = callConverter(DATE); + + assertThat(converted).get().extracting(XMLGregorianCalendar::getYear, XMLGregorianCalendar::getMonth, XMLGregorianCalendar::getDay) + .containsExactly(YEAR, MONTH, DAY); + } + + @ParameterizedTest + @ValueSource(strings = { "2005-10-10", "abc", "19. February 1970", " ", "" }) + void shouldReturnEmpty(String dateStr) { + var converted = callConverter(dateStr); + + assertThat(converted).isEmpty(); + } + + @Test + void shouldReturnEmptyIfDateIsNull() { + var converted = callConverter(null); + + assertThat(converted).isEmpty(); + } + + private Optional<XMLGregorianCalendar> callConverter(String dateStr) { + return DateConverter.convertGermanFormatToISO(dateStr); + } + } + + @Nested + class TestCreateDatatypeFactory { + + @Test + void shouldThrowTechnicalException() { + try (MockedStatic<DatatypeFactory> datatypeFactory = Mockito.mockStatic(DatatypeFactory.class)) { + datatypeFactory.when(DatatypeFactory::newInstance).thenThrow(DatatypeConfigurationException.class); + + assertThatThrownBy(() -> DateConverter.createDatatypeFactory()).isInstanceOf(TechnicalException.class); + } + } + } + + @Nested + class TestToXmlGregorianCalendar { + + @Test + void shouldConvertZonedDateTime() { + var date = ZonedDateTime.now(); + + var xmlGregorianCalendar = DateConverter.toXmlGregorianCalendar(date); + + assertThat(xmlGregorianCalendar.getYear()).isEqualTo(date.getYear()); + assertThat(xmlGregorianCalendar.getMonth()).isEqualTo(date.getMonthValue()); + assertThat(xmlGregorianCalendar.getDay()).isEqualTo(date.getDayOfMonth()); + } + + } +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/DateiformatCodeTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/DateiformatCodeTest.java new file mode 100644 index 0000000000000000000000000000000000000000..51be0e165911b9ddf5398b2a69b62abba8f0812b --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/DateiformatCodeTest.java @@ -0,0 +1,70 @@ +package de.ozgcloud.alfa.common; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; +import org.junit.jupiter.params.provider.ValueSource; + +class DateiformatCodeTest { + + @Nested + class TestGetXdomeaCode { + + @Test + void shouldReturnCode() { + var code = DateiformatCode.getXdomeaCode("application/pdf", "pdf"); + + assertThat(code).isEqualTo("018"); + } + + @Test + void shouldReturnSonstiges() { + var code = DateiformatCode.getXdomeaCode("abc", "abc"); + + assertThat(code).isEqualTo(DateiformatCode.SONSTIGES_CODE); + } + + @ParameterizedTest + @NullAndEmptySource + void shouldReturnCodeOnSingleFileExtensionMapping(String extension) { + var code = DateiformatCode.getXdomeaCode("application/pdf", extension); + + assertThat(code).isEqualTo("018"); + } + + @Test + void shouldReturnCodeOnMultipleFileExtensionMapping() { + var code = DateiformatCode.getXdomeaCode("image/jpeg", "jpg"); + + assertThat(code).isEqualTo("011"); + } + + @ParameterizedTest + @NullAndEmptySource + void shouldReturnSonstigesOnMultipleFileExtensionMapping(String extension) { + var code = DateiformatCode.getXdomeaCode("image/jpeg", extension); + + assertThat(code).isEqualTo(DateiformatCode.SONSTIGES_CODE); + } + + @ParameterizedTest + @NullAndEmptySource + void shouldReturnSonstigesOnEmptyMimeType(String mimeType) { + var code = DateiformatCode.getXdomeaCode(mimeType, "pdf"); + + assertThat(code).isEqualTo(DateiformatCode.SONSTIGES_CODE); + } + + @ParameterizedTest + @ValueSource(strings = { "application/xml", "text/xml" }) + void shouldReturnXml(String mimeType) { + var code = DateiformatCode.getXdomeaCode(mimeType, "xml"); + + assertThat(code).isEqualTo("030"); + } + } + +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/DateiformatCodeTypeTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/DateiformatCodeTypeTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..299391ad928a9c7bacba0101e474592f55874c8a --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/DateiformatCodeTypeTestFactory.java @@ -0,0 +1,11 @@ +package de.ozgcloud.alfa.common; + +import de.xoev.xdomea.DateiformatCodeType; + +public class DateiformatCodeTypeTestFactory { + + public static DateiformatCodeType create() { + return new DateiformatCodeType(); + } + +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/FormatTypeTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/FormatTypeTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..ea0393aea974a6b7f00fad540c30e630d9e6e520 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/FormatTypeTestFactory.java @@ -0,0 +1,10 @@ +package de.ozgcloud.alfa.common; + +import de.xoev.xdomea.FormatType; + +public class FormatTypeTestFactory { + + public static FormatType create() { + return new FormatType(); + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/HistorienProtokollInformationTypeTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/HistorienProtokollInformationTypeTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..425a9731e62f3055a703ef2aecd623ba5603ea83 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/HistorienProtokollInformationTypeTestFactory.java @@ -0,0 +1,11 @@ +package de.ozgcloud.alfa.common; + +import de.xoev.xdomea.HistorienProtokollInformationType; + +public class HistorienProtokollInformationTypeTestFactory { + + public static HistorienProtokollInformationType create() { + return new HistorienProtokollInformationType(); + } + +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/IdentifikationObjektTypeBuilderTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/IdentifikationObjektTypeBuilderTest.java new file mode 100644 index 0000000000000000000000000000000000000000..55aeed8af0216295c413cab2c1e48443b105558a --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/IdentifikationObjektTypeBuilderTest.java @@ -0,0 +1,63 @@ +package de.ozgcloud.alfa.common; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Random; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Spy; + +import de.ozgcloud.alfa.common.file.OzgFileTestFactory; +import de.ozgcloud.alfa.export.IdentifikationObjektTypeTestFactory; + +class IdentifikationObjektTypeBuilderTest { + private static final Long DOKUMENT_ORDINAL_NUMBER = new Random().nextLong(); + + @Spy + private IdentifikationObjektTypeBuilder builder = IdentifikationObjektTypeBuilder.builder().withObjectID(OzgFileTestFactory.ID.toString()) + .withOrdinalNumber(DOKUMENT_ORDINAL_NUMBER); + + @Nested + class TestBuild { + private MockedStatic<UUIDConverter> uuidConverterMockedStatic; + + @BeforeEach + void setUp() { + uuidConverterMockedStatic = mockStatic(UUIDConverter.class); + uuidConverterMockedStatic.when(() -> UUIDConverter.fromObjectId(OzgFileTestFactory.ID.toString())) + .thenReturn(IdentifikationObjektTypeTestFactory.ID); + } + + @AfterEach + void tearDown() { + uuidConverterMockedStatic.close(); + } + + @Test + void shouldConvertOzgFileId() { + builder.build(); + + uuidConverterMockedStatic.verify(() -> UUIDConverter.fromObjectId(OzgFileTestFactory.ID.toString())); + } + + @Test + void shouldHaveId() { + var identifikation = builder.build(); + + assertThat(identifikation.getID()).isEqualTo(IdentifikationObjektTypeTestFactory.ID); + } + + @Test + void shouldHaveNummerImUebergeordnetenContainer() { + var identifikation = builder.build(); + + assertThat(identifikation.getNummerImUebergeordnetenContainer()).isEqualTo(DOKUMENT_ORDINAL_NUMBER); + } + } + +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/PrimaerdokumentTypeBuilderTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/PrimaerdokumentTypeBuilderTest.java new file mode 100644 index 0000000000000000000000000000000000000000..c269f1948b14a8484a0250f77b29fcbe95fe8906 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/PrimaerdokumentTypeBuilderTest.java @@ -0,0 +1,106 @@ +package de.ozgcloud.alfa.common; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.time.ZonedDateTime; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; + +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.file.OzgFileTestFactory; + +class PrimaerdokumentTypeBuilderTest { + + private final PrimaerdokumentTypeBuilder builder = PrimaerdokumentTypeBuilder.builder().withOzgFile(OzgFileTestFactory.createWithUniqueId()); + + @Nested + class TestBuild { + + private MockedStatic<ExportFilenameGenerator> exportFilenameGeneratorMockedStatic; + + private static final String ERSTELLER = "Ersteller"; + private static final String GENERATED_FILE_NAME = "file_name"; + private static final ZonedDateTime CREATED_AT = ZonedDateTime.now(); + private final OzgFile ozgFile = OzgFileTestFactory.createWithUniqueId(); + + @BeforeEach + void setUp() { + exportFilenameGeneratorMockedStatic = mockStatic(ExportFilenameGenerator.class); + exportFilenameGeneratorMockedStatic.when(() -> ExportFilenameGenerator.generateExportFilename(ozgFile)).thenReturn(GENERATED_FILE_NAME); + } + + @AfterEach + void tearDown() { + exportFilenameGeneratorMockedStatic.close(); + } + + @Test + void shouldGenerateExportFilename() { + builder.withOzgFile(ozgFile).build(); + + exportFilenameGeneratorMockedStatic.verify(() -> ExportFilenameGenerator.generateExportFilename(ozgFile)); + } + + @Test + void shouldHaveDateiname() { + var primaerdokumentType = builder.withOzgFile(ozgFile).build(); + + assertThat(primaerdokumentType.getDateiname()).isEqualTo(GENERATED_FILE_NAME); + } + + @Test + void shouldNotHaveDateiname() { + var primaerdokumentType = builder.build(); + + assertThat(primaerdokumentType.getDateiname()).isNull(); + } + + @Test + void shouldHaveDateinameOriginal() { + var primaerdokumentType = builder.withOzgFile(ozgFile).build(); + + assertThat(primaerdokumentType.getDateinameOriginal()).isEqualTo(OzgFileTestFactory.NAME); + } + + @Test + void shouldHaveErsteller() { + var primaerdokumentType = builder.withErsteller(ERSTELLER).build(); + + assertThat(primaerdokumentType.getErsteller()).isEqualTo(ERSTELLER); + } + + @Test + void shouldNotHaveErsteller() { + var primaerdokumentType = builder.build(); + + assertThat(primaerdokumentType.getErsteller()).isNull(); + } + + @Test + void shouldHaveDatumUhrzeit() { + var primaerdokumentType = builder.withCreatedAt(CREATED_AT).build(); + + assertThat(primaerdokumentType.getDatumUhrzeit()).isEqualTo(DateConverter.toXmlGregorianCalendar(CREATED_AT)); + } + + @Test + void shouldNotHaveDatumUhrzeit() { + var primaerdokumentType = builder.build(); + + assertThat(primaerdokumentType.getDatumUhrzeit()).isNull(); + } + + @Test + void shouldThrowIllegalgStateException() { + builder.withOzgFile(null); + + assertThatThrownBy(builder::build).isInstanceOf(IllegalStateException.class); + } + } + +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/PrimaerdokumentTypeTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/PrimaerdokumentTypeTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..9ea20bb8172b6528091a928726a3e4beff46448c --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/PrimaerdokumentTypeTestFactory.java @@ -0,0 +1,10 @@ +package de.ozgcloud.alfa.common; + +import de.xoev.xdomea.PrimaerdokumentType; + +public class PrimaerdokumentTypeTestFactory { + + public static PrimaerdokumentType create() { + return new PrimaerdokumentType(); + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/VersionTypeBuilderTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/VersionTypeBuilderTest.java new file mode 100644 index 0000000000000000000000000000000000000000..219cca4fdeb0a561cf52a66fd6af6414fcc2fd3f --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/VersionTypeBuilderTest.java @@ -0,0 +1,208 @@ +package de.ozgcloud.alfa.common; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.time.ZonedDateTime; + +import org.apache.commons.io.FilenameUtils; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Spy; + +import com.thedeanda.lorem.LoremIpsum; + +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.file.OzgFileTestFactory; +import de.xoev.xdomea.DateiformatCodeType; +import de.xoev.xdomea.FormatType; + +class VersionTypeBuilderTest { + private static final String FILE_NAME = "TestFile.ext"; + private final OzgFile ozgFile = OzgFileTestFactory.createBuilder().name(FILE_NAME).build(); + private final static ZonedDateTime CREATED_AT = ZonedDateTime.now(); + private final static String ERSTELLER = LoremIpsum.getInstance().getName(); + private final static String SONSTIGER_NAME = LoremIpsum.getInstance().getName(); + @Spy + private VersionTypeBuilder builder = VersionTypeBuilder.builder().withOzgFile(ozgFile).withCreatedAt(CREATED_AT).withErsteller(ERSTELLER) + .withSonstigerName(SONSTIGER_NAME); + + @Nested + class TestBuild { + private final FormatType formatType = FormatTypeTestFactory.create(); + + @BeforeEach + void setUp() { + doReturn(formatType).when(builder).createFormatType(); + } + + @Test + void shouldCallCreateFormatType() { + builder.build(); + + verify(builder).createFormatType(); + } + + @Test + void shouldHaveNummer() { + var version = builder.build(); + + assertThat(version.getNummer()).isEqualTo(VersionTypeBuilder.VERSION_NUMMER); + } + + @Test + void shouldHaveFormatType() { + var version = builder.build(); + + assertThat(version.getFormat()).contains(formatType); + } + } + + @Nested + class TestCreateFormatType { + private MockedStatic<PrimaerdokumentTypeBuilder> primaerdokumentTypeBuilderMockedStatic; + @Mock + private PrimaerdokumentTypeBuilder primaerdokumentTypeBuilder; + + private final DateiformatCodeType dateiformatCodeType = DateiformatCodeTypeTestFactory.create(); + + @BeforeEach + void setUp() { + primaerdokumentTypeBuilderMockedStatic = mockStatic(PrimaerdokumentTypeBuilder.class); + primaerdokumentTypeBuilderMockedStatic.when(PrimaerdokumentTypeBuilder::builder).thenReturn(primaerdokumentTypeBuilder); + when(primaerdokumentTypeBuilder.withOzgFile(ozgFile)).thenReturn(primaerdokumentTypeBuilder); + when(primaerdokumentTypeBuilder.withCreatedAt(CREATED_AT)).thenReturn(primaerdokumentTypeBuilder); + when(primaerdokumentTypeBuilder.withErsteller(ERSTELLER)).thenReturn(primaerdokumentTypeBuilder); + doReturn(dateiformatCodeType).when(builder).createDateiformatCodeType(); + } + + @AfterEach + void tearDown() { + primaerdokumentTypeBuilderMockedStatic.close(); + } + + @Test + void shouldBuildPrimaerdokument() { + callCreateFormatType(); + + verify(primaerdokumentTypeBuilder).build(); + } + + @Test + void shouldSetOzgFile() { + callCreateFormatType(); + + verify(primaerdokumentTypeBuilder).withOzgFile(ozgFile); + } + + @Test + void shouldSetCreatedAt() { + callCreateFormatType(); + + verify(primaerdokumentTypeBuilder).withCreatedAt(CREATED_AT); + } + + @Test + void shouldSetErsteller() { + callCreateFormatType(); + + verify(primaerdokumentTypeBuilder).withErsteller(ERSTELLER); + } + + @Test + void shouldHaveEmptyVersion() { + var formatType = callCreateFormatType(); + + assertThat(formatType.getVersion()).isEmpty(); + } + + @Test + void shouldCreateDateiformatCode() { + callCreateFormatType(); + + verify(builder).createDateiformatCodeType(); + } + + @Test + void shouldHaveName() { + var formatType = callCreateFormatType(); + + assertThat(formatType.getName()).isEqualTo(dateiformatCodeType); + } + + @Test + void shouldHaveSonstigerName() { + var formatType = callCreateFormatType(); + + assertThat(formatType.getSonstigerName()).isEqualTo(SONSTIGER_NAME); + } + + private FormatType callCreateFormatType() { + return builder.createFormatType(); + } + } + + @Nested + class TestCreateDateiformatCodeType { + + private static final String CODE = "111"; + + private MockedStatic<DateiformatCode> dateiformatCodeMockedStatic; + + @BeforeEach + void setUp() { + dateiformatCodeMockedStatic = mockStatic(DateiformatCode.class); + dateiformatCodeMockedStatic.when( + () -> DateiformatCode.getXdomeaCode(OzgFileTestFactory.CONTENT_TYPE, FilenameUtils.getExtension(FILE_NAME))) + .thenReturn(CODE); + } + + @AfterEach + void tearDown() { + dateiformatCodeMockedStatic.close(); + } + + @Test + void shouldHaveListURI() { + var dateiformatCode = builder.createDateiformatCodeType(); + + assertThat(dateiformatCode.getListURI()).isEqualTo(VersionTypeBuilder.DATEI_FORMAT_LIST_URI); + } + + @Test + void shouldHaveListVersionID() { + var dateiformatCode = builder.createDateiformatCodeType(); + + assertThat(dateiformatCode.getListVersionID()).isEqualTo(VersionTypeBuilder.LIST_VERSION_ID); + } + + @Test + void shouldGetXdomeaCode() { + builder.createDateiformatCodeType(); + + dateiformatCodeMockedStatic.verify( + () -> DateiformatCode.getXdomeaCode(OzgFileTestFactory.CONTENT_TYPE, FilenameUtils.getExtension(FILE_NAME))); + } + + @Test + void shouldTransformExtensionToLowerCase() { + builder.withOzgFile(OzgFileTestFactory.createBuilder().name("TestFile.EXT").build()); + + builder.createDateiformatCodeType(); + + dateiformatCodeMockedStatic.verify( + () -> DateiformatCode.getXdomeaCode(OzgFileTestFactory.CONTENT_TYPE, FilenameUtils.getExtension(FILE_NAME))); + } + + @Test + void shouldHaveCode() { + var dateiformatCode = builder.createDateiformatCodeType(); + + assertThat(dateiformatCode.getCode()).isEqualTo(CODE); + } + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/VersionTypeTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/VersionTypeTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..f2fcd270fad8435d51170bd8963b3883baf7aa27 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/common/VersionTypeTestFactory.java @@ -0,0 +1,12 @@ +package de.ozgcloud.alfa.common; + +import de.xoev.xdomea.VersionType; + +public class VersionTypeTestFactory { + + public static VersionType create() { + var versionType = new VersionType(); + versionType.getFormat().add(FormatTypeTestFactory.create()); + return versionType; + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/AbgabeAbgabe0401TestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/AbgabeAbgabe0401TestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..16ea606a308c0864e06bf26d32138166313b4b1a --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/AbgabeAbgabe0401TestFactory.java @@ -0,0 +1,10 @@ +package de.ozgcloud.alfa.export; + +import de.xoev.xdomea.AbgabeAbgabe0401; + +public class AbgabeAbgabe0401TestFactory { + + public static AbgabeAbgabe0401 create() { + return new AbgabeAbgabe0401(); + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/AkteTypeTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/AkteTypeTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..a13852e5a7eb4ad6cf42af49f7cf983d81a0e8a1 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/AkteTypeTestFactory.java @@ -0,0 +1,10 @@ +package de.ozgcloud.alfa.export; + +import de.xoev.xdomea.AkteType; + +public class AkteTypeTestFactory { + + public static AkteType create() { + return new AkteType(); + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/AllgemeineMetadatenTypeTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/AllgemeineMetadatenTypeTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..fc7dd301486edbb9fc0ba13bef92329bdf208872 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/AllgemeineMetadatenTypeTestFactory.java @@ -0,0 +1,16 @@ +package de.ozgcloud.alfa.export; + +import com.thedeanda.lorem.LoremIpsum; + +import de.xoev.xdomea.AllgemeineMetadatenType; + +public class AllgemeineMetadatenTypeTestFactory { + + public static final String KENNZEICHEN = LoremIpsum.getInstance().getWords(1); + + public static AllgemeineMetadatenType create() { + var allgemeineMetadatenType = new AllgemeineMetadatenType(); + allgemeineMetadatenType.setKennzeichen(KENNZEICHEN); + return allgemeineMetadatenType; + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/DokumentTypeTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/DokumentTypeTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..8de8ed3e01318e4883481d704d6db97012b0c708 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/DokumentTypeTestFactory.java @@ -0,0 +1,11 @@ +package de.ozgcloud.alfa.export; + +import de.xoev.xdomea.DokumentType; + +public class DokumentTypeTestFactory { + + public static DokumentType create() { + var dokument = new DokumentType(); + return dokument; + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/ExportConfigurationTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/ExportConfigurationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..4dc62c958303b3a467bd9c32a432df417fcdab87 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/ExportConfigurationTest.java @@ -0,0 +1,77 @@ +package de.ozgcloud.alfa.export; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Map; + +import jakarta.xml.bind.Marshaller; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.springframework.oxm.jaxb.Jaxb2Marshaller; + +class ExportConfigurationTest { + + @Spy + @InjectMocks + private ExportConfiguration configuration; + + @Mock + private XdomeaNamespacePrefixMapper prefixMapper; + + @Nested + class TestCreateMarshallerProperties { + + @Test + void shouldFromatMarshalledXml() { + var props = configuration.createMarshallerProperties(); + + assertThat(props).containsEntry(Marshaller.JAXB_FORMATTED_OUTPUT, ExportConfiguration.JAXB_FORMATTED_OUTPUT); + } + + @Test + void shouldUseNamespacePrefixMapper() { + var props = configuration.createMarshallerProperties(); + + assertThat(props).containsEntry(ExportConfiguration.PROPERTY_NAMESPACE_PREFIX_MAPPER, prefixMapper); + } + } + + @Nested + class TestMarshaller { + + private final Map<String, Object> marshallerProps = Map.of(); + + @BeforeEach + void init() { + doReturn(marshallerProps).when(configuration).createMarshallerProperties(); + } + + @Test + void shouldSetContextPath() { + var marshaller = configuration.marshaller(); + + assertThat(marshaller.getContextPath()).isEqualTo(ExportConfiguration.CONTEXT_PATH); + } + + @Test + void shouldCreateMarshallerProperties() { + configuration.marshaller(); + + verify(configuration).createMarshallerProperties(); + } + + @Test + void shouldReturnMarshaller() { + var marshaller = configuration.marshaller(); + + assertThat(marshaller).isNotNull().isInstanceOf(Jaxb2Marshaller.class); + } + } + +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/ExportDataTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/ExportDataTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..84f4c718b85e1b76c6fa69fa3103fbd0c62fbe51 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/ExportDataTestFactory.java @@ -0,0 +1,25 @@ +package de.ozgcloud.alfa.export; + +import java.util.Set; + +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.file.OzgFileTestFactory; +import de.xoev.xdomea.AbgabeAbgabe0401; + +class ExportDataTestFactory { + + public static final String EXPORT_FILENAME = "file.zip"; + public static final OzgFile OZG_FILE = OzgFileTestFactory.create(); + public static final AbgabeAbgabe0401 ABGABE = AbgabeAbgabe0401TestFactory.create(); + + public static ExportData create() { + return createBuilder().build(); + } + + public static ExportData.ExportDataBuilder createBuilder() { + return ExportData.builder() + .exportFilename(EXPORT_FILENAME) + .abgabe(ABGABE) + .exportFiles(Set.of(OZG_FILE)); + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/ExportFilenameGeneratorTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/ExportFilenameGeneratorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0cf25b49436886e9478b67c4e204ff824c9abed9 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/ExportFilenameGeneratorTest.java @@ -0,0 +1,59 @@ +package de.ozgcloud.alfa.export; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; + +import de.ozgcloud.alfa.common.ExportFilenameGenerator; +import de.ozgcloud.alfa.common.AlfaTestUtils; +import de.ozgcloud.alfa.common.UUIDConverter; +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.file.OzgFileTestFactory; + +class ExportFilenameGeneratorTest { + + private MockedStatic<UUIDConverter> uuidConverter; + + @Nested + class TestGenerateExportFilename { + + private static final String UUID = "64a820d3-6285-172a-c028-0000000026d0"; + + private final OzgFile ozgFile = OzgFileTestFactory.create(); + + @BeforeEach + void init() { + uuidConverter = mockStatic(UUIDConverter.class); + uuidConverter.when(() -> UUIDConverter.fromObjectId(ozgFile.getId().toString())).thenReturn(UUID); + } + + @AfterEach + void cleanup() { + uuidConverter.close(); + } + + @Test + void shouldConvertObjectId() { + callGenerator(); + + uuidConverter.verify(() -> UUIDConverter.fromObjectId(ozgFile.getId().toString())); + } + + @Test + void shouldGenerate() { + var filename = callGenerator(); + + assertThat(filename).matches(String.format("^%s_%s$", AlfaTestUtils.UUID_REGEX, ozgFile.getName())); + } + + private String callGenerator() { + return ExportFilenameGenerator.generateExportFilename(ozgFile); + } + } + +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/ExportServiceITCase.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/ExportServiceITCase.java new file mode 100644 index 0000000000000000000000000000000000000000..a55f463cb200af363bfef7d3a08e39c15066b0d2 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/ExportServiceITCase.java @@ -0,0 +1,87 @@ +package de.ozgcloud.alfa.export; + +import static de.ozgcloud.alfa.common.AlfaTestUtils.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.io.ByteArrayOutputStream; +import java.util.UUID; +import java.util.stream.Stream; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.mock.mockito.SpyBean; + +import de.ozgcloud.alfa.bescheid.BescheidExportDataTestFactory; +import de.ozgcloud.alfa.bescheid.ExportBescheidService; +import de.ozgcloud.alfa.common.binaryfile.BinaryFileService; +import de.ozgcloud.alfa.common.file.OzgFileTestFactory; +import de.ozgcloud.alfa.common.user.UserProfileTestFactory; +import de.ozgcloud.alfa.common.user.UserService; +import de.ozgcloud.alfa.file.ExportFileService; +import de.ozgcloud.alfa.historie.ExportHistorieService; +import de.ozgcloud.alfa.kommentar.ExportKommentarService; +import de.ozgcloud.alfa.kommentar.KommentarsExportDataTestFactory; +import de.ozgcloud.alfa.postfach.ExportNachrichtService; +import de.ozgcloud.alfa.postfach.PostfachMail; +import de.ozgcloud.alfa.postfach.PostfachMailExportDataTestFactory; +import de.ozgcloud.alfa.postfach.PostfachMailTestFactory; +import de.ozgcloud.alfa.vorgang.ExportVorgangService; +import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; +import de.ozgcloud.alfa.vorgang.VorgangWithEingang; +import de.ozgcloud.alfa.vorgang.VorgangWithEingangTestFactory; +import de.ozgcloud.common.test.ITCase; + +@ITCase +class ExportServiceITCase { + + @SpyBean + private ExportFileService exportFileService; + @SpyBean + private ExportVorgangService exportVorgangService; + @MockBean + private ExportHistorieService exportHistorieService; + @MockBean + private ExportKommentarService exportKommentarService; + @MockBean + private BinaryFileService binaryFileService; + @MockBean + private ExportNachrichtService exportNachrichtService; + @MockBean + private ExportBescheidService exportBescheidService; + @MockBean + private UserService userService; + @Autowired + private ExportService exportService; + + @Nested + class TestWriteExport { + + private final VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); + private final PostfachMail postfachMail = PostfachMailTestFactory.createBuilder().id(createMongoDbObjectId()).build(); + + @BeforeEach + void setup() { + doReturn(vorgang).when(exportVorgangService).getVorgang(VorgangHeaderTestFactory.ID); + doReturn(Stream.of(OzgFileTestFactory.createWithUniqueId())).when(exportFileService).getRepresentations(vorgang); + doReturn(Stream.of(OzgFileTestFactory.createWithUniqueId())).when(exportFileService).getAttachments(vorgang); + doReturn(Stream.of(OzgFileTestFactory.createWithUniqueId())).when(binaryFileService).getFiles(postfachMail.getAttachments()); + doReturn(UserProfileTestFactory.create()).when(userService).getById(UserProfileTestFactory.ID); + doNothing().when(exportFileService).writeOzgFile(any(), any()); + when(exportHistorieService.createHistorienProtokollInformationTypes(vorgang)).thenReturn(Stream.empty()); + when(exportKommentarService.createExportData(vorgang)).thenReturn(KommentarsExportDataTestFactory.create()); + when(exportNachrichtService.createExportData(vorgang)).thenReturn(PostfachMailExportDataTestFactory.create()); + when(exportBescheidService.createExportData(vorgang)).thenReturn(BescheidExportDataTestFactory.create()); + } + + @Test + void shouldNotThrowException() { + assertDoesNotThrow( + () -> exportService.writeExport(VorgangHeaderTestFactory.ID, UUID.randomUUID().toString(), new ByteArrayOutputStream())); + } + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/ExportServiceTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/ExportServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..35bc4766a34a31b28701ce62ee9ec29a4033bf53 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/ExportServiceTest.java @@ -0,0 +1,642 @@ +package de.ozgcloud.alfa.export; + +import static de.ozgcloud.alfa.common.AlfaTestUtils.*; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.UUID; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Spy; + +import de.ozgcloud.alfa.bescheid.BescheidExportData; +import de.ozgcloud.alfa.bescheid.BescheidExportDataTestFactory; +import de.ozgcloud.alfa.bescheid.ExportBescheidService; +import de.ozgcloud.alfa.common.ExportFilenameGenerator; +import de.ozgcloud.alfa.common.HistorienProtokollInformationTypeTestFactory; +import de.ozgcloud.alfa.common.AlfaTestUtils; +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.file.OzgFileTestFactory; +import de.ozgcloud.alfa.file.ExportFileService; +import de.ozgcloud.alfa.historie.ExportHistorieService; +import de.ozgcloud.alfa.kommentar.ExportKommentarService; +import de.ozgcloud.alfa.kommentar.KommentarsExportData; +import de.ozgcloud.alfa.kommentar.KommentarsExportDataTestFactory; +import de.ozgcloud.alfa.postfach.ExportNachrichtService; +import de.ozgcloud.alfa.postfach.PostfachMailExportData; +import de.ozgcloud.alfa.postfach.PostfachMailExportDataTestFactory; +import de.ozgcloud.alfa.vorgang.EingangHeaderTestFactory; +import de.ozgcloud.alfa.vorgang.EingangTestFactory; +import de.ozgcloud.alfa.vorgang.ExportVorgangService; +import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; +import de.ozgcloud.alfa.vorgang.VorgangTypeTestFactory; +import de.ozgcloud.alfa.vorgang.VorgangWithEingang; +import de.ozgcloud.alfa.vorgang.VorgangWithEingangTestFactory; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.xoev.xdomea.AbgabeAbgabe0401; +import de.xoev.xdomea.AkteType; +import de.xoev.xdomea.DokumentType; +import de.xoev.xdomea.HistorienProtokollInformationType; +import de.xoev.xdomea.NkAbgabeType; +import de.xoev.xdomea.VorgangType; +import lombok.SneakyThrows; + +class ExportServiceTest { + + @Spy + @InjectMocks + private ExportService service; + + @Mock + private XdomeaXmlMarshaller xdomeaXmlMarshaller; + + @Mock + private ExportFileService exportFileService; + @Mock + private ExportVorgangService exportVorgangService; + @Mock + private ExportHistorieService exportHistorieService; + @Mock + private ExportKommentarService exportKommentarService; + @Mock + private ExportNachrichtService exportNachrichtService; + @Mock + private ExportBescheidService exportBescheidService; + + @DisplayName("Write exportToXdomea") + @Nested + class TestWriteExport { + + private static final String FILENAME_ID = UUID.randomUUID().toString(); + private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + private final ExportData exportData = ExportDataTestFactory.create(); + + @Mock + private File zipFile; + + @BeforeEach + void setUp() { + doReturn(exportData).when(service).collectExportData(VorgangHeaderTestFactory.ID, FILENAME_ID); + doReturn(zipFile).when(service).createZipFile(exportData); + doNothing().when(service).writeZipFileContent(zipFile, outputStream); + } + + @Test + void shouldCollectExportData() { + callService(); + + verify(service).collectExportData(VorgangHeaderTestFactory.ID, FILENAME_ID); + } + + @Test + void shouldCreateZipFile() { + callService(); + + verify(service).createZipFile(exportData); + } + + @Test + void shouldWriteZipFileContentToOutputStream() { + callService(); + + verify(service).writeZipFileContent(zipFile, outputStream); + } + + private void callService() { + service.writeExport(VorgangHeaderTestFactory.ID, FILENAME_ID, outputStream); + } + } + + @Nested + class TestCollectExportData { + + private MockedStatic<XdomeaNachrichtBuilder> xdomeaNachrichtBuilderMockedStatic; + + private static final String FILENAME_ID = UUID.randomUUID().toString(); + private static final String FILE_NAME = "file.zip"; + private final VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); + private final VorgangType vorgangType = VorgangTypeTestFactory.create(); + private final NkAbgabeType kopfType = NkAbgabeTypeTestFactory.create(); + private final AbgabeAbgabe0401 abgabe = AbgabeAbgabe0401TestFactory.create(); + private final AkteType akteType = AkteTypeTestFactory.create(); + private final List<OzgFile> representations = List.of(OzgFileTestFactory.createWithUniqueId()); + private final List<OzgFile> attachments = List.of(OzgFileTestFactory.createWithUniqueId()); + private final List<DokumentType> representationsDokumentTypes = List.of(DokumentTypeTestFactory.create()); + private final List<DokumentType> attachmentsDokumentTypes = List.of(DokumentTypeTestFactory.create()); + private final List<HistorienProtokollInformationType> historienProtokollInformationTypes = List.of( + HistorienProtokollInformationTypeTestFactory.create()); + private final KommentarsExportData kommentarsExportData = KommentarsExportDataTestFactory.create(); + private final PostfachMailExportData postfachMailExportData = PostfachMailExportDataTestFactory.create(); + private final BescheidExportData bescheidExportData = BescheidExportDataTestFactory.create(); + + @Mock + private XdomeaNachrichtBuilder xdomeaNachrichtBuilder; + + @BeforeEach + void setUp() { + setUpVorgangService(); + setUpXdomeaNachrichtBuilder(); + setUpExportFileService(); + setUpExportHistorieService(); + setUpExportKommentarService(); + setUpExportNachrichtService(); + setUpExportBescheidService(); + + doReturn(FILE_NAME).when(service).buildXmlFilename(FILENAME_ID); + doReturn(EingangHeaderTestFactory.FORM_ENGINE_NAME).when(service).getFormEngineName(vorgang); + + } + + private void setUpVorgangService() { + when(exportVorgangService.getVorgang(VorgangHeaderTestFactory.ID)).thenReturn(vorgang); + when(exportVorgangService.createVorgangType(vorgang)).thenReturn(vorgangType); + when(exportVorgangService.createKopf(vorgang)).thenReturn(kopfType); + when(exportVorgangService.createAkteType(vorgang)).thenReturn(akteType); + } + + private void setUpXdomeaNachrichtBuilder() { + xdomeaNachrichtBuilderMockedStatic = mockStatic(XdomeaNachrichtBuilder.class); + when(xdomeaNachrichtBuilder.withKopf(kopfType)).thenReturn(xdomeaNachrichtBuilder); + when(xdomeaNachrichtBuilder.withVorgang(vorgangType)).thenReturn(xdomeaNachrichtBuilder); + when(xdomeaNachrichtBuilder.withAktenzeichen(akteType)).thenReturn(xdomeaNachrichtBuilder); + when(xdomeaNachrichtBuilder.withRepresentations(representationsDokumentTypes)).thenReturn(xdomeaNachrichtBuilder); + when(xdomeaNachrichtBuilder.withAttachments(attachmentsDokumentTypes)).thenReturn(xdomeaNachrichtBuilder); + when(xdomeaNachrichtBuilder.withHistorie(historienProtokollInformationTypes)).thenReturn(xdomeaNachrichtBuilder); + when(xdomeaNachrichtBuilder.withKommentare(kommentarsExportData.getDokumentTypes())).thenReturn(xdomeaNachrichtBuilder); + when(xdomeaNachrichtBuilder.withPostfachMails(postfachMailExportData.getDokumentTypes())).thenReturn(xdomeaNachrichtBuilder); + when(xdomeaNachrichtBuilder.withBescheids(bescheidExportData.getDokumentTypes())).thenReturn(xdomeaNachrichtBuilder); + xdomeaNachrichtBuilderMockedStatic.when(XdomeaNachrichtBuilder::builder).thenReturn(xdomeaNachrichtBuilder); + when(xdomeaNachrichtBuilder.build()).thenReturn(abgabe); + } + + private void setUpExportFileService() { + mockStreamToList(representations, stream -> when(exportFileService.getRepresentations(vorgang)).thenReturn(stream)); + mockStreamToList(attachments, stream -> when(exportFileService.getAttachments(vorgang)).thenReturn(stream)); + mockStreamToList(representationsDokumentTypes, + stream -> when(exportFileService.createDokumentTypes(representations, EingangHeaderTestFactory.FORM_ENGINE_NAME)) + .thenReturn(stream)); + mockStreamToList(attachmentsDokumentTypes, + stream -> when(exportFileService.createDokumentTypes(attachments, EingangHeaderTestFactory.FORM_ENGINE_NAME)).thenReturn(stream)); + } + + private void setUpExportHistorieService() { + mockStreamToList(historienProtokollInformationTypes, + stream -> when(exportHistorieService.createHistorienProtokollInformationTypes(vorgang)).thenReturn(stream)); + } + + private void setUpExportKommentarService() { + when(exportKommentarService.createExportData(vorgang)).thenReturn(kommentarsExportData); + } + + private void setUpExportNachrichtService() { + when(exportNachrichtService.createExportData(vorgang)).thenReturn(postfachMailExportData); + } + + private void setUpExportBescheidService() { + when(exportBescheidService.createExportData(vorgang)).thenReturn(bescheidExportData); + } + + @AfterEach + void tearDown() { + xdomeaNachrichtBuilderMockedStatic.close(); + } + + @Test + void shouldLoadVorgang() { + callService(); + + verify(exportVorgangService).getVorgang(VorgangHeaderTestFactory.ID); + } + + @Test + void shouldGenerateXmlFilename() { + callService(); + + verify(service).buildXmlFilename(FILENAME_ID); + } + + @Test + void shouldGetRepresentations() { + callService(); + + verify(exportFileService).getRepresentations(vorgang); + } + + @Test + void shouldGetAttachments() { + callService(); + + verify(exportFileService).getAttachments(vorgang); + } + + @Test + void shouldCreateKopf() { + callService(); + + verify(exportVorgangService).createKopf(vorgang); + } + + @Test + void shouldCreateVorgangType() { + callService(); + + verify(exportVorgangService).createVorgangType(vorgang); + } + + @Test + void shouldCreateRepresentationsDokumentTypes() { + callService(); + + verify(exportFileService).createDokumentTypes(representations, EingangHeaderTestFactory.FORM_ENGINE_NAME); + } + + @Test + void shouldCreateAttachmentsDokumentTypes() { + callService(); + + verify(exportFileService).createDokumentTypes(attachments, EingangHeaderTestFactory.FORM_ENGINE_NAME); + } + + @Test + void shouldCreatePostfachMailsExportData() { + callService(); + + verify(exportNachrichtService).createExportData(vorgang); + } + + @Test + void shouldCreateAkteType() { + callService(); + + verify(exportVorgangService).createAkteType(vorgang); + } + + @Test + void shouldSetKopf() { + callService(); + + verify(xdomeaNachrichtBuilder).withKopf(kopfType); + } + + @Test + void shouldSetVorgang() { + callService(); + + verify(xdomeaNachrichtBuilder).withVorgang(vorgangType); + } + + @Test + void shouldSetRepresentations() { + callService(); + + verify(xdomeaNachrichtBuilder).withRepresentations(representationsDokumentTypes); + } + + @Test + void shouldSetAttachments() { + callService(); + + verify(xdomeaNachrichtBuilder).withAttachments(attachmentsDokumentTypes); + } + + @Test + void shouldSetPostfachMails() { + callService(); + + verify(xdomeaNachrichtBuilder).withPostfachMails(postfachMailExportData.getDokumentTypes()); + } + + @Test + void shouldSetBescheids() { + callService(); + + verify(xdomeaNachrichtBuilder).withBescheids(bescheidExportData.getDokumentTypes()); + } + + @Test + void shouldSetAktenzeichen() { + callService(); + + verify(xdomeaNachrichtBuilder).withAktenzeichen(akteType); + } + + @Test + void shouldSetHistorie() { + callService(); + + verify(xdomeaNachrichtBuilder).withHistorie(historienProtokollInformationTypes); + } + + @Test + void shouldCreateAbgabe() { + callService(); + + verify(xdomeaNachrichtBuilder).build(); + } + + @Test + void shouldContainAbgabe() { + var exportData = callService(); + + assertThat(exportData.getAbgabe()).isEqualTo(abgabe); + } + + @Test + void shouldContainExportFilename() { + var exportData = callService(); + + assertThat(exportData.getExportFilename()).isEqualTo(FILE_NAME); + } + + @Test + void shouldContainExportFiles() { + var exportData = callService(); + + assertThat(exportData.getExportFiles()) + .hasSize(6) + .containsAll(representations) + .containsAll(attachments) + .containsAll(kommentarsExportData.getAttachments()) + .containsAll(postfachMailExportData.getAttachments()) + .containsAll(bescheidExportData.getFiles()); + } + + void shouldExportKommentare() { + callService(); + + verify(exportKommentarService).createExportData(vorgang); + } + + private ExportData callService() { + return service.collectExportData(VorgangHeaderTestFactory.ID, FILENAME_ID); + } + } + + @DisplayName("Build xml Filename") + @Nested + class TestBuildXmlFilename { + + @Test + void shouldMatchPattern() { + var filename = service.buildXmlFilename(UUID.randomUUID().toString()); + + assertThat(filename).matches(AlfaTestUtils.uuidRegexWithSuffix(ExportService.EXPORT_FILENAME_SUFFIX)); + } + } + + @DisplayName("Create xml content") + @Nested + class TestCreateXmlContent { + + private static final String XML_STRING = "<xml>"; + + @BeforeEach + void init() { + when(xdomeaXmlMarshaller.marshal(any())).thenReturn(XML_STRING); + } + + @Test + void shouldCallXmlMarshaller() { + callService(); + + verify(xdomeaXmlMarshaller).marshal(ExportDataTestFactory.ABGABE); + } + + @Test + void shouldReturnMarshalledString() { + var result = callService(); + + assertThat(result).isEqualTo(XML_STRING); + } + + private String callService() { + return service.createXmlContent(ExportDataTestFactory.ABGABE); + } + } + + @Nested + class TestCreateZipFile { + + private static final String XML_FILE_CONTENT = "<xml></xml>"; + private static final String XML_STRING = "<xml>"; + private final ExportData exportData = ExportDataTestFactory.create(); + + @Captor + private ArgumentCaptor<ZipOutputStream> zipOutputStreamArgumentCaptor; + + @SneakyThrows + @BeforeEach + void setUp() { + when(service.createXmlContent(ExportDataTestFactory.ABGABE)).thenReturn(XML_FILE_CONTENT); + doNothing().when(service).putOzgFileIntoZip(any(OzgFile.class), any(ZipOutputStream.class)); + } + + @Test + void shouldCreateXmlStringContent() { + callService(); + + verify(service).createXmlContent(ExportDataTestFactory.ABGABE); + } + + @Test + void shouldCreateZipEntry() throws IOException { + callService(); + + verify(service).putZipEntry(eq(ExportDataTestFactory.EXPORT_FILENAME), eq(XML_FILE_CONTENT), + any(ZipOutputStream.class)); + } + + @Test + void shouldCreateZipOutputStream() throws IOException { + callService(); + + verify(service).putZipEntry(eq(ExportDataTestFactory.EXPORT_FILENAME), eq(XML_FILE_CONTENT), + zipOutputStreamArgumentCaptor.capture()); + assertThat(zipOutputStreamArgumentCaptor.getValue()).isInstanceOf(ZipOutputStream.class); + } + + @Test + void shouldWriteBytes() { + var file = callService(); + + assertThat(file).isNotEmpty().content().hasSizeGreaterThan(100); + } + + @SneakyThrows + @Test + void shouldWritePdfFiles() { + callService(); + + verify(service).putOzgFileIntoZip(eq(ExportDataTestFactory.OZG_FILE), any(ZipOutputStream.class)); + } + + @Test + void shouldThrowTechnicalException() throws IOException { + doThrow(IOException.class).when(service).putZipEntry(anyString(), eq(XML_STRING), any(ZipOutputStream.class)); + + assertThatThrownBy(this::callService).isInstanceOf(TechnicalException.class); + } + + private File callService() { + return service.createZipFile(exportData); + } + + } + + @Nested + class TestPutZipEntry { + + @Mock + private ZipOutputStream zipOutputStream; + + @Captor + private ArgumentCaptor<ZipEntry> zipEntryArgumentCaptor; + + @Captor + private ArgumentCaptor<byte[]> fileDataArgumentCaptor; + + private final String FILE_NAME = "file.xml"; + private final String FILE_DATA = "xml content"; + + @SneakyThrows + @Test + void shouldPutNextEntry() { + callService(); + + verify(zipOutputStream).putNextEntry(zipEntryArgumentCaptor.capture()); + assertThat(zipEntryArgumentCaptor.getValue().getName()).isEqualTo(FILE_NAME); + } + + @SneakyThrows + @Test + void shouldWriteDataBytes() { + callService(); + + verify(zipOutputStream).write(fileDataArgumentCaptor.capture()); + assertThat(fileDataArgumentCaptor.getValue()).isEqualTo(FILE_DATA.getBytes(StandardCharsets.UTF_8)); + } + + @SneakyThrows + @Test + void shouldCloseEntry() { + callService(); + + verify(zipOutputStream).closeEntry(); + } + + @SneakyThrows + private void callService() { + service.putZipEntry(FILE_NAME, FILE_DATA, zipOutputStream); + } + } + + @Nested + class TestPutOzgFileIntoZip { + + private MockedStatic<ExportFilenameGenerator> exportFilenameGenerator; + + @Mock + private ZipOutputStream zipOutputStream; + + @Captor + private ArgumentCaptor<ZipEntry> zipEntryArgumentCaptor; + + private final OzgFile ozgFile = OzgFileTestFactory.create(); + + @BeforeEach + void setUp() { + exportFilenameGenerator = mockStatic(ExportFilenameGenerator.class); + exportFilenameGenerator.when(() -> ExportFilenameGenerator.generateExportFilename(ozgFile)).thenReturn(OzgFileTestFactory.NAME); + } + + @AfterEach + void cleanUp() { + exportFilenameGenerator.close(); + } + + @Test + void shouldGenerateExportFilename() { + callService(); + + exportFilenameGenerator.verify(() -> ExportFilenameGenerator.generateExportFilename(ozgFile)); + } + + @SneakyThrows + @Test + void shouldPutNextEntry() { + callService(); + + verify(zipOutputStream).putNextEntry(zipEntryArgumentCaptor.capture()); + assertThat(zipEntryArgumentCaptor.getValue().getName()).isEqualTo(OzgFileTestFactory.NAME); + } + + @Test + void shouldCallExportFileService() { + callService(); + + verify(exportFileService).writeOzgFile(OzgFileTestFactory.ID, zipOutputStream); + } + + @SneakyThrows + @Test + void shouldCloseEntry() { + callService(); + + verify(zipOutputStream).closeEntry(); + } + + @SneakyThrows + private void callService() { + service.putOzgFileIntoZip(ozgFile, zipOutputStream); + } + + } + + @Nested + class TestGetFormEngineName { + + @Test + void shouldReturnEmptyStringOnNullEingang() { + var vorgang = VorgangWithEingangTestFactory.createBuilder().eingang(null).build(); + + var formEngineName = service.getFormEngineName(vorgang); + + assertThat(formEngineName).isEmpty(); + } + + @Test + void shouldReturnEmptyStringOnNullEingangHeader() { + var vorgang = VorgangWithEingangTestFactory.createBuilder().eingang(EingangTestFactory.createBuilder().header(null).build()).build(); + + var formEngineName = service.getFormEngineName(vorgang); + + assertThat(formEngineName).isEmpty(); + } + + @Test + void shouldReturnFormEngineName() { + VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); + + var formEngineName = service.getFormEngineName(vorgang); + + assertThat(formEngineName).isEqualTo(EingangHeaderTestFactory.FORM_ENGINE_NAME); + } + } +} \ No newline at end of file diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/export/ExportVorgangControllerTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/ExportVorgangControllerTest.java similarity index 55% rename from alfa-service/src/test/java/de/ozgcloud/alfa/export/ExportVorgangControllerTest.java rename to alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/ExportVorgangControllerTest.java index 57f0063280880e67b654368c8c68f081d7dd5a3f..e83d251ba893e0efd9df548cdbe29846ebd4240c 100644 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/export/ExportVorgangControllerTest.java +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/ExportVorgangControllerTest.java @@ -1,15 +1,17 @@ package de.ozgcloud.alfa.export; +import static org.assertj.core.api.AssertionsForClassTypes.*; import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; -import java.io.OutputStream; import java.util.UUID; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; @@ -19,6 +21,7 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import de.ozgcloud.alfa.common.AlfaTestUtils; import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; class ExportVorgangControllerTest { @@ -26,8 +29,9 @@ class ExportVorgangControllerTest { @Spy @InjectMocks private ExportVorgangController controller; + @Mock - private ExportRemoteService exportRemoteService; + private ExportService xDomeaService; private MockMvc mockMvc; @@ -37,42 +41,50 @@ class ExportVorgangControllerTest { } @Nested - class TestExportVorgang { - - public static final String VORGANG_ID = VorgangHeaderTestFactory.ID; - public static final String EXPORTED_VORGANG_FILENAME = UUID.randomUUID().toString(); + class TestBuildZipFilename { - @Mock - private ExportedVorgangFile exportedVorgangFile; + @Test + void shouldMatchPattern() { + var filename = controller.buildZipFilename(UUID.randomUUID().toString()); - @BeforeEach - void init() { - when(exportedVorgangFile.getFileName()).thenReturn(EXPORTED_VORGANG_FILENAME); - when(exportRemoteService.exportVorgang(VORGANG_ID)).thenReturn(exportedVorgangFile); + assertThat(filename).matches(AlfaTestUtils.uuidRegexWithSuffix("_Abgabe.Abgabe.0401.xdomea")); } + } - @Test - void shouldExportVorgang() throws Exception { - doRequest(); + @Nested + class TestExportToXdomea { - verify(exportRemoteService).exportVorgang(VORGANG_ID); + private static final String VORGANG_EXPORT_FILENAME = "00000000-0000-0000-0000-000000000000_Abgabe.Abgabe.0401.xml"; + + @Captor + private ArgumentCaptor<String> filenameIdArgumentCaptor; + + @BeforeEach + void init() { + doReturn(VORGANG_EXPORT_FILENAME).when(controller).buildZipFilename(anyString()); } @Test void shouldHaveContentDispositonHeader() throws Exception { - doRequest().andExpect(header().string(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + EXPORTED_VORGANG_FILENAME)); + doRequest().andExpect(header().string(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + VORGANG_EXPORT_FILENAME)); } @Test - void shouldHaveContentTypeHeader() throws Exception { - doRequest().andExpect(header().string(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM.toString())); + void shouldCallXdomeaService() throws Exception { + doRequest(); + + verify(xDomeaService).writeExport(eq(VorgangHeaderTestFactory.ID), filenameIdArgumentCaptor.capture(), any()); + assertThat(filenameIdArgumentCaptor.getValue()).matches(AlfaTestUtils.UUID_REGEX); } @Test - void shouldWriteFileToOutputStream() throws Exception { + void shouldUseUUIDAsFilenameId() throws Exception { doRequest(); - verify(exportedVorgangFile).writeToOutputStream(any(OutputStream.class)); + verify(controller).buildZipFilename(filenameIdArgumentCaptor.capture()); + + assertThat(filenameIdArgumentCaptor.getValue()).matches(AlfaTestUtils.UUID_REGEX); + } private ResultActions doRequest() throws Exception { diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/export/ExportVorgangProcessorTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/ExportVorgangProcessorTest.java similarity index 100% rename from alfa-service/src/test/java/de/ozgcloud/alfa/export/ExportVorgangProcessorTest.java rename to alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/ExportVorgangProcessorTest.java diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/IdentifikationObjektTypeTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/IdentifikationObjektTypeTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..9946765cf3e8bb56674da6ed13f4d089b7f3c084 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/IdentifikationObjektTypeTestFactory.java @@ -0,0 +1,16 @@ +package de.ozgcloud.alfa.export; + +import java.util.UUID; + +import de.xoev.xdomea.IdentifikationObjektType; + +public class IdentifikationObjektTypeTestFactory { + + public static final String ID = UUID.randomUUID().toString(); + + public static IdentifikationObjektType create() { + var identifikationObjektType = new IdentifikationObjektType(); + identifikationObjektType.setID(ID); + return identifikationObjektType; + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/NamespacePrefixMapperTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/NamespacePrefixMapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..1261762b14a1ae7278b4489016faef0187f53374 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/NamespacePrefixMapperTest.java @@ -0,0 +1,72 @@ +package de.ozgcloud.alfa.export; + +import static org.assertj.core.api.Assertions.*; + +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +class NamespacePrefixMapperTest { + + private XdomeaNamespacePrefixMapper prefixMapper = new XdomeaNamespacePrefixMapper(); + + @DisplayName("Get preferred prefix") + @Nested + class TestGetPreferredPrefix { + + @Test + void shouldReturnXdomeaPrefix() { + var prefix = prefixMapper.getPreferredPrefix(XdomeaNamespacePrefixMapper.XDOMEA_NAMESPACE_URI, StringUtils.EMPTY, false); + + assertThat(prefix).isEqualTo(XdomeaNamespacePrefixMapper.XDOMEA_NAMESPACE_PREFIX); + } + + @Test + void shouldReturnSuggestion() { + var prefix = prefixMapper.getPreferredPrefix("not existing", "suggestion", false); + + assertThat(prefix).isEqualTo("suggestion"); + } + } + + @DisplayName("Get pre decrlared namespace uris") + @Nested + class TestGetPreDeclaredNamespaceUris { + + @Test + void shouldHaveSize() { + var uris = prefixMapper.getPreDeclaredNamespaceUris(); + + assertThat(uris).hasSize(4); + } + + @Test + void shouldContainsDinspec() { + var uris = prefixMapper.getPreDeclaredNamespaceUris(); + + assertThat(uris).contains(XdomeaNamespacePrefixMapper.XDOMEA_NAMESPACE_DINSPEC_URI); + } + + @Test + void shouldContainsGml() { + var uris = prefixMapper.getPreDeclaredNamespaceUris(); + + assertThat(uris).contains(XdomeaNamespacePrefixMapper.XDOMEA_NAMESPACE_GML_URI); + } + + @Test + void shouldContainsXoevCode() { + var uris = prefixMapper.getPreDeclaredNamespaceUris(); + + assertThat(uris).contains(XdomeaNamespacePrefixMapper.XDOMEA_NAMESPACE_XOEV_CODE_URI); + } + + @Test + void shouldContainsXoevLx() { + var uris = prefixMapper.getPreDeclaredNamespaceUris(); + + assertThat(uris).contains(XdomeaNamespacePrefixMapper.XDOMEA_NAMESPACE_XOEV_LC_URI); + } + } +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/NkAbgabeTypeTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/NkAbgabeTypeTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..e93a73419cc57dd0da460c220fe2e5fcaa7d3fa9 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/NkAbgabeTypeTestFactory.java @@ -0,0 +1,11 @@ +package de.ozgcloud.alfa.export; + +import de.xoev.xdomea.NkAbgabeType; + +public class NkAbgabeTypeTestFactory { + + public static NkAbgabeType create() { + return new NkAbgabeType(); + } + +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/UUIDConverterTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/UUIDConverterTest.java new file mode 100644 index 0000000000000000000000000000000000000000..2af0c16013bf75ec4f81c938aad8092afc884083 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/UUIDConverterTest.java @@ -0,0 +1,29 @@ +package de.ozgcloud.alfa.export; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import de.ozgcloud.alfa.common.AlfaTestUtils; +import de.ozgcloud.alfa.common.UUIDConverter; + +class UUIDConverterTest { + + @Nested + class TestFromObjectId { + + @Test + void shouldReturnUUID() { + var result = UUIDConverter.fromObjectId("64a820d36285172ac02826d0"); + + assertThat(result).isEqualTo("64a820d3-6285-172a-c028-0000000026d0").matches(AlfaTestUtils.UUID_REGEX); + } + + @Test + void shouldThrowIllegalArgumentException() { + assertThatThrownBy(() -> UUIDConverter.fromObjectId("abc")).isInstanceOf(IllegalArgumentException.class); + } + } + +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/XdomeaNachrichtBuilderTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/XdomeaNachrichtBuilderTest.java new file mode 100644 index 0000000000000000000000000000000000000000..c524f4f7c82761a842f02be8f42dde2b2159af53 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/XdomeaNachrichtBuilderTest.java @@ -0,0 +1,167 @@ +package de.ozgcloud.alfa.export; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.Spy; + +import de.ozgcloud.alfa.common.HistorienProtokollInformationTypeTestFactory; +import de.ozgcloud.alfa.vorgang.VorgangTypeTestFactory; +import de.xoev.xdomea.AbgabeAbgabe0401; +import de.xoev.xdomea.AkteType; +import de.xoev.xdomea.DokumentType; +import de.xoev.xdomea.HistorienProtokollInformationType; +import de.xoev.xdomea.NkAbgabeType; +import de.xoev.xdomea.VorgangType; + +class XdomeaNachrichtBuilderTest { + + private final VorgangType vorgangType = VorgangTypeTestFactory.create(); + @Spy + private final XdomeaNachrichtBuilder builder = XdomeaNachrichtBuilder.builder().withVorgang(vorgangType); + + @Nested + class TestBuild { + private final AbgabeAbgabe0401 expectedAbgabe = AbgabeAbgabe0401TestFactory.create(); + + @BeforeEach + void setUpMock() { + doReturn(expectedAbgabe).when(builder).createAbgabeType(); + } + + @Test + void shouldCallAddVorgangDokumente() { + builder.build(); + + verify(builder).addVorgangDokumente(); + } + + @Test + void shouldCallAddVorgangChangeHistory() { + builder.build(); + + verify(builder).addVorgangChangeHistory(); + } + + @Test + void shouldCallCreateAbgabeType() { + builder.build(); + + verify(builder).createAbgabeType(); + } + + @Test + void shouldReturnAbgabeType() { + var abgabeType = builder.build(); + + assertThat(abgabeType).isEqualTo(expectedAbgabe); + } + } + + @Nested + class TestCreateAbgabeType { + private final NkAbgabeType kopfType = NkAbgabeTypeTestFactory.create(); + private final AkteType akte = AkteTypeTestFactory.create(); + + @Test + void shouldHaveKopf() { + var abgabeType = builder.withKopf(kopfType).createAbgabeType(); + + assertThat(abgabeType.getKopf()).isEqualTo(kopfType); + } + + @Test + void shoulAddTwoSchriftgutobjekt() { + var abgabeType = builder.withAktenzeichen(akte).createAbgabeType(); + + assertThat(abgabeType.getSchriftgutobjekt()).size().isEqualTo(2); + } + + @Test + void shouldHaveVorgangSchriftgutObjekt() { + var abgabeType = builder.createAbgabeType(); + + assertThat(abgabeType.getSchriftgutobjekt().get(0).getVorgang()).isEqualTo(vorgangType); + } + + @Test + void shouldHaveAkteSchriftgutObjekt() { + var abgabeType = builder.withAktenzeichen(akte).createAbgabeType(); + + assertThat(abgabeType.getSchriftgutobjekt().get(1).getAkte()).isEqualTo(akte); + } + + } + + @Nested + class TestAddVorgangDokumente { + private final List<DokumentType> representations = List.of(DokumentTypeTestFactory.create(), DokumentTypeTestFactory.create()); + private final List<DokumentType> attachments = List.of(DokumentTypeTestFactory.create(), DokumentTypeTestFactory.create()); + private final List<DokumentType> kommentare = List.of(DokumentTypeTestFactory.create(), DokumentTypeTestFactory.create()); + private final List<DokumentType> postfachMails = List.of(DokumentTypeTestFactory.create(), DokumentTypeTestFactory.create()); + private final List<DokumentType> bescheids = List.of(DokumentTypeTestFactory.create(), DokumentTypeTestFactory.create()); + + @Test + void shouldAddRepresentations() { + builder.withRepresentations(representations).addVorgangDokumente(); + + assertThat(vorgangType.getDokument()).isEqualTo(representations); + } + + @Test + void shouldAddAttachments() { + builder.withAttachments(attachments).addVorgangDokumente(); + + assertThat(vorgangType.getDokument()).isEqualTo(attachments); + } + + @Test + void shouldAddKommentare() { + builder.withKommentare(kommentare).addVorgangDokumente(); + + assertThat(vorgangType.getDokument()).isEqualTo(kommentare); + } + + @Test + void shouldAddPostfachMails() { + builder.withPostfachMails(postfachMails).addVorgangDokumente(); + + assertThat(vorgangType.getDokument()).isEqualTo(postfachMails); + } + + @Test + void shouldAddBescheids() { + builder.withBescheids(bescheids).addVorgangDokumente(); + + assertThat(vorgangType.getDokument()).isEqualTo(bescheids); + } + + } + + @Nested + class TestAddVorgangChangeHistory { + + private final List<HistorienProtokollInformationType> historie = List.of(HistorienProtokollInformationTypeTestFactory.create(), + HistorienProtokollInformationTypeTestFactory.create()); + + @Test + void shouldAddHistorie() { + builder.withHistorie(historie).addVorgangChangeHistory(); + + assertThat(vorgangType.getHistorienProtokollInformation()).isEqualTo(historie); + } + + @Test + void shouldNotAddHistorie() { + builder.addVorgangChangeHistory(); + + assertThat(vorgangType.getHistorienProtokollInformation()).isEmpty(); + } + } + +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/XdomeaPropertiesTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/XdomeaPropertiesTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..78d786011aeedec05d51b6407305c2fb3769a626 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/XdomeaPropertiesTestFactory.java @@ -0,0 +1,23 @@ +package de.ozgcloud.alfa.export; + +import com.thedeanda.lorem.LoremIpsum; + +import de.ozgcloud.alfa.export.XdomeaProperties.XdomeaPropertiesBuilder; + +public class XdomeaPropertiesTestFactory { + + public static final String BEHOERDENSCHLUESSEL = LoremIpsum.getInstance().getWords(1); + public static final String BEHOERDENSCHLUESSEL_URI = LoremIpsum.getInstance().getUrl(); + public static final String BEHOERDENSCHLUESSEL_VERSION = LoremIpsum.getInstance().getWords(1); + + public static XdomeaProperties create() { + return createBuilder().build(); + } + + public static XdomeaPropertiesBuilder createBuilder() { + return new XdomeaPropertiesBuilder() + .behoerdenschluessel(BEHOERDENSCHLUESSEL) + .behoerdenschluesselUri(BEHOERDENSCHLUESSEL_URI) + .behoerdenschluesselVersion(BEHOERDENSCHLUESSEL_VERSION); + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/XdomeaPropertiesValidatorITCase.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/XdomeaPropertiesValidatorITCase.java new file mode 100644 index 0000000000000000000000000000000000000000..451d2c7c49059af03d5e26034ad45f7bc6929998 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/XdomeaPropertiesValidatorITCase.java @@ -0,0 +1,17 @@ +package de.ozgcloud.alfa.export; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Test; +import org.springframework.context.ApplicationContext; + +import de.ozgcloud.common.test.ITCase; + +@ITCase +class XdomeaPropertiesValidatorITCase { + + @Test + void shouldExistInApplicationContext(ApplicationContext context) { + assertThat(context.getBean("configurationPropertiesValidator")).isNotNull().isInstanceOf(XdomeaPropertiesValidator.class); + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/XdomeaPropertiesValidatorTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/XdomeaPropertiesValidatorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..cd6cf19672ab8118254ded34a4b2444d921f8f55 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/XdomeaPropertiesValidatorTest.java @@ -0,0 +1,138 @@ +package de.ozgcloud.alfa.export; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; +import org.mockito.Spy; +import org.springframework.validation.Errors; + +class XdomeaPropertiesValidatorTest { + + @Spy + private XdomeaPropertiesValidator validator; + + @Nested + class TestSupports { + + @Test + void shouldSupportXdomeaProperties() { + var supports = validator.supports(XdomeaProperties.class); + + assertThat(supports).isTrue(); + } + } + + @Nested + class TestValidate { + + @Test + void shouldBeValidIfAllBehoerdenschluesselPropertiesAreSet() { + var properties = XdomeaPropertiesTestFactory.create(); + + var errors = validate(properties); + + assertThat(errors.hasErrors()).isFalse(); + } + + @ParameterizedTest + @NullAndEmptySource + void shouldBeValidIfBehoerdenschluesselIsNotSet(String behoerdenschluessel) { + var properties = XdomeaPropertiesTestFactory.createBuilder().behoerdenschluessel(behoerdenschluessel).build(); + + var errors = validate(properties); + + assertThat(errors.hasErrors()).isFalse(); + } + + @Nested + class OnUriNotSet { + + private static final String PROPERTY_NAME = "behoerdenschluesselUri"; + public static final String PROPERTY_PATH = "ozgcloud.xdomea." + PROPERTY_NAME; + public static final String ERROR_CODE = PROPERTY_PATH + ".empty"; + + @ParameterizedTest + @NullAndEmptySource + void shouldHaveFieldErrors(String uri) { + var properties = withBehoerdenschluesselUri(uri); + + var errors = validate(properties); + + assertThat(errors.hasFieldErrors(PROPERTY_NAME)).isTrue(); + } + + @ParameterizedTest + @NullAndEmptySource + void shouldHaveMeaningfulErrorMessage(String uri) { + var properties = withBehoerdenschluesselUri(uri); + + var errors = validate(properties); + + assertThat(errors.getFieldError(PROPERTY_NAME).getDefaultMessage()).contains(PROPERTY_NAME); + } + + @ParameterizedTest + @NullAndEmptySource + void shouldHaveErrorCode(String uri) { + var properties = withBehoerdenschluesselUri(uri); + + var errors = validate(properties); + + assertThat(errors.getFieldError(PROPERTY_NAME).getCode()).isEqualTo(ERROR_CODE); + } + + private XdomeaProperties withBehoerdenschluesselUri(String uri) { + return XdomeaPropertiesTestFactory.createBuilder().behoerdenschluesselUri(uri).build(); + } + } + + @Nested + class OnVersionNotSet { + + public static final String PROPERTY_NAME = "behoerdenschluesselVersion"; + public static final String PROPERTY_PATH = "ozgcloud.xdomea." + PROPERTY_NAME; + public static final String ERROR_CODE = PROPERTY_PATH + ".empty"; + + @ParameterizedTest + @NullAndEmptySource + void shouldHaveFieldErrors(String version) { + var properties = withBehoerdenschluesselVersion(version); + + var errors = validate(properties); + + assertThat(errors.hasFieldErrors(PROPERTY_NAME)).isTrue(); + } + + @ParameterizedTest + @NullAndEmptySource + void shouldHaveMeaningfulErrorMessage(String version) { + var properties = withBehoerdenschluesselVersion(version); + + var errors = validate(properties); + + assertThat(errors.getFieldError(PROPERTY_NAME).getDefaultMessage()).contains(PROPERTY_NAME); + } + + @ParameterizedTest + @NullAndEmptySource + void shouldHaveErrorCode(String version) { + var properties = withBehoerdenschluesselVersion(version); + + var errors = validate(properties); + + assertThat(errors.getFieldError(PROPERTY_NAME).getCode()).isEqualTo(ERROR_CODE); + } + + private XdomeaProperties withBehoerdenschluesselVersion(String version) { + return XdomeaPropertiesTestFactory.createBuilder().behoerdenschluesselVersion(version).build(); + } + } + + private Errors validate(XdomeaProperties properties) { + return validator.validateObject(properties); + } + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/XmlMarshallerTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/XmlMarshallerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..47e3c97c8f8bb27670b5bcde0b25a82700cb1148 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/export/XmlMarshallerTest.java @@ -0,0 +1,47 @@ +package de.ozgcloud.alfa.export; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.io.StringWriter; + +import javax.xml.transform.stream.StreamResult; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.springframework.oxm.jaxb.Jaxb2Marshaller; + +import de.xoev.xdomea.AbgabeAbgabe0401; + +class XmlMarshallerTest { + + @Spy + @InjectMocks + private XdomeaXmlMarshaller xdomeaXmlMarshaller; + + @Mock + private Jaxb2Marshaller marshaller; + + @Nested + class TestMarshal { + + private final AbgabeAbgabe0401 abgabe = AbgabeAbgabe0401TestFactory.create(); + + @Captor + private ArgumentCaptor<StreamResult> streamResultArgumentCaptor; + + @Test + void shouldMarshal() { + xdomeaXmlMarshaller.marshal(abgabe); + + verify(marshaller).marshal(eq(abgabe), streamResultArgumentCaptor.capture()); + assertThat(streamResultArgumentCaptor.getValue().getWriter()).isInstanceOf(StringWriter.class); + } + } +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/file/DokumentTypeBuilderITCase.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/file/DokumentTypeBuilderITCase.java new file mode 100644 index 0000000000000000000000000000000000000000..60c0a2996f22512a3a9b740b65ecd22dc4c16d9d --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/file/DokumentTypeBuilderITCase.java @@ -0,0 +1,189 @@ +package de.ozgcloud.alfa.file; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Random; + +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; + +import de.ozgcloud.alfa.common.UUIDConverter; +import de.ozgcloud.alfa.common.VersionTypeBuilder; +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.file.OzgFileTestFactory; +import de.xoev.xdomea.AllgemeineMetadatenType; +import de.xoev.xdomea.DateiformatCodeType; +import de.xoev.xdomea.FormatType; +import de.xoev.xdomea.IdentifikationObjektType; +import de.xoev.xdomea.PrimaerdokumentType; +import de.xoev.xdomea.VersionType; + +class DokumentTypeBuilderITCase { + + private static final Long DOKUMENT_ORDINAL_NUMBER = new Random().nextLong(); + private static final String FORM_ENGINE_NAME = "DUMMY_NAME"; + private final OzgFile ozgFile = OzgFileTestFactory.createBuilder().contentType("application/pdf").build(); + + private final DokumentTypeBuilder builder = DokumentTypeBuilder.builder() + .withOzgFile(ozgFile) + .withFormEngineName(FORM_ENGINE_NAME) + .withOrdinalNumber(DOKUMENT_ORDINAL_NUMBER); + + private MockedStatic<UUIDConverter> uuidConverter; + + @BeforeEach + void init() { + uuidConverter = mockStatic(UUIDConverter.class); + } + + @AfterEach + void cleanup() { + uuidConverter.close(); + } + + @Nested + class TestBuild { + + private final String FILE_UUID = "64a820d3-6285-172a-c028-0000000026d0"; + + @BeforeEach + void init() { + uuidConverter.when(() -> UUIDConverter.fromObjectId(OzgFileTestFactory.ID.toString())).thenReturn(FILE_UUID); + } + + @Test + void shouldHaveIdentifikation() { + var identifikationObjekt = new IdentifikationObjektType(); + identifikationObjekt.setID(FILE_UUID); + identifikationObjekt.setNummerImUebergeordnetenContainer(DOKUMENT_ORDINAL_NUMBER); + var dokument = builder.build(); + + assertThat(dokument.getIdentifikation()).usingRecursiveComparison().isEqualTo(identifikationObjekt); + } + + @Nested + class TestAllgemeineMetadaten { + @Test + void shouldHaveBetreff() { + var allgemeineMetadaten = createAllgemeineMetadaten(); + + assertThat(allgemeineMetadaten.getBetreff()).isEqualTo(OzgFileTestFactory.NAME); + } + + @Test + void shouldHaveEmptyKennzeichen() { + var allgemeineMetadaten = createAllgemeineMetadaten(); + + assertThat(allgemeineMetadaten.getKennzeichen()).isEmpty(); + } + + @Test + void shouldHaveEmptyBemerkung() { + var allgemeineMetadaten = createAllgemeineMetadaten(); + + assertThat(allgemeineMetadaten.getBemerkung()).isEmpty(); + } + + @Test + void shouldHaveMedium() { + var allgemeineMetadaten = createAllgemeineMetadaten(); + + assertThat(allgemeineMetadaten.getMedium().getCode()).isEqualTo(DokumentTypeBuilder.ALLGEMEINE_METADATEN_MEDIUM_CODE); + } + + private AllgemeineMetadatenType createAllgemeineMetadaten() { + return builder.build().getAllgemeineMetadaten(); + } + } + + @Nested + class TestVersion { + + @Test + void shouldHaveNummer() { + var versionType = createVersion(); + + assertThat(versionType.getNummer()).isEqualTo(DokumentTypeBuilder.VERSION_NUMMER); + } + + private VersionType createVersion() { + return builder.build().getVersion().getFirst(); + } + + @Nested + class TestFormat { + @Test + void shouldHaveName() { + var expectedDateiformatCode = createDateiformatCode("018"); + + var formatType = createFormatType(); + + assertThat(formatType.getName()).usingRecursiveComparison().isEqualTo(expectedDateiformatCode); + } + + private DateiformatCodeType createDateiformatCode(String codeValue) { + var dateiFormatCode = new DateiformatCodeType(); + dateiFormatCode.setCode(codeValue); + dateiFormatCode.setListURI(VersionTypeBuilder.DATEI_FORMAT_LIST_URI); + dateiFormatCode.setListVersionID(VersionTypeBuilder.LIST_VERSION_ID); + return dateiFormatCode; + } + + @Test + void shouldHaveSonstinerNameEmptyString() { + var formatType = createFormatType(); + + assertThat(formatType.getSonstigerName()).isEqualTo(StringUtils.EMPTY); + } + + @Test + void shouldHaveVersionEmptyString() { + var formatType = createFormatType(); + + assertThat(formatType.getVersion()).isEqualTo(StringUtils.EMPTY); + } + + private FormatType createFormatType() { + return createVersion().getFormat().getFirst(); + } + + @Nested + class TestPrimaerDokument { + + @Test + void shouldHaveDateiname() { + var primaerdokument = createPrimaerdokumentType(); + + assertThat(primaerdokument.getDateiname()).isEqualTo(FILE_UUID + "_" + ozgFile.getName()); + } + + @Test + void shouldHaveDateinameOriginal() { + var primaerdokument = createPrimaerdokumentType(); + + assertThat(primaerdokument.getDateinameOriginal()).isEqualTo(ozgFile.getName()); + } + + @Test + void shouldHaveErsteller() { + var primaerdokument = createPrimaerdokumentType(); + + assertThat(primaerdokument.getErsteller()).isEqualTo(FORM_ENGINE_NAME); + } + + private PrimaerdokumentType createPrimaerdokumentType() { + return createFormatType().getPrimaerdokument(); + } + } + + } + + } + } + +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/file/DokumentTypeBuilderTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/file/DokumentTypeBuilderTest.java new file mode 100644 index 0000000000000000000000000000000000000000..5278cd01777012fa5c4ff682918eee1506eb96bd --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/file/DokumentTypeBuilderTest.java @@ -0,0 +1,259 @@ +package de.ozgcloud.alfa.file; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Random; + +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Spy; + +import de.ozgcloud.alfa.common.IdentifikationObjektTypeBuilder; +import de.ozgcloud.alfa.common.UUIDConverter; +import de.ozgcloud.alfa.common.VersionTypeBuilder; +import de.ozgcloud.alfa.common.VersionTypeTestFactory; +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.file.OzgFileTestFactory; +import de.ozgcloud.alfa.export.AllgemeineMetadatenTypeTestFactory; +import de.ozgcloud.alfa.export.IdentifikationObjektTypeTestFactory; +import de.xoev.xdomea.AllgemeineMetadatenType; +import de.xoev.xdomea.IdentifikationObjektType; +import de.xoev.xdomea.VersionType; + +class DokumentTypeBuilderTest { + + private static final Long DOKUMENT_ORDINAL_NUMBER = new Random().nextLong(); + private static final String FORM_ENGINE_NAME = "DUMMY_NAME"; + private final OzgFile ozgFile = OzgFileTestFactory.create(); + + @Spy + private final DokumentTypeBuilder builder = DokumentTypeBuilder.builder() + .withOzgFile(ozgFile) + .withFormEngineName(FORM_ENGINE_NAME) + .withOrdinalNumber(DOKUMENT_ORDINAL_NUMBER); + + private MockedStatic<UUIDConverter> uuidConverter; + + @BeforeEach + void init() { + uuidConverter = mockStatic(UUIDConverter.class); + } + + @AfterEach + void cleanup() { + uuidConverter.close(); + } + + @Nested + class TestBuild { + + private final IdentifikationObjektType identifikationObjekt = IdentifikationObjektTypeTestFactory.create(); + private final AllgemeineMetadatenType allgemeineMetadaten = AllgemeineMetadatenTypeTestFactory.create(); + private final VersionType versionType = VersionTypeTestFactory.create(); + + @BeforeEach + void setUp() { + doReturn(identifikationObjekt).when(builder).createIdentifikation(); + doReturn(versionType).when(builder).createVersionType(); + doReturn(allgemeineMetadaten).when(builder).createAllgemeineMetadaten(); + } + + @Test + void shouldCreateIdentifikation() { + builder.build(); + + verify(builder).createIdentifikation(); + } + + @Test + void shouldHaveIdentifikation() { + var dokument = builder.build(); + + assertThat(dokument.getIdentifikation()).isEqualTo(identifikationObjekt); + } + + @Test + void shouldCreateAllgemeineMetadaten() { + builder.build(); + + verify(builder).createAllgemeineMetadaten(); + } + + @Test + void shouldHaveAllgemeineMetadaten() { + var dokument = builder.build(); + + assertThat(dokument.getAllgemeineMetadaten()).isEqualTo(allgemeineMetadaten); + } + + @Test + void shouldCreateVersion() { + builder.build(); + + verify(builder).createVersionType(); + } + + @Test + void shouldHaveVersion() { + var dokumentType = builder.build(); + + assertThat(dokumentType.getVersion()).containsExactly(versionType); + } + + } + + @Nested + class TestCreateIdentifikation { + + private MockedStatic<IdentifikationObjektTypeBuilder> identifikationObjektTypeBuilderMockedStatic; + @Mock + private IdentifikationObjektTypeBuilder identifikationObjektTypeBuilder; + private final IdentifikationObjektType identifikationObjektType = IdentifikationObjektTypeTestFactory.create(); + + @BeforeEach + void setUp() { + identifikationObjektTypeBuilderMockedStatic = mockStatic(IdentifikationObjektTypeBuilder.class); + identifikationObjektTypeBuilderMockedStatic.when(IdentifikationObjektTypeBuilder::builder).thenReturn(identifikationObjektTypeBuilder); + when(identifikationObjektTypeBuilder.withObjectID(OzgFileTestFactory.ID.toString())).thenReturn(identifikationObjektTypeBuilder); + when(identifikationObjektTypeBuilder.withOrdinalNumber(DOKUMENT_ORDINAL_NUMBER)) + .thenReturn(identifikationObjektTypeBuilder); + when(identifikationObjektTypeBuilder.build()).thenReturn(identifikationObjektType); + } + + @AfterEach + void tearDown() { + identifikationObjektTypeBuilderMockedStatic.close(); + } + + @Test + void shouldSetObjectId() { + builder.createIdentifikation(); + + verify(identifikationObjektTypeBuilder).withObjectID(ozgFile.getId().toString()); + } + + @Test + void shouldSetNummerImUebergeordnetenContainer() { + builder.createIdentifikation(); + + verify(identifikationObjektTypeBuilder).withOrdinalNumber(DOKUMENT_ORDINAL_NUMBER); + } + + @Test + void shouldBuildIdentifikationObjectType() { + builder.createIdentifikation(); + + verify(identifikationObjektTypeBuilder).build(); + } + + @Test + void shouldReturnBuiltIdentifikation() { + var resultIdentifikation = builder.createIdentifikation(); + + assertThat(resultIdentifikation).isEqualTo(identifikationObjektType); + } + } + + @Nested + class TestCreateAllgemeineMetadaten { + + @Test + void shouldHaveBetreff() { + var allgemeineMetadaten = builder.createAllgemeineMetadaten(); + + assertThat(allgemeineMetadaten.getBetreff()).isEqualTo(OzgFileTestFactory.NAME); + } + + @Test + void shouldHaveEmptyKennzeichen() { + var allgemeineMetadaten = builder.createAllgemeineMetadaten(); + + assertThat(allgemeineMetadaten.getKennzeichen()).isEmpty(); + } + + @Test + void shouldHaveEmptyBemerkung() { + var allgemeineMetadaten = builder.createAllgemeineMetadaten(); + + assertThat(allgemeineMetadaten.getBemerkung()).isEmpty(); + } + + @Test + void shouldHaveMedium() { + var allgemeineMetadaten = builder.createAllgemeineMetadaten(); + + assertThat(allgemeineMetadaten.getMedium().getCode()).isEqualTo(DokumentTypeBuilder.ALLGEMEINE_METADATEN_MEDIUM_CODE); + } + + } + + @Nested + class CreateVersionType { + + private MockedStatic<VersionTypeBuilder> versionTypeBuilderMockedStatic; + @Mock + private VersionTypeBuilder versionTypeBuilder; + private final VersionType version = VersionTypeTestFactory.create(); + + @BeforeEach + void setUp() { + versionTypeBuilderMockedStatic = mockStatic(VersionTypeBuilder.class); + versionTypeBuilderMockedStatic.when(VersionTypeBuilder::builder).thenReturn(versionTypeBuilder); + when(versionTypeBuilder.withErsteller(FORM_ENGINE_NAME)).thenReturn(versionTypeBuilder); + when(versionTypeBuilder.withOzgFile(ozgFile)).thenReturn(versionTypeBuilder); + when(versionTypeBuilder.withSonstigerName(StringUtils.EMPTY)).thenReturn(versionTypeBuilder); + when(versionTypeBuilder.build()).thenReturn(version); + } + + @AfterEach + void tearDown() { + versionTypeBuilderMockedStatic.close(); + } + + @Test + void shouldSetOzgFile() { + callCreateVersionType(); + + verify(versionTypeBuilder).withOzgFile(ozgFile); + } + + @Test + void shouldSetErsteller() { + callCreateVersionType(); + + verify(versionTypeBuilder).withErsteller(FORM_ENGINE_NAME); + } + + @Test + void shouldSetSonstigerName() { + callCreateVersionType(); + + verify(versionTypeBuilder).withSonstigerName(StringUtils.EMPTY); + } + + @Test + void shouldBuildVersionType() { + callCreateVersionType(); + + verify(versionTypeBuilder).build(); + } + + @Test + void shouldReturnBuiltVersion() { + var resultVersionType = callCreateVersionType(); + + assertThat(resultVersionType).isEqualTo(version); + } + + private VersionType callCreateVersionType() { + return builder.createVersionType(); + } + } + +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/file/ExportFileServiceTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/file/ExportFileServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..73d519947c0903948271c05fd95c06ebcc29f3cf --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/file/ExportFileServiceTest.java @@ -0,0 +1,184 @@ +package de.ozgcloud.alfa.file; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.io.OutputStream; +import java.util.List; +import java.util.stream.Stream; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; + +import de.ozgcloud.alfa.common.binaryfile.BinaryFileService; +import de.ozgcloud.alfa.common.binaryfile.FileId; +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.file.OzgFileService; +import de.ozgcloud.alfa.common.file.OzgFileTestFactory; +import de.ozgcloud.alfa.export.DokumentTypeTestFactory; +import de.ozgcloud.alfa.vorgang.EingangHeaderTestFactory; +import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; +import de.ozgcloud.alfa.vorgang.VorgangWithEingang; +import de.ozgcloud.alfa.vorgang.VorgangWithEingangTestFactory; +import de.xoev.xdomea.DokumentType; + +class ExportFileServiceTest { + + @InjectMocks + private ExportFileService service; + + @Mock + private OzgFileService ozgFileService; + + @Mock + private BinaryFileService binaryFileService; + + private final OzgFile ozgFile = OzgFileTestFactory.create(); + + private final VorgangWithEingang vorgangWithEingang = VorgangWithEingangTestFactory.create(); + + @DisplayName("get representations") + @Nested + class TestGetRepresentations { + + @BeforeEach + void mock() { + when(ozgFileService.getRepresentations(VorgangHeaderTestFactory.ID)).thenReturn(Stream.of(ozgFile)); + } + + @DisplayName("should call get representations") + @Test + void shouldShouldCallGetRepresentations() { + getRepresentations(); + + verify(ozgFileService).getRepresentations(VorgangHeaderTestFactory.ID); + } + + @DisplayName("should return representations") + @Test + void shouldReturnRepresentations() { + var representations = getRepresentations(); + + assertThat(representations).containsExactly(ozgFile); + } + + private List<OzgFile> getRepresentations() { + return service.getRepresentations(vorgangWithEingang).toList(); + } + } + + @DisplayName("get attachments") + @Nested + class TestGetAttachments { + @BeforeEach + void mock() { + when(ozgFileService.getAttachments(VorgangHeaderTestFactory.ID)).thenReturn(Stream.of(ozgFile)); + } + + @DisplayName("should call get attachments") + @Test + void shouldShouldCallGetRepresentations() { + getAttachments(); + + verify(ozgFileService).getAttachments(VorgangHeaderTestFactory.ID); + } + + @DisplayName("should return") + @Test + void shouldReturn() { + var representations = getAttachments(); + + assertThat(representations).containsExactly(ozgFile); + } + + private List<OzgFile> getAttachments() { + return service.getAttachments(vorgangWithEingang).toList(); + } + } + + @Nested + class TestWriteOzgFile { + + private final FileId fileId = OzgFileTestFactory.ID; + + @Mock + private OutputStream outputStream; + + @Test + void shouldCallBinaryFileService() { + service.writeOzgFile(fileId, outputStream); + + verify(binaryFileService).writeFileContent(fileId, outputStream); + } + } + + @Nested + class TestCreateDokumentType { + + private MockedStatic<DokumentTypeBuilder> dokumentTypeBuilderMockedStatic; + + @Mock + private DokumentTypeBuilder dokumentTypeBuilder; + + private final OzgFile ozgFile = OzgFileTestFactory.create(); + private final DokumentType dokumentType = DokumentTypeTestFactory.create(); + + @BeforeEach + void setUp() { + dokumentTypeBuilderMockedStatic = mockStatic(DokumentTypeBuilder.class); + dokumentTypeBuilderMockedStatic.when(DokumentTypeBuilder::builder).thenReturn(dokumentTypeBuilder); + + when(dokumentTypeBuilder.withOzgFile(ozgFile)).thenReturn(dokumentTypeBuilder); + when(dokumentTypeBuilder.withOrdinalNumber(1L)).thenReturn(dokumentTypeBuilder); + when(dokumentTypeBuilder.withFormEngineName(EingangHeaderTestFactory.FORM_ENGINE_NAME)).thenReturn(dokumentTypeBuilder); + when(dokumentTypeBuilder.build()).thenReturn(dokumentType); + } + + @AfterEach + void tearDown() { + dokumentTypeBuilderMockedStatic.close(); + } + + @Test + void shouldBuild() { + service.createDokumentTypes(List.of(ozgFile), EingangHeaderTestFactory.FORM_ENGINE_NAME).toList(); + + verify(dokumentTypeBuilder).build(); + } + + @Test + void shouldSetOzgFile() { + service.createDokumentTypes(List.of(ozgFile), EingangHeaderTestFactory.FORM_ENGINE_NAME).toList(); + + verify(dokumentTypeBuilder).withOzgFile(ozgFile); + } + + @Test + void shouldSetOrdinalNumber() { + service.createDokumentTypes(List.of(ozgFile), EingangHeaderTestFactory.FORM_ENGINE_NAME).toList(); + + verify(dokumentTypeBuilder).withOrdinalNumber(1L); + } + + @Test + void shouldSetFormEngineName() { + service.createDokumentTypes(List.of(ozgFile), EingangHeaderTestFactory.FORM_ENGINE_NAME).toList(); + + verify(dokumentTypeBuilder).withFormEngineName(EingangHeaderTestFactory.FORM_ENGINE_NAME); + } + + @Test + void shouldReturnDokumentTypes() { + var dokumentTypes = service.createDokumentTypes(List.of(ozgFile), EingangHeaderTestFactory.FORM_ENGINE_NAME); + + assertThat(dokumentTypes).containsExactly(dokumentType); + } + } + +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/historie/ExportHistorieServiceTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/historie/ExportHistorieServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..bb06b69d792ba8e9d7178d1e8a4204aeebd5c039 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/historie/ExportHistorieServiceTest.java @@ -0,0 +1,292 @@ +package de.ozgcloud.alfa.historie; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.EnumSource.Mode; +import org.junit.jupiter.params.provider.NullAndEmptySource; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; + +import com.thedeanda.lorem.LoremIpsum; + +import de.ozgcloud.alfa.common.DateConverter; +import de.ozgcloud.alfa.common.HistorienProtokollInformationTypeTestFactory; +import de.ozgcloud.alfa.common.command.CommandOrder; +import de.ozgcloud.alfa.vorgang.VorgangWithEingang; +import de.ozgcloud.alfa.vorgang.VorgangWithEingangTestFactory; +import de.xoev.xdomea.HistorienProtokollInformationType; + +class ExportHistorieServiceTest { + + @Spy + @InjectMocks + private ExportHistorieService service; + + @Mock + private VorgangChangeHistoryService vorgangChangeHistoryService; + + @Nested + class TestCreateHistorienProtokollInformationTypes { + + private final VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); + private final VorgangChangeHistory history = VorgangChangeHistoryTestFactory.create(); + private final HistorienProtokollInformationType statusChangeHistorienProtokollInformationType = HistorienProtokollInformationTypeTestFactory + .create(); + private final HistorienProtokollInformationType aktenzeichenChangeHistorienProtokollInformationType = HistorienProtokollInformationTypeTestFactory + .create(); + private final HistorienProtokollInformationType assignUserChangeHistorienProtokollInformationType = HistorienProtokollInformationTypeTestFactory + .create(); + + @BeforeEach + void setUp() { + when(vorgangChangeHistoryService.createVorgangChangeHistory(vorgang)).thenReturn(history); + doReturn(statusChangeHistorienProtokollInformationType).when(service) + .createHistorienProtokollInformationType(VorgangChangeHistoryTestFactory.STATUS_CHANGE_HISTORY.get(0)); + doReturn(aktenzeichenChangeHistorienProtokollInformationType).when(service) + .createHistorienProtokollInformationType(VorgangChangeHistoryTestFactory.AKTENZEICHEN_CHANGE_HISTORY.get(0)); + doReturn(assignUserChangeHistorienProtokollInformationType).when(service) + .createHistorienProtokollInformationType(VorgangChangeHistoryTestFactory.ASSIGNED_USER_CHANGE_HISTORY.get(0)); + } + + @Test + void shouldGetVorgangChangeHistory() { + service.createHistorienProtokollInformationTypes(vorgang).toList(); + + verify(vorgangChangeHistoryService).createVorgangChangeHistory(vorgang); + } + + @Test + void shouldCreateStatusChangeHistory() { + service.createHistorienProtokollInformationTypes(vorgang).toList(); + + verify(service).createHistorienProtokollInformationType(VorgangChangeHistoryTestFactory.STATUS_CHANGE_HISTORY.get(0)); + } + + @Test + void shouldReturnStatusChangeHistorienProtokollInformationType() { + var historienProtokollInformationTypes = service.createHistorienProtokollInformationTypes(vorgang); + + assertThat(historienProtokollInformationTypes).contains(statusChangeHistorienProtokollInformationType); + } + + @Test + void shouldCreateAktenzeichenChangeHistory() { + service.createHistorienProtokollInformationTypes(vorgang).toList(); + + verify(service).createHistorienProtokollInformationType(VorgangChangeHistoryTestFactory.AKTENZEICHEN_CHANGE_HISTORY.get(0)); + } + + @Test + void shouldReturnAktenzeichenHistorienProtokollInformationType() { + var historienProtokollInformationTypes = service.createHistorienProtokollInformationTypes(vorgang); + + assertThat(historienProtokollInformationTypes).contains(aktenzeichenChangeHistorienProtokollInformationType); + } + + @Test + void shouldCreateAssignUserChangeHistory() { + service.createHistorienProtokollInformationTypes(vorgang).toList(); + + verify(service).createHistorienProtokollInformationType(VorgangChangeHistoryTestFactory.ASSIGNED_USER_CHANGE_HISTORY.get(0)); + } + + @Test + void shouldReturnAssignUserHistorienProtokollInformationType() { + var historienProtokollInformationTypes = service.createHistorienProtokollInformationTypes(vorgang); + + assertThat(historienProtokollInformationTypes).contains(assignUserChangeHistorienProtokollInformationType); + } + } + + @Nested + class TestCreateHistorienProtokollInformationType { + + private static final String CREATED_VALUE_BEFORE_CHANGE = VorgangChangeTestFactory.VALUE_BEFORE_CHANGE + + VorgangChangeTestFactory.ORGANISATIONSEINHEITEN_ID; + private static final String CREATED_VALUE_AFTER_CHANGE = VorgangChangeTestFactory.VALUE_AFTER_CHANGE + + VorgangChangeTestFactory.ORGANISATIONSEINHEITEN_ID; + private final VorgangChange vorgangChange = VorgangChangeTestFactory.create(); + + @BeforeEach + void setUp() { + doReturn(VorgangChangeTestFactory.CREATED_BY_NAME).when(service).createAkteur(vorgangChange); + doReturn(CREATED_VALUE_BEFORE_CHANGE).when(service).createValueBeforeChange(vorgangChange); + doReturn(CREATED_VALUE_AFTER_CHANGE).when(service).createValueAfterChange(vorgangChange); + } + + @Test + void shouldCreateValueBeforeChange() { + service.createHistorienProtokollInformationType(vorgangChange); + + verify(service).createValueBeforeChange(vorgangChange); + } + + @Test + void shouldHaveAlterWert() { + var created = service.createHistorienProtokollInformationType(vorgangChange); + + assertThat(created.getMetadatumAlterWert()).isEqualTo(CREATED_VALUE_BEFORE_CHANGE); + } + + @Test + void shouldCreateValueAfterChange() { + service.createHistorienProtokollInformationType(vorgangChange); + + verify(service).createValueAfterChange(vorgangChange); + } + + @Test + void shouldHaveNeuerWert() { + var created = service.createHistorienProtokollInformationType(vorgangChange); + + assertThat(created.getMetadatumNeuerWert()).isEqualTo(CREATED_VALUE_AFTER_CHANGE); + } + + @Test + void shouldHaveAkteur() { + var created = service.createHistorienProtokollInformationType(vorgangChange); + + assertThat(created.getAkteur()).isEqualTo(VorgangChangeTestFactory.CREATED_BY_NAME); + } + + @Test + void shouldHaveDatumUhrzeit() { + var created = service.createHistorienProtokollInformationType(vorgangChange); + + assertThat(created.getDatumUhrzeit()).isEqualTo(DateConverter.toXmlGregorianCalendar(VorgangChangeTestFactory.FINISHED_AT)); + } + + @Test + void shouldHaveAktion() { + var created = service.createHistorienProtokollInformationType(vorgangChange); + + assertThat(created.getAktion()).isEqualTo(VorgangChangeTestFactory.ORDER); + } + + @Test + void shouldCreateAkteur() { + service.createHistorienProtokollInformationType(vorgangChange); + + verify(service).createAkteur(vorgangChange); + } + } + + @Nested + class TestCreateAkteur { + + private static final String VALUE_FOR_AKTEUR = LoremIpsum.getInstance().getWords(2); + + @Test + void shouldGetValueForAkteur() { + service.createAkteur(VorgangChangeTestFactory.create()); + + verify(service).appendOrganisationseinheitenID(VorgangChangeTestFactory.CREATED_BY_NAME, + VorgangChangeTestFactory.ORGANISATIONSEINHEITEN_ID); + } + + @Test + void shouldReturnValueForAkteur() { + doReturn(VALUE_FOR_AKTEUR).when(service) + .appendOrganisationseinheitenID(VorgangChangeTestFactory.CREATED_BY_NAME, VorgangChangeTestFactory.ORGANISATIONSEINHEITEN_ID); + + var akteur = service.createAkteur(VorgangChangeTestFactory.create()); + + assertThat(akteur).isEqualTo(VALUE_FOR_AKTEUR); + } + } + + @Nested + class TestCreateValueBeforeChange { + + private static final String ASSIGNED_USER = LoremIpsum.getInstance().getWords(2); + + @ParameterizedTest + @EnumSource(mode = Mode.EXCLUDE, names = "ASSIGN_USER") + void shouldReturnValueForOrder(CommandOrder order) { + var value = service.createValueBeforeChange(VorgangChangeTestFactory.createBuilder().order(order.name()).build()); + + assertThat(value).isEqualTo(VorgangChangeTestFactory.VALUE_BEFORE_CHANGE); + } + + @Test + void shouldGetValueForAssignUserOrder() { + service.createValueBeforeChange(VorgangChangeTestFactory.createBuilder().order(CommandOrder.ASSIGN_USER.name()).build()); + + verify(service).appendOrganisationseinheitenID(VorgangChangeTestFactory.VALUE_BEFORE_CHANGE, + VorgangChangeTestFactory.ORGANISATIONSEINHEITEN_ID); + } + + @Test + void shouldReturnValueForAssignUserOrder() { + doReturn(ASSIGNED_USER).when(service) + .appendOrganisationseinheitenID(VorgangChangeTestFactory.VALUE_BEFORE_CHANGE, VorgangChangeTestFactory.ORGANISATIONSEINHEITEN_ID); + + var value = service + .createValueBeforeChange(VorgangChangeTestFactory.createBuilder().order(CommandOrder.ASSIGN_USER.name()).build()); + + assertThat(value).isEqualTo(ASSIGNED_USER); + } + } + + @Nested + class TestCreateValueAfterChange { + + private static final String ASSIGNED_USER = LoremIpsum.getInstance().getWords(2); + + @ParameterizedTest + @EnumSource(mode = Mode.EXCLUDE, names = "ASSIGN_USER") + void shouldReturnValueForOrder(CommandOrder order) { + var value = service.createValueAfterChange(VorgangChangeTestFactory.createBuilder().order(order.name()).build()); + + assertThat(value).isEqualTo(VorgangChangeTestFactory.VALUE_AFTER_CHANGE); + } + + @Test + void shouldGetValueForAssignUserOrder() { + service.createValueAfterChange(VorgangChangeTestFactory.createBuilder().order(CommandOrder.ASSIGN_USER.name()).build()); + + verify(service).appendOrganisationseinheitenID(VorgangChangeTestFactory.VALUE_AFTER_CHANGE, + VorgangChangeTestFactory.ORGANISATIONSEINHEITEN_ID); + } + + @Test + void shouldReturnValueForAssignUserOrder() { + doReturn(ASSIGNED_USER).when(service) + .appendOrganisationseinheitenID(VorgangChangeTestFactory.VALUE_AFTER_CHANGE, VorgangChangeTestFactory.ORGANISATIONSEINHEITEN_ID); + + var value = service.createValueAfterChange(VorgangChangeTestFactory.createBuilder().order(CommandOrder.ASSIGN_USER.name()).build()); + + assertThat(value).isEqualTo(ASSIGNED_USER); + } + } + + @Nested + class TestAppendOrganisationseinheitenID { + + private static final String TEXT = LoremIpsum.getInstance().getWords(2); + + @ParameterizedTest + @NullAndEmptySource + void shouldReturnEmpty(String assignedUser) { + var value = service.appendOrganisationseinheitenID(assignedUser, VorgangChangeTestFactory.ORGANISATIONSEINHEITEN_ID); + + assertThat(value).isEmpty(); + } + + @Test + void shouldAppendOrganisationseinheitenID() { + var value = service.appendOrganisationseinheitenID(TEXT, VorgangChangeTestFactory.ORGANISATIONSEINHEITEN_ID); + + assertThat(value).isEqualTo( + String.format("%s; %s", TEXT, VorgangChangeTestFactory.ORGANISATIONSEINHEITEN_ID)); + } + } + +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/kommentar/DokumentTypeBuilderITCase.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/kommentar/DokumentTypeBuilderITCase.java new file mode 100644 index 0000000000000000000000000000000000000000..366b478272feb2591773b77c42d6c7d6a08088c9 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/kommentar/DokumentTypeBuilderITCase.java @@ -0,0 +1,187 @@ +package de.ozgcloud.alfa.kommentar; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.List; +import java.util.stream.Stream; + +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.MockedStatic; + +import de.ozgcloud.alfa.common.UUIDConverter; +import de.ozgcloud.alfa.common.VersionTypeBuilder; +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.file.OzgFileTestFactory; +import de.xoev.xdomea.AnlageDokumentType; +import de.xoev.xdomea.DateiformatCodeType; +import de.xoev.xdomea.FormatType; +import de.xoev.xdomea.IdentifikationObjektType; +import de.xoev.xdomea.VersionType; + +class DokumentTypeBuilderITCase { + + private static final String VERSION_NUMMER = "1"; + private static final String TYP = "Notiz"; + + private static final int IDX_ANLAGE_PDF = 0; + private static final int IDX_ANLAGE_JPEG = 1; + private static final int IDX_ANLAGE_JPG = 2; + + private final Kommentar kommentar = KommentarTestFactory.create(); + private final OzgFile attachment1 = OzgFileTestFactory.createBuilder().contentType("application/pdf").build(); + private final OzgFile attachment2 = OzgFileTestFactory.createBuilder().contentType("image/jpeg").name("Testfile.jpeg").build(); + private final OzgFile attachment3 = OzgFileTestFactory.createBuilder().contentType("image/jpeg").name("Testfile.jpg").build(); + private final List<OzgFile> attachments = List.of(attachment1, attachment2, attachment3); + private final DokumentTypeBuilder builder = DokumentTypeBuilder.builder().withKommentar(kommentar).withKommentarAttachments(attachments); + + @Nested + class TestBuild { + private MockedStatic<UUIDConverter> uuidConverterMockedStatic; + private final static String KOMMENTAR_UUID = "correct kommentar ID"; + private final static String ATTACHMENT1_UUID = "correct attachment ID"; + + @BeforeEach + void setUp() { + uuidConverterMockedStatic = mockStatic(UUIDConverter.class); + uuidConverterMockedStatic.when(() -> UUIDConverter.fromObjectId(KommentarTestFactory.ID)) + .thenReturn(KOMMENTAR_UUID); + uuidConverterMockedStatic.when(() -> UUIDConverter.fromObjectId(attachment1.getId().toString())) + .thenReturn(ATTACHMENT1_UUID); + } + + @AfterEach + void tearDown() { + uuidConverterMockedStatic.close(); + } + + @Test + void shouldHaveTyp() { + var dokumentType = builder.build(); + + assertThat(dokumentType.getTyp()).isEqualTo(TYP); + } + + @Test + void shouldHaveIdentifikation() { + var expectedIdentifikation = new IdentifikationObjektType(); + expectedIdentifikation.setID(KOMMENTAR_UUID); + + var dokumentType = builder.build(); + + assertThat(dokumentType.getIdentifikation()).usingRecursiveComparison().isEqualTo(expectedIdentifikation); + } + + @Nested + class TestAnlage { + @Test + void shouldHaveIdentifikation() { + var expectedIdentifikation = new IdentifikationObjektType(); + expectedIdentifikation.setID(ATTACHMENT1_UUID); + + var anlageType = getAnlage(IDX_ANLAGE_PDF); + + assertThat(anlageType.getIdentifikation()).usingRecursiveComparison().isEqualTo(expectedIdentifikation); + } + + @Nested + class TestVersion { + @Test + void shouldHaveNummer() { + var version = getVersion(IDX_ANLAGE_PDF); + + assertThat(version.getNummer()).isEqualTo(VERSION_NUMMER); + } + + private VersionType getVersion(int anlageIndex) { + var anlage = getAnlage(anlageIndex); + assertThat(anlage.getVersion()).hasSize(1); + return getAnlage(anlageIndex).getVersion().getFirst(); + } + + @Nested + class TestFormat { + @Test + void shouldHaveNameForPdf() { + var expectedDateiFormat = createDateiformatCode("018"); + + var format = getFormat(IDX_ANLAGE_PDF); + + assertThat(format.getName()).usingRecursiveComparison().isEqualTo(expectedDateiFormat); + } + + @ParameterizedTest + @MethodSource("shouldHaveNameForJpegDataProvider") + void shouldHaveNameForJpeg(int anlageIdx, String expectedCode) { + var expectedDateiFormat = createDateiformatCode(expectedCode); + + var format = getFormat(anlageIdx); + + assertThat(format.getName()).usingRecursiveComparison().isEqualTo(expectedDateiFormat); + } + + private static Stream<Arguments> shouldHaveNameForJpegDataProvider() { + return Stream.of( + Arguments.of(IDX_ANLAGE_JPEG, "010"), + Arguments.of(IDX_ANLAGE_JPG, "011")); + } + + private DateiformatCodeType createDateiformatCode(String codeValue) { + var dateiFormatCode = new DateiformatCodeType(); + dateiFormatCode.setCode(codeValue); + dateiFormatCode.setListURI(VersionTypeBuilder.DATEI_FORMAT_LIST_URI); + dateiFormatCode.setListVersionID(VersionTypeBuilder.LIST_VERSION_ID); + return dateiFormatCode; + } + + @Test + void shouldHaveVersion() { + var format = getFormat(IDX_ANLAGE_PDF); + + assertThat(format.getVersion()).isEqualTo(StringUtils.EMPTY); + + } + + private FormatType getFormat(int anlageIndex) { + var version = getVersion(anlageIndex); + assertThat(version.getFormat()).hasSize(1); + return getVersion(anlageIndex).getFormat().getFirst(); + } + + @Nested + class TestPrimaerDokument { + @Test + void shouldHaveDateiname() { + var primaerdokument = getFormat(IDX_ANLAGE_PDF).getPrimaerdokument(); + + assertThat(primaerdokument.getDateiname()) + .isEqualTo(ATTACHMENT1_UUID + "_" + attachment1.getName()); + + } + + @Test + void shouldHaveDateinameOriginal() { + var primaerdokument = getFormat(IDX_ANLAGE_PDF).getPrimaerdokument(); + + assertThat(primaerdokument.getDateinameOriginal()) + .isEqualTo(attachment1.getName()); + + } + } + } + + } + + private AnlageDokumentType getAnlage(int index) { + return builder.build().getAnlage().get(index); + } + } + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/kommentar/DokumentTypeBuilderTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/kommentar/DokumentTypeBuilderTest.java new file mode 100644 index 0000000000000000000000000000000000000000..e09747b371014cfb5b9b776f8fed4a533649421e --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/kommentar/DokumentTypeBuilderTest.java @@ -0,0 +1,278 @@ +package de.ozgcloud.alfa.kommentar; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.List; + +import javax.xml.datatype.XMLGregorianCalendar; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Spy; + +import com.thedeanda.lorem.LoremIpsum; + +import de.ozgcloud.alfa.common.AnlageDokumentTypeBuilder; +import de.ozgcloud.alfa.common.AnlageDokumentTypeTestFactory; +import de.ozgcloud.alfa.common.DateConverter; +import de.ozgcloud.alfa.common.HistorienProtokollInformationTypeTestFactory; +import de.ozgcloud.alfa.common.IdentifikationObjektTypeBuilder; +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.file.OzgFileTestFactory; +import de.ozgcloud.alfa.common.user.UserProfileTestFactory; +import de.ozgcloud.alfa.export.IdentifikationObjektTypeTestFactory; +import de.ozgcloud.alfa.vorgang.ZustaendigeStelleTestFactory; +import de.xoev.xdomea.AnlageDokumentType; +import de.xoev.xdomea.DokumentType; +import de.xoev.xdomea.HistorienProtokollInformationType; +import de.xoev.xdomea.IdentifikationObjektType; + +class DokumentTypeBuilderTest { + + @Spy + private DokumentTypeBuilder builder = DokumentTypeBuilder.builder().withKommentar(KommentarTestFactory.create()); + + @Nested + class TestBuild { + + private MockedStatic<IdentifikationObjektTypeBuilder> identifikationObjektTypeBuilderMockedStatic; + @Mock + private IdentifikationObjektTypeBuilder identifikationObjektTypeBuilder; + private final IdentifikationObjektType identifikationObjektType = IdentifikationObjektTypeTestFactory.create(); + + private final OzgFile ozgFile = OzgFileTestFactory.create(); + private final AnlageDokumentType anlageDokumentType = AnlageDokumentTypeTestFactory.create(); + + private final HistorienProtokollInformationType historienProtokollInformationType = HistorienProtokollInformationTypeTestFactory.create(); + + @BeforeEach + void setUp() { + identifikationObjektTypeBuilderMockedStatic = mockStatic(IdentifikationObjektTypeBuilder.class); + identifikationObjektTypeBuilderMockedStatic.when(IdentifikationObjektTypeBuilder::builder).thenReturn(identifikationObjektTypeBuilder); + when(identifikationObjektTypeBuilder.withObjectID(KommentarTestFactory.ID)).thenReturn(identifikationObjektTypeBuilder); + when(identifikationObjektTypeBuilder.build()).thenReturn(identifikationObjektType); + doReturn(historienProtokollInformationType).when(builder).createHistorie(); + } + + @AfterEach + void tearDown() { + identifikationObjektTypeBuilderMockedStatic.close(); + } + + @Test + void shouldSetObjectId() { + builder.build(); + + verify(identifikationObjektTypeBuilder).withObjectID(KommentarTestFactory.ID); + } + + @Test + void shouldBuildIdentifikationObjectType() { + builder.build(); + + verify(identifikationObjektTypeBuilder).build(); + } + + @Nested + class WithoutKommentareAttachments { + + @Test + void shouldHaveIdentifikation() { + var dokumentType = builder.build(); + + assertThat(dokumentType.getIdentifikation()).isEqualTo(identifikationObjektType); + } + + @Test + void shouldHaveTypNotiz() { + var dokumentType = builder.build(); + + assertThat(dokumentType.getTyp()).isEqualTo(DokumentTypeBuilder.TYP); + } + } + + @Nested + class WithKommentareAttachments { + + @BeforeEach + void setUp() { + doReturn(anlageDokumentType).when(builder).createAnlage(ozgFile); + } + + @Test + void shouldCreateAnlagenForKommentarAttachments() { + builder.withKommentarAttachments(List.of(ozgFile)).build(); + + verify(builder).createAnlage(ozgFile); + } + + @Test + void shouldHaveAnlagen() { + var dokumentType = builder.withKommentarAttachments(List.of(ozgFile)).build(); + + assertThat(dokumentType.getAnlage()).contains(anlageDokumentType); + } + } + + @Test + void shouldHaveHistorienProtokoll() { + DokumentType dokumentType = builder.build(); + + assertThat(dokumentType.getHistorienProtokollInformation().get(0)).isEqualTo(historienProtokollInformationType); + } + + @Test + void shouldHaveOneHistorienProtokoll() { + DokumentType dokumentType = builder.build(); + + assertThat(dokumentType.getHistorienProtokollInformation()).size().isEqualTo(1); + } + + @Test + void shouldCreateHistorienProtokoll() { + builder.build(); + + verify(builder).createHistorie(); + } + + } + + @Nested + class TestCreateAnlage { + + private final OzgFile ozgFile = OzgFileTestFactory.create(); + + private MockedStatic<AnlageDokumentTypeBuilder> anlageDokumentTypeBuilderMockedStatic; + @Mock + private AnlageDokumentTypeBuilder anlageDokumentTypeBuilder; + private AnlageDokumentType expectedAnlage = AnlageDokumentTypeTestFactory.create(); + + @BeforeEach + void setUp() { + anlageDokumentTypeBuilderMockedStatic = mockStatic(AnlageDokumentTypeBuilder.class); + anlageDokumentTypeBuilderMockedStatic.when(AnlageDokumentTypeBuilder::builder).thenReturn(anlageDokumentTypeBuilder); + when(anlageDokumentTypeBuilder.withOzgFile(ozgFile)).thenReturn(anlageDokumentTypeBuilder); + when(anlageDokumentTypeBuilder.build()).thenReturn(expectedAnlage); + } + + @AfterEach + void tearDown() { + anlageDokumentTypeBuilderMockedStatic.close(); + } + + @Test + void shouldSetOzgFile() { + callCreateAnlage(); + + verify(anlageDokumentTypeBuilder).withOzgFile(ozgFile); + } + + @Test + void shouldBuildAnlageDokumentType() { + callCreateAnlage(); + + verify(anlageDokumentTypeBuilder).build(); + } + + @Test + void shouldReturnBuiltAnlage() { + var resultAnlage = callCreateAnlage(); + + assertThat(resultAnlage).isEqualTo(expectedAnlage); + } + + private AnlageDokumentType callCreateAnlage() { + return builder.createAnlage(ozgFile); + } + } + + @Nested + class TestWithOrganisationseinheitenID { + @Test + void shouldReturnBuilder() { + var result = builder.withOrganisationseinheitenID(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEITEN_ID); + + assertThat(result).isNotNull(); + } + } + + @Nested + class TestWithAuthorFullName { + @Test + void shouldReturnBuilder() { + var result = builder.withAuthorFullName(UserProfileTestFactory.FULLNAME); + + assertThat(result).isNotNull(); + } + } + + @Nested + class TestCreateHistorie { + + Kommentar kommentar = KommentarTestFactory.create(); + + @BeforeEach + void setupBuilder() { + builder.withKommentar(kommentar); + } + + @Test + void shouldHaveMetadatumName() { + var historie = builder.createHistorie(); + + assertThat(historie.getMetadatumName()).isEqualTo(KommentarTestFactory.TEXT); + } + + @Test + void shouldHaveAkteur() { + String expectedAkteurName = LoremIpsum.getInstance().getWords(5); + doReturn(expectedAkteurName).when(builder).createAkteur(); + + var historie = builder.createHistorie(); + + assertThat(historie.getAkteur()).isEqualTo(expectedAkteurName); + } + + @Test + void shouldHaveDatumUhrzeit() { + var historie = builder.createHistorie(); + + assertThat(historie.getDatumUhrzeit()).isEqualTo(createExpectedDatumUhrzeit()); + } + + @Test + void shouldHaveAktion() { + var historie = builder.createHistorie(); + + assertThat(historie).hasFieldOrPropertyWithValue("aktion", DokumentTypeBuilder.AKTION); + } + + private XMLGregorianCalendar createExpectedDatumUhrzeit() { + return DateConverter.toXmlGregorianCalendar(kommentar.getCreatedAt()); + } + } + + @Nested + class TestCreateAkteur { + @Test + void shouldCreateName() { + builder.withAuthorFullName(UserProfileTestFactory.FULLNAME); + builder.withOrganisationseinheitenID(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEITEN_ID); + + String akteur = builder.createAkteur(); + + assertThat(akteur).isEqualTo(createExpectedAkteurName()); + } + + private String createExpectedAkteurName() { + return UserProfileTestFactory.FULLNAME + "; " + ZustaendigeStelleTestFactory.ORGANISATIONSEINHEITEN_ID; + } + + } + +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/kommentar/ExportKommentarServiceTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/kommentar/ExportKommentarServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..66d5b18b2bb00cf80d1747fc2fa4804fba28dd48 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/kommentar/ExportKommentarServiceTest.java @@ -0,0 +1,259 @@ +package de.ozgcloud.alfa.kommentar; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.List; +import java.util.stream.Stream; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Spy; + +import de.ozgcloud.alfa.common.binaryfile.BinaryFileService; +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.user.UserId; +import de.ozgcloud.alfa.common.user.UserProfileTestFactory; +import de.ozgcloud.alfa.common.user.UserService; +import de.ozgcloud.alfa.export.DokumentTypeTestFactory; +import de.ozgcloud.alfa.kommentar.KommentarsExportData.KommentarsExportDataBuilder; +import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; +import de.ozgcloud.alfa.vorgang.VorgangWithEingang; +import de.ozgcloud.alfa.vorgang.VorgangWithEingangTestFactory; +import de.ozgcloud.alfa.vorgang.ZustaendigeStelleTestFactory; +import de.xoev.xdomea.DokumentType; + +class ExportKommentarServiceTest { + + @Spy + @InjectMocks + private ExportKommentarService service; + + @Mock + private KommentarService kommentarService; + @Mock + private BinaryFileService binaryFileService; + + @Mock + private UserService userService; + + private final Kommentar kommentar = KommentarTestFactory.create(); + + @Nested + class TestCreateExportData { + + private final VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); + private final KommentarsExportData exportData = KommentarsExportDataTestFactory.create(); + + private final ExportKommentarService.KommentarExportData kommentarExportData = new ExportKommentarService.KommentarExportData( + ZustaendigeStelleTestFactory.ORGANISATIONSEINHEITEN_ID, kommentar); + + private MockedStatic<KommentarsExportData> kommentarsExportDataMockedStatic; + @Mock + private KommentarsExportDataBuilder exportDataBuilder; + + @BeforeEach + void setUp() { + kommentarsExportDataMockedStatic = mockStatic(KommentarsExportData.class); + kommentarsExportDataMockedStatic.when(KommentarsExportData::builder).thenReturn(exportDataBuilder); + when(service.getKommentare(vorgang)).thenReturn(Stream.of(kommentar)); + when(service.createKommentarExportData(vorgang, kommentar)).thenReturn(kommentarExportData); + doNothing().when(service).addKommentarExportData(kommentarExportData, exportDataBuilder); + when(exportDataBuilder.build()).thenReturn(exportData); + } + + @AfterEach + void tearDown() { + kommentarsExportDataMockedStatic.close(); + } + + @Test + void shouldAddKommentarExportData() { + callService(); + + verify(service).addKommentarExportData(eq(kommentarExportData), eq(exportDataBuilder)); + } + + @Test + void shouldBuildExportData() { + callService(); + + verify(exportDataBuilder).build(); + } + + @Test + void shouldReturnBuiltExportData() { + var result = callService(); + + assertThat(result).isEqualTo(exportData); + } + + private KommentarsExportData callService() { + return service.createExportData(vorgang); + } + } + + @Nested + class TestAddKommentarExportData { + + private final String authorFullName = UserProfileTestFactory.FULLNAME; + private final List<OzgFile> attachments = List.of(KommentarsExportDataTestFactory.OZG_FILE); + private final DokumentType dokumentType = DokumentTypeTestFactory.create(); + private final String organisationsEinheitenID = ZustaendigeStelleTestFactory.ORGANISATIONSEINHEITEN_ID; + private final ExportKommentarService.KommentarExportData kommentarExportData = new ExportKommentarService.KommentarExportData( + organisationsEinheitenID, + kommentar + ); + private MockedStatic<DokumentTypeBuilder> dokumentTypeBuilderMockedStatic; + @Mock + private DokumentTypeBuilder dokumentTypeBuilder; + @Mock + private KommentarsExportDataBuilder exportDataBuilder; + + @BeforeEach + void setUp() { + doReturn(attachments).when(service).getAttachments(kommentar); + doReturn(authorFullName).when(service).getAuthorFullName(kommentar); + + dokumentTypeBuilderMockedStatic = mockStatic(DokumentTypeBuilder.class); + dokumentTypeBuilderMockedStatic.when(() -> DokumentTypeBuilder.builder()).thenReturn(dokumentTypeBuilder); + + doReturn(dokumentTypeBuilder).when(dokumentTypeBuilder).withKommentarAttachments(attachments); + doReturn(dokumentTypeBuilder).when(dokumentTypeBuilder).withKommentar(kommentar); + doReturn(dokumentTypeBuilder).when(dokumentTypeBuilder) + .withOrganisationseinheitenID(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEITEN_ID); + doReturn(dokumentTypeBuilder).when(dokumentTypeBuilder).withAuthorFullName(authorFullName); + doReturn(dokumentType).when(dokumentTypeBuilder).build(); + } + + @AfterEach + void tearDown() { + dokumentTypeBuilderMockedStatic.close(); + } + + @Test + void shouldSetDokumentType() { + callService(); + + verify(exportDataBuilder).dokumentType(dokumentType); + } + + @Test + void shouldSetAttachments() { + callService(); + + verify(exportDataBuilder).attachments(attachments); + } + + @Test + void shouldSetOzgFile() { + callService(); + + verify(dokumentTypeBuilder).withKommentarAttachments(attachments); + } + + @Test + void shouldSetKommentar() { + callService(); + + verify(dokumentTypeBuilder).withKommentar(kommentar); + } + + @Test + void shouldSetOrganisationseinheitID() { + callService(); + + verify(dokumentTypeBuilder).withOrganisationseinheitenID(organisationsEinheitenID); + } + + @Test + void shouldReturnAuthorFullName() { + callService(); + + verify(dokumentTypeBuilder).withAuthorFullName(authorFullName); + } + + @Test + void shouldBuildDokumentType() { + callService(); + + verify(dokumentTypeBuilder).build(); + } + + private void callService() { + service.addKommentarExportData(kommentarExportData, exportDataBuilder); + } + } + + @Nested + class TestGetAttachments { + + @Test + void shouldGetFiles() { + service.getAttachments(kommentar); + + verify(binaryFileService).getFiles(KommentarTestFactory.ATTACHMENTS); + } + + @Test + void shouldReturnAttachments() { + List<OzgFile> attachments = List.of(KommentarsExportDataTestFactory.OZG_FILE); + when(binaryFileService.getFiles(KommentarTestFactory.ATTACHMENTS)).thenReturn(attachments.stream()); + + var result = service.getAttachments(kommentar); + + assertThat(result).isEqualTo(attachments); + } + } + + @Nested + class TestGetAuthorFullName { + + @BeforeEach + void init() { + when(userService.getById(UserProfileTestFactory.ID)).thenReturn(UserProfileTestFactory.create()); + } + + @Test + void shouldGetUser() { + service.getAuthorFullName(KommentarTestFactory.create()); + + verify(userService).getById(eq(UserId.from(KommentarTestFactory.CREATED_BY))); + } + + @Test + void shouldReturnAuthorsFullName() { + var authorFullName = service.getAuthorFullName(KommentarTestFactory.create()); + + assertThat(authorFullName).isEqualTo(UserProfileTestFactory.FULLNAME); + } + } + + @Nested + class TestGetKommentare { + + private VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); + + @Test + void shouldFindKommentareByVorgang() { + service.getKommentare(vorgang); + + verify(kommentarService).findByVorgangId(VorgangHeaderTestFactory.ID); + } + + @Test + void shouldReturnKommentare() { + when(kommentarService.findByVorgangId(VorgangHeaderTestFactory.ID)).thenReturn(Stream.of(kommentar)); + + var result = service.getKommentare(vorgang); + + assertThat(result).containsExactly(kommentar); + } + } + +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/kommentar/KommentarsExportDataTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/kommentar/KommentarsExportDataTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..a27b9da5f377ac5adf07be8cf939536b2edafb03 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/kommentar/KommentarsExportDataTestFactory.java @@ -0,0 +1,23 @@ +package de.ozgcloud.alfa.kommentar; + +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.file.OzgFileTestFactory; +import de.ozgcloud.alfa.export.DokumentTypeTestFactory; +import de.ozgcloud.alfa.kommentar.KommentarsExportData.KommentarsExportDataBuilder; +import de.xoev.xdomea.DokumentType; + +public class KommentarsExportDataTestFactory { + + public static final DokumentType DOKUMENT_TYPE = DokumentTypeTestFactory.create(); + public static final OzgFile OZG_FILE = OzgFileTestFactory.createWithUniqueId(); + + public static KommentarsExportData create() { + return createBuilder().build(); + } + + public static KommentarsExportDataBuilder createBuilder() { + return KommentarsExportData.builder() + .dokumentType(DOKUMENT_TYPE) + .attachment(OZG_FILE); + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/postfach/DokumentTypeBuilderTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/postfach/DokumentTypeBuilderTest.java new file mode 100644 index 0000000000000000000000000000000000000000..92f88ef542e125d0c0054564bfca590d0b0d5b32 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/postfach/DokumentTypeBuilderTest.java @@ -0,0 +1,297 @@ +package de.ozgcloud.alfa.postfach; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.time.ZonedDateTime; +import java.util.Collections; +import java.util.List; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Spy; + +import de.ozgcloud.alfa.common.AnlageDokumentTypeBuilder; +import de.ozgcloud.alfa.common.AnlageDokumentTypeTestFactory; +import de.ozgcloud.alfa.common.DateConverter; +import de.ozgcloud.alfa.common.HistorienProtokollInformationTypeTestFactory; +import de.ozgcloud.alfa.common.IdentifikationObjektTypeBuilder; +import de.ozgcloud.alfa.common.binaryfile.BinaryFileTestFactory; +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.file.OzgFileTestFactory; +import de.ozgcloud.alfa.common.user.UserProfile; +import de.ozgcloud.alfa.common.user.UserProfileTestFactory; +import de.ozgcloud.alfa.export.IdentifikationObjektTypeTestFactory; +import de.ozgcloud.alfa.postfach.PostfachMail.Direction; +import de.ozgcloud.alfa.vorgang.ZustaendigeStelleTestFactory; +import de.xoev.xdomea.AnlageDokumentType; +import de.xoev.xdomea.HistorienProtokollInformationType; +import de.xoev.xdomea.IdentifikationObjektType; + +public class DokumentTypeBuilderTest { + + private final PostfachMail postfachMail = PostfachMailTestFactory.create(); + private final OzgFile ozgFile = OzgFileTestFactory.createBuilder().id(BinaryFileTestFactory.FILE_ID).build(); + + @Spy + @InjectMocks + private final DokumentTypeBuilder builder = DokumentTypeBuilder.builder() + .withPostfachMail(postfachMail) + .withOzgFiles(List.of(ozgFile)) + .withOrganisationseinheitenId(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEITEN_ID); + + @Nested + class TestBuild { + private static final String TYP = "Nachricht"; + + private MockedStatic<IdentifikationObjektTypeBuilder> identifikationObjektTypeBuilderMockedStatic; + @Mock + private IdentifikationObjektTypeBuilder identifikationObjektTypeBuilder; + private final IdentifikationObjektType identifikationObjektType = IdentifikationObjektTypeTestFactory.create(); + + private final AnlageDokumentType anlageDokument = AnlageDokumentTypeTestFactory.create(); + private final HistorienProtokollInformationType historienProtokollInformation = HistorienProtokollInformationTypeTestFactory.create(); + + @BeforeEach + void setUp() { + identifikationObjektTypeBuilderMockedStatic = mockStatic(IdentifikationObjektTypeBuilder.class); + identifikationObjektTypeBuilderMockedStatic.when(IdentifikationObjektTypeBuilder::builder).thenReturn(identifikationObjektTypeBuilder); + when(identifikationObjektTypeBuilder.withObjectID(PostfachMailTestFactory.ID)).thenReturn(identifikationObjektTypeBuilder); + when(identifikationObjektTypeBuilder.build()).thenReturn(identifikationObjektType); + + doReturn(historienProtokollInformation).when(builder).createHistorienProtokollInformation(); + } + + @AfterEach + void tearDown() { + identifikationObjektTypeBuilderMockedStatic.close(); + } + + @Nested + class TestWithOneAnlage { + @BeforeEach + void mockCreateAnlage() { + doReturn(anlageDokument).when(builder).createAnlage(ozgFile); + } + + @Test + void shouldSetObjectId() { + builder.build(); + + verify(identifikationObjektTypeBuilder).withObjectID(postfachMail.getId()); + } + + @Test + void shouldBuildIdentifikationObjectType() { + builder.build(); + + verify(identifikationObjektTypeBuilder).build(); + } + + @Test + void shouldHaveIdentifikation() { + var dokument = builder.build(); + + assertThat(dokument.getIdentifikation()).isEqualTo(identifikationObjektType); + } + + @Test + void shouldHaveTyp() { + var dokument = builder.build(); + + assertThat(dokument.getTyp()).isEqualTo(TYP); + } + + @Test + void shouldHaveHistorienProtokollInformation() { + var dokument = builder.build(); + + assertThat(dokument.getHistorienProtokollInformation()).containsExactly(historienProtokollInformation); + } + + @Test + void shouldCallCreateAnlage() { + builder.build(); + + verify(builder).createAnlage(ozgFile); + } + + @Test + void shouldHaveOneAnlage() { + var dokument = builder.build(); + + assertThat(dokument.getAnlage()).containsExactly(anlageDokument); + } + } + + @Nested + class TestWithoutAnlage { + @Test + void shouldHaveNoAnlage() { + var dokument = builder.withOzgFiles(Collections.emptyList()).build(); + + assertThat(dokument.getAnlage()).isEmpty(); + } + } + } + + @Nested + class TestCreateHistorienProtokollInformation { + private static final String AKTEUR = "correct aktuer"; + private static final String NACHRICHT_EMPFANGEN = "Nachricht empfangen"; + private static final String NACHRICHT_GESENDET = "Nachricht gesendet"; + + @BeforeEach + void setUpMock() { + doReturn(AKTEUR).when(builder).getAkteur(); + doReturn(PostfachMailTestFactory.CREATED_AT).when(builder).getSentTime(); + } + + @Test + void shouldHaveMetadatumName() { + var resultHistorie = callCreateHistorienProtokollInformation(); + + assertThat(resultHistorie.getMetadatumName()).isEqualTo(PostfachMailTestFactory.MAIL_BODY); + } + + @Test + void shouldHaveAkteur() { + var resultHistorie = callCreateHistorienProtokollInformation(); + + assertThat(resultHistorie.getAkteur()).isEqualTo(AKTEUR); + } + + @Test + void shouldCallGetSentTime() { + callCreateHistorienProtokollInformation(); + + verify(builder).getSentTime(); + } + + @Test + void shouldHaveDatumUhrzeit() { + var resultHistorie = callCreateHistorienProtokollInformation(); + + assertThat(resultHistorie.getDatumUhrzeit()).isEqualTo(DateConverter.toXmlGregorianCalendar(PostfachMailTestFactory.CREATED_AT)); + } + + @Test + void shouldReturnAktionWithGesendet() { + builder.withPostfachMail(PostfachMailTestFactory.createBuilder().direction(Direction.OUT).build()); + + var resultHistorie = callCreateHistorienProtokollInformation(); + + assertThat(resultHistorie.getAktion()).isEqualTo(NACHRICHT_GESENDET); + } + + @Test + void shouldReturnAktionWithEmpfangen() { + builder.withPostfachMail(PostfachMailTestFactory.createBuilder().direction(Direction.IN).build()); + + var resultHistorie = callCreateHistorienProtokollInformation(); + + assertThat(resultHistorie.getAktion()).isEqualTo(NACHRICHT_EMPFANGEN); + } + + private HistorienProtokollInformationType callCreateHistorienProtokollInformation() { + return builder.createHistorienProtokollInformation(); + } + } + + @Nested + class TestGetAkteur { + private final UserProfile userProfile = UserProfileTestFactory.create(); + + @Test + void shouldReturnNameAndOrgaIdOfBearbeiter() { + builder.withUserProfile(userProfile); + + var akteur = builder.getAkteur(); + + assertThat(akteur).isEqualTo(UserProfileTestFactory.FULLNAME + "; " + ZustaendigeStelleTestFactory.ORGANISATIONSEINHEITEN_ID); + } + + @Test + void shouldReturnAntragsteller() { + builder.withUserProfile(null); + + var akteur = builder.getAkteur(); + + assertThat(akteur).isEqualTo("Antragsteller"); + } + } + + @Nested + class TestCreateAnlage { + private MockedStatic<AnlageDokumentTypeBuilder> anlageDokumentTypeBuilderMockedStatic; + @Mock + private AnlageDokumentTypeBuilder anlageDokumentTypeBuilder; + private AnlageDokumentType expectedAnlage = AnlageDokumentTypeTestFactory.create(); + + @BeforeEach + void setUp() { + anlageDokumentTypeBuilderMockedStatic = mockStatic(AnlageDokumentTypeBuilder.class); + anlageDokumentTypeBuilderMockedStatic.when(AnlageDokumentTypeBuilder::builder).thenReturn(anlageDokumentTypeBuilder); + when(anlageDokumentTypeBuilder.withOzgFile(ozgFile)).thenReturn(anlageDokumentTypeBuilder); + when(anlageDokumentTypeBuilder.build()).thenReturn(expectedAnlage); + } + + @AfterEach + void tearDown() { + anlageDokumentTypeBuilderMockedStatic.close(); + } + + @Test + void shouldSetOzgFile() { + callCreateAnlage(); + + verify(anlageDokumentTypeBuilder).withOzgFile(ozgFile); + } + + @Test + void shouldBuildAnlageDokumentType() { + callCreateAnlage(); + + verify(anlageDokumentTypeBuilder).build(); + } + + @Test + void shouldReturnBuiltAnlage() { + var resultAnlage = callCreateAnlage(); + + assertThat(resultAnlage).isEqualTo(expectedAnlage); + } + + private AnlageDokumentType callCreateAnlage() { + return builder.createAnlage(ozgFile); + } + } + + @Nested + class TestGetSentTime { + private final ZonedDateTime testTime = ZonedDateTime.now().withNano(0); + + @Test + void shouldReturnCreatedAtForIncoming() { + builder.withPostfachMail(PostfachMailTestFactory.createBuilder().direction(Direction.IN).createdAt(testTime).build()); + + var resultTime = builder.getSentTime(); + + assertThat(resultTime).isEqualTo(testTime); + } + + @Test + void shouldReturnSentAtForOutgoing() { + builder.withPostfachMail(PostfachMailTestFactory.createBuilder().direction(Direction.OUT).sentAt(testTime).build()); + + var resultTime = builder.getSentTime(); + + assertThat(resultTime).isEqualTo(testTime); + } + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/postfach/ExportNachrichtServiceTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/postfach/ExportNachrichtServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..b72bbbf4aa5d1b736b8b55751111154e64564023 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/postfach/ExportNachrichtServiceTest.java @@ -0,0 +1,342 @@ +package de.ozgcloud.alfa.postfach; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentMatcher; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Spy; + +import de.ozgcloud.alfa.common.binaryfile.BinaryFileService; +import de.ozgcloud.alfa.common.binaryfile.BinaryFileTestFactory; +import de.ozgcloud.alfa.common.binaryfile.FileId; +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.file.OzgFileTestFactory; +import de.ozgcloud.alfa.common.user.UserProfile; +import de.ozgcloud.alfa.common.user.UserProfileTestFactory; +import de.ozgcloud.alfa.common.user.UserService; +import de.ozgcloud.alfa.export.DokumentTypeTestFactory; +import de.ozgcloud.alfa.postfach.PostfachMailExportData.PostfachMailExportDataBuilder; +import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; +import de.ozgcloud.alfa.vorgang.VorgangWithEingang; +import de.ozgcloud.alfa.vorgang.VorgangWithEingangTestFactory; +import de.xoev.xdomea.DokumentType; + +class ExportNachrichtServiceTest { + + @Spy + @InjectMocks + private ExportNachrichtService service; + + @Mock + private PostfachMailService postfachMailService; + + @Mock + private UserService userService; + + @Mock + private BinaryFileService binaryFileService; + + @Nested + class TestCreateExportData { + private final VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); + private final PostfachMail postfachMail = PostfachMailTestFactory.create(); + private final List<OzgFile> attachments = List.of(OzgFileTestFactory.create()); + private final PostfachMailExportData exportData = PostfachMailExportDataTestFactory.create(); + + private final ArgumentMatcher<PostfachMailExportInput> exportInputMatcher = input -> input.postfachMail().equals(postfachMail) + && input.organisationseinheitenId().equals(PostfachMailExportInputTestFactory.ORGANISATIONSEINHEITEN_ID) + && input.attachments().equals(attachments); + + private MockedStatic<PostfachMailExportData> postfachMailExportDataMockedStatic; + @Mock + private PostfachMailExportDataBuilder exportDataBuilder; + + @BeforeEach + void setUpMock() { + postfachMailExportDataMockedStatic = mockStatic(PostfachMailExportData.class); + postfachMailExportDataMockedStatic.when(PostfachMailExportData::builder).thenReturn(exportDataBuilder); + doReturn(Stream.of(postfachMail)).when(service).getPostfachMails(VorgangHeaderTestFactory.ID); + doReturn(attachments).when(service).getAttachments(postfachMail); + doNothing().when(service).addPostfachMailExportData(argThat(exportInputMatcher), eq(exportDataBuilder)); + when(exportDataBuilder.build()).thenReturn(exportData); + } + + @AfterEach + void tearDown() { + postfachMailExportDataMockedStatic.close(); + } + + @Test + void shouldgetPostfachMails() { + callService(); + + verify(service).getPostfachMails(vorgang.getId()); + } + + @Test + void shouldCallGetAttachents() { + callService(); + + verify(service).getAttachments(postfachMail); + } + + @Test + void shouldAddInputToBuilder() { + callService(); + + verify(service).addPostfachMailExportData(argThat(exportInputMatcher), eq(exportDataBuilder)); + } + + @Test + void shouldBuildExportData() { + callService(); + + verify(exportDataBuilder).build(); + } + + @Test + void shouldReturnBuiltExportData() { + var result = callService(); + + assertThat(result).isEqualTo(exportData); + } + + private PostfachMailExportData callService() { + return service.createExportData(vorgang); + } + } + + @Nested + class TestAddPostfachMailExportData { + private final List<OzgFile> attachments = PostfachMailExportInputTestFactory.ATTACHMENTS; + private final DokumentType dokumentType = DokumentTypeTestFactory.create(); + private final PostfachMailExportInput exportInput = PostfachMailExportInputTestFactory.create(); + + @Mock + private PostfachMailExportDataBuilder exportDataBuilder; + + @BeforeEach + void setUpMocks() { + doReturn(dokumentType).when(service).buildDokumentType(exportInput); + } + + @Test + void shouldAddAttachmentsToBuilder() { + callService(); + + verify(exportDataBuilder).attachments(attachments); + } + + @Test + void shouldBuildDokumentType() { + callService(); + + verify(service).buildDokumentType(exportInput); + } + + @Test + void shouldAddDokumentTypeToBuilder() { + callService(); + + verify(exportDataBuilder).dokumentType(dokumentType); + } + + private void callService() { + service.addPostfachMailExportData(exportInput, exportDataBuilder); + } + } + + @Nested + class TestGetPostfachMails { + private final PostfachMail postfachMail = PostfachMailTestFactory.create(); + + @Test + void shouldCallPostfachMailServiceGetAll() { + service.getPostfachMails(VorgangHeaderTestFactory.ID); + + verify(postfachMailService).getAll(VorgangHeaderTestFactory.ID); + } + + @Test + void shouldReturnPostfachMails() { + when(postfachMailService.getAll(VorgangHeaderTestFactory.ID)).thenReturn(Stream.of(postfachMail)); + + var postfachMails = service.getPostfachMails(VorgangHeaderTestFactory.ID); + + assertThat(postfachMails).containsExactly(postfachMail); + } + } + + @Nested + class TestBuildDokumentType { + private final PostfachMailExportInput exportInput = PostfachMailExportInputTestFactory.create(); + private final PostfachMail postfachMail = PostfachMailExportInputTestFactory.POSTFACH_MAIL; + private final List<OzgFile> attachments = PostfachMailExportInputTestFactory.ATTACHMENTS; + private final UserProfile userProfile = UserProfileTestFactory.create(); + + private MockedStatic<DokumentTypeBuilder> dokumentTypeBuilderMockedStatic; + @Mock + private DokumentTypeBuilder dokumentTypeBuilder; + + @BeforeEach + void setUp() { + dokumentTypeBuilderMockedStatic = mockStatic(DokumentTypeBuilder.class); + dokumentTypeBuilderMockedStatic.when(DokumentTypeBuilder::builder).thenReturn(dokumentTypeBuilder); + + when(dokumentTypeBuilder.withPostfachMail(postfachMail)).thenReturn(dokumentTypeBuilder); + when(dokumentTypeBuilder.withOzgFiles(attachments)).thenReturn(dokumentTypeBuilder); + when(dokumentTypeBuilder.withUserProfile(userProfile)).thenReturn(dokumentTypeBuilder); + when(dokumentTypeBuilder.withOrganisationseinheitenId(PostfachMailExportInputTestFactory.ORGANISATIONSEINHEITEN_ID)) + .thenReturn(dokumentTypeBuilder); + doReturn(Optional.of(userProfile)).when(service).getUserProfile(postfachMail); + } + + @AfterEach + void tearDown() { + dokumentTypeBuilderMockedStatic.close(); + } + + @Test + void shouldCallBuilder() { + callService(); + + dokumentTypeBuilderMockedStatic.verify(() -> DokumentTypeBuilder.builder()); + } + + @Test + void shouldCallGetUserProfile() { + callService(); + + verify(service).getUserProfile(postfachMail); + } + + @Test + void shouldBuildWithPostfachMail() { + callService(); + + verify(dokumentTypeBuilder).withPostfachMail(postfachMail); + } + + @Test + void shouldBuildWithOzgFiles() { + callService(); + + verify(dokumentTypeBuilder).withOzgFiles(attachments); + } + + @Test + void shouldBuildWithUserProfile() { + callService(); + + verify(dokumentTypeBuilder).withUserProfile(userProfile); + } + + @Test + void shouldBuildWithOrganisationseinheitenId() { + callService(); + + verify(dokumentTypeBuilder).withOrganisationseinheitenId(PostfachMailExportInputTestFactory.ORGANISATIONSEINHEITEN_ID); + } + + @Test + void shouldBuild() { + callService(); + + verify(dokumentTypeBuilder).build(); + } + + @Test + void shouldReturnBuiltDokumentType() { + var expectedDokumentType = DokumentTypeTestFactory.create(); + when(dokumentTypeBuilder.build()).thenReturn(expectedDokumentType); + + var resultDokumentType = callService(); + + assertThat(resultDokumentType).isEqualTo(expectedDokumentType); + } + + private DokumentType callService() { + return service.buildDokumentType(exportInput); + } + } + + @Nested + class TestGetAttachments { + private final PostfachMail postfachMail = PostfachMailTestFactory.create(); + private final List<FileId> fileIds = List.of(BinaryFileTestFactory.FILE_ID); + + @Test + void shouldCallBinaryFileServiceGetFile() { + service.getAttachments(postfachMail); + + verify(binaryFileService).getFiles(fileIds); + } + + @Test + void shouldReturnGottenOzgFiles() { + var expectedOzgFile = OzgFileTestFactory.create(); + when(binaryFileService.getFiles(fileIds)).thenReturn(Stream.of(expectedOzgFile)); + + var resultOzgFiles = service.getAttachments(postfachMail); + + assertThat(resultOzgFiles).containsExactly(expectedOzgFile); + } + } + + @Nested + class TestGetUserProfile { + @Nested + class TestWithNullUserId { + @Test + void shouldReturnEmptyOptional() { + var postfachMail = PostfachMailTestFactory.createBuilder().createdBy(null).build(); + + var userProfile = callService(postfachMail); + + assertThat(userProfile).isEmpty(); + } + } + + @Nested + class TestWithValidUserId { + private PostfachMail postfachMail = PostfachMailTestFactory.create(); + private UserProfile expectedUserProfile = UserProfileTestFactory.create(); + + @BeforeEach + void mockUserService() { + when(userService.getById(postfachMail.getCreatedBy())).thenReturn(expectedUserProfile); + } + + @Test + void shouldCallUserServiceGetbyId() { + callService(postfachMail); + + verify(userService).getById(PostfachMailTestFactory.CREATED_BY); + } + + @Test + void shouldReturnOptionalOfUserProfile() { + var userProfile = callService(postfachMail); + + assertThat(userProfile).contains(expectedUserProfile); + } + + } + + private Optional<UserProfile> callService(PostfachMail postfachMail) { + return service.getUserProfile(postfachMail); + } + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/postfach/PostfachMailExportDataTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/postfach/PostfachMailExportDataTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..8e121779722428e9a71a6022d62304e0f841b49f --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/postfach/PostfachMailExportDataTestFactory.java @@ -0,0 +1,23 @@ +package de.ozgcloud.alfa.postfach; + +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.file.OzgFileTestFactory; +import de.ozgcloud.alfa.export.DokumentTypeTestFactory; +import de.ozgcloud.alfa.postfach.PostfachMailExportData.PostfachMailExportDataBuilder; +import de.xoev.xdomea.DokumentType; + +public class PostfachMailExportDataTestFactory { + + public static final DokumentType DOKUMENT_TYPE = DokumentTypeTestFactory.create(); + public static final OzgFile OZG_FILE = OzgFileTestFactory.createWithUniqueId(); + + public static PostfachMailExportData create() { + return createBuilder().build(); + } + + public static PostfachMailExportDataBuilder createBuilder() { + return PostfachMailExportData.builder() + .dokumentType(DOKUMENT_TYPE) + .attachment(OZG_FILE); + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/postfach/PostfachMailExportInputTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/postfach/PostfachMailExportInputTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..7a712bb7fc5552f3816bd86ecaf5c902421dc157 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/postfach/PostfachMailExportInputTestFactory.java @@ -0,0 +1,19 @@ +package de.ozgcloud.alfa.postfach; + +import java.util.List; + +import de.ozgcloud.alfa.common.file.OzgFile; +import de.ozgcloud.alfa.common.file.OzgFileTestFactory; +import de.ozgcloud.alfa.vorgang.ZustaendigeStelleTestFactory; + +public class PostfachMailExportInputTestFactory { + + public final static PostfachMail POSTFACH_MAIL = PostfachMailTestFactory.create(); + public final static String ORGANISATIONSEINHEITEN_ID = ZustaendigeStelleTestFactory.ORGANISATIONSEINHEITEN_ID; + public final static List<OzgFile> ATTACHMENTS = List.of(OzgFileTestFactory.create()); + + public static PostfachMailExportInput create() { + return new PostfachMailExportInput(POSTFACH_MAIL, ORGANISATIONSEINHEITEN_ID, ATTACHMENTS); + } + +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/AntragsdatenItemTypeTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/AntragsdatenItemTypeTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..78beaf2e220c513cd516506ea459a848fa4964f3 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/AntragsdatenItemTypeTestFactory.java @@ -0,0 +1,47 @@ +package de.ozgcloud.alfa.vorgang; + +import java.util.List; + +import de.xoev.xdomea.AntragsdatenGroupType; +import de.xoev.xdomea.AntragsdatenItemType; +import de.xoev.xdomea.AntragsdatenMultiValueFieldType; +import de.xoev.xdomea.AntragsdatenSingleValueFieldType; +import de.xoev.xdomea.DatatypeType; + +public class AntragsdatenItemTypeTestFactory { + + public static final String KEY_STRING = "string"; + public static final String KEY_MAP = "map"; + public static final String KEY_COLLECTION = "collection"; + public static final String VALUE_STRING = "value1"; + public static final Integer VALUE_INTEGER = 1; + + public static AntragsdatenSingleValueFieldType createSingleValueField() { + var antragsdatenItemType = new AntragsdatenSingleValueFieldType(); + antragsdatenItemType.setType(DatatypeType.STRING); + antragsdatenItemType.setName(KEY_STRING); + antragsdatenItemType.setValue(VALUE_STRING); + return antragsdatenItemType; + } + + public static AntragsdatenMultiValueFieldType createMultiValueField() { + var antragsdatenItemType = new AntragsdatenMultiValueFieldType(); + antragsdatenItemType.setType(DatatypeType.INTEGER); + antragsdatenItemType.setName(KEY_COLLECTION); + antragsdatenItemType.getValue().add(VALUE_INTEGER); + return antragsdatenItemType; + } + + public static AntragsdatenGroupType createGroup() { + var antragsdatenGroupType = new AntragsdatenGroupType(); + antragsdatenGroupType.setName(KEY_MAP); + + antragsdatenGroupType.getItem().addAll(createAntragsdatenItemTypes()); + + return antragsdatenGroupType; + } + + public static List<AntragsdatenItemType> createAntragsdatenItemTypes() { + return List.of(createMultiValueField(), createSingleValueField()); + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/AnwendungsspezifischeErweiterungTypeCreatorTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/AnwendungsspezifischeErweiterungTypeCreatorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..ce274988405747bdcb4c47960c7b96699db5896d --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/AnwendungsspezifischeErweiterungTypeCreatorTest.java @@ -0,0 +1,69 @@ +package de.ozgcloud.alfa.vorgang; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; + +import de.xoev.xdomea.AnwendungsspezifischeErweiterungType; +import de.xoev.xdomea.FeldgruppeType; + +class AnwendungsspezifischeErweiterungTypeCreatorTest { + + @Spy + @InjectMocks + private AnwendungsspezifischeErweiterungTypeCreator creator; + + @Mock + private FeldGruppeTypeCreator feldGruppeTypeCreator; + + @Nested + class TestCreate { + + private final VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); + private final FeldgruppeType feldgruppeType = new FeldgruppeType(); + + @BeforeEach + void init() { + when(feldGruppeTypeCreator.create(vorgang)).thenReturn(feldgruppeType); + } + + @Test + void shouldHaveKennung() { + var anwendungsspezifischeErweiterung = create(); + + assertThat(anwendungsspezifischeErweiterung.getKennung()).isEqualTo(AnwendungsspezifischeErweiterungTypeCreator.KENNUNG); + } + + @Test + void shouldHaveName() { + var anwendungsspezifischeErweiterung = create(); + + assertThat(anwendungsspezifischeErweiterung.getName()).isEqualTo(AnwendungsspezifischeErweiterungTypeCreator.NAME); + } + + @Test + void shouldCallFeldgrupperMapper() { + create(); + + verify(feldGruppeTypeCreator).create(vorgang); + } + + @Test + void shouldHaveFeldGruppe() { + var anwendungsspezifischeErweiterung = create(); + + assertThat(anwendungsspezifischeErweiterung.getFeldgruppe()).hasSize(1).first().isEqualTo(feldgruppeType); + } + + private AnwendungsspezifischeErweiterungType create() { + return creator.create(vorgang); + } + } + +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/AnwendungsspezifischeErweiterungTypeTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/AnwendungsspezifischeErweiterungTypeTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..c23de6fe41c1d9ff17d9395478793d9830de4280 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/AnwendungsspezifischeErweiterungTypeTestFactory.java @@ -0,0 +1,10 @@ +package de.ozgcloud.alfa.vorgang; + +import de.xoev.xdomea.AnwendungsspezifischeErweiterungType; + +public class AnwendungsspezifischeErweiterungTypeTestFactory { + + public static AnwendungsspezifischeErweiterungType create() { + return new AnwendungsspezifischeErweiterungType(); + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/AnwendungsspezifischeErweiterungXMLTypeCreatorTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/AnwendungsspezifischeErweiterungXMLTypeCreatorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..554dd1f7d98990b064a334d55217db0b40837f73 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/AnwendungsspezifischeErweiterungXMLTypeCreatorTest.java @@ -0,0 +1,53 @@ +package de.ozgcloud.alfa.vorgang; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; + +import de.xoev.xdomea.Antragsdaten; +import de.xoev.xdomea.AnwendungsspezifischeErweiterungXMLType; + +public class AnwendungsspezifischeErweiterungXMLTypeCreatorTest { + + @Spy + @InjectMocks + private AnwendungsspezifischeErweiterungXMLTypeCreator creator; + @Mock + private FormDataMapper formDataMapper; + + @Nested + class TestCreate { + + private final VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); + private final Antragsdaten Antragsdaten = new Antragsdaten(); + + @BeforeEach + void init() { + when(formDataMapper.toAntragsdaten(any())).thenReturn(Antragsdaten); + } + + @Test + void shouldCallFormDataMapper() { + create(); + + verify(formDataMapper).toAntragsdaten(vorgang); + } + + @Test + void shouldHaveAntragsdaten() { + var anwendungsspezifischeErweiterung = create(); + + assertThat(anwendungsspezifischeErweiterung.getAny()).hasSize(1).first().isEqualTo(Antragsdaten); + } + + private AnwendungsspezifischeErweiterungXMLType create() { + return creator.create(vorgang); + } + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/DatatypeMapperTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/DatatypeMapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..2fc79e9adf1c6d41b455c8baf7679b1c53435b9b --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/DatatypeMapperTest.java @@ -0,0 +1,89 @@ +package de.ozgcloud.alfa.vorgang; + +import static org.assertj.core.api.Assertions.*; + +import java.time.LocalDate; +import java.time.ZonedDateTime; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullSource; +import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.InjectMocks; + +import de.xoev.xdomea.DatatypeType; + +class DatatypeMapperTest { + + @InjectMocks + private DatatypeMapper datatypeMapper; + + @DisplayName("should return DatatypeType STRING when") + @ParameterizedTest(name = "\"{0}\"") + @NullSource + @ValueSource(strings = { StringUtils.EMPTY, "a" }) + void shouldReturnString(String arg) { + var datatype = datatypeMapper.from(arg); + + assertThat(datatype).isEqualTo(DatatypeType.STRING); + } + + @Test + void shouldReturnStringAsDefault() { + var datatype = datatypeMapper.from(new Object()); + + assertThat(datatype).isEqualTo(DatatypeType.STRING); + } + + @Test + void shouldReturnDate() { + var datatype = datatypeMapper.from(LocalDate.now()); + + assertThat(datatype).isEqualTo(DatatypeType.DATE); + } + + @Test + void shouldReturnDatetime() { + var datatype = datatypeMapper.from(ZonedDateTime.now()); + + assertThat(datatype).isEqualTo(DatatypeType.DATETIME); + } + + @Test + void shouldReturnInteger() { + var datatype = datatypeMapper.from(1); + + assertThat(datatype).isEqualTo(DatatypeType.INTEGER); + } + + @Test + void shouldReturnFloat() { + var datatype = datatypeMapper.from(1.0f); + + assertThat(datatype).isEqualTo(DatatypeType.FLOAT); + } + + @Test + void shouldReturnBoolean() { + var datatype = datatypeMapper.from(true); + + assertThat(datatype).isEqualTo(DatatypeType.BOOLEAN); + } + + @Test + void shouldReturnTypeOfElementsInCollection() { + var datatype = datatypeMapper.from(List.of(1, 2)); + + assertThat(datatype).isEqualTo(DatatypeType.INTEGER); + } + + @Test + void shouldReturnDefaultIfCollectionIsEmpty() { + var datatype = datatypeMapper.from(new Object[] {}); + + assertThat(datatype).isEqualTo(DatatypeType.STRING); + } +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/ExportFelderTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/ExportFelderTest.java new file mode 100644 index 0000000000000000000000000000000000000000..ae5c14a26f56bde7b114c41bcf87b62bcf56ae1d --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/ExportFelderTest.java @@ -0,0 +1,51 @@ +package de.ozgcloud.alfa.vorgang; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import de.xoev.xdomea.FeldType; + +class ExportFelderTest { + + @Nested + class TestCreateFeld { + + private static final FeldType FELD = ExportFelder.LEIKA_ID.createFeld(); + + @Test + void shouldHaveName() { + assertThat(FELD.getName()).isEqualTo(ExportFelder.LEIKA_ID.getName()); + } + + @Test + void shouldHaveBeschreibung() { + assertThat(FELD.getBeschreibung()).isEqualTo(ExportFelder.LEIKA_ID.getBeschreibung()); + } + + @Test + void shouldHaveDatentyp() { + assertThat(FELD.getDatentyp().getCode()).isEqualTo(ExportFelder.LEIKA_ID.getDatentypCode()); + } + + @Test + void shouldNotHaveWert() { + assertThat(FELD.getWert()).isNull(); + } + + @Nested + class MitWert { + + private static final String FELD_WERT = "123"; + + @Test + void shouldHaveWert() { + var feld = ExportFelder.LEIKA_ID.createFeld(FELD_WERT); + + assertThat(feld.getWert()).isEqualTo(FELD_WERT); + } + } + } + +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/ExportVorgangServiceITCase.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/ExportVorgangServiceITCase.java new file mode 100644 index 0000000000000000000000000000000000000000..8116403db510a3af998bb644a0f56f2e5e810f7b --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/ExportVorgangServiceITCase.java @@ -0,0 +1,100 @@ +package de.ozgcloud.alfa.vorgang; + +import static de.ozgcloud.alfa.vorgang.AntragsdatenItemTypeTestFactory.*; +import static org.assertj.core.api.Assertions.*; + +import java.util.List; +import java.util.Map; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import de.ozgcloud.common.test.ITCase; +import de.xoev.xdomea.Antragsdaten; +import de.xoev.xdomea.AntragsdatenGroupType; +import de.xoev.xdomea.AntragsdatenItemType; +import de.xoev.xdomea.AntragsdatenSingleValueFieldType; + +@ITCase +class ExportVorgangServiceITCase { + + @Autowired + private ExportVorgangService exportVorgangService; + + @Nested + class TestMapVorgang { + + @Nested + class TestMapAntragsdaten { + + private static final Map<String, Object> FORM_DATA = Map.of( + KEY_STRING, VALUE_STRING + + ); + + private static final Map<String, Object> OTHER_DATA = Map.of( + KEY_MAP, Map.of(KEY_COLLECTION, List.of(VALUE_INTEGER)) + ); + + @Test + void shouldContainSingleAntragsdatenElement() { + var vorgangType = exportVorgangService.createVorgangType(VorgangWithEingangTestFactory.create()); + + assertThat(vorgangType.getAnwendungsspezifischeErweiterungXML().getAny()).hasSize(1).first().isInstanceOf(Antragsdaten.class); + } + + @Test + void shouldMapSingleField() { + var antragsdaten = mapToAntragsdaten(); + + assertThat(antragsdaten.getItem()).hasSize(2); + assertContainsSingleValueField(antragsdaten.getItem()); + } + + private void assertContainsSingleValueField(List<AntragsdatenItemType> items) { + var singleValueField = items.stream().filter(item -> item instanceof AntragsdatenSingleValueFieldType).findFirst(); + assertThat(singleValueField).isPresent().get().usingRecursiveComparison().isEqualTo(createSingleValueField()); + } + + @Test + void shouldMapGroup() { + var antragsdaten = mapToAntragsdaten(); + + assertThat(antragsdaten.getItem()).hasSize(2); + assertContainsGroup(antragsdaten.getItem()); + } + + private void assertContainsGroup(List<AntragsdatenItemType> items) { + var group = items.stream().filter(item -> item instanceof AntragsdatenGroupType).findFirst(); + assertThat(group).isPresent().get().extracting(AntragsdatenItemType::getName).isEqualTo(KEY_MAP); + } + + @Test + void shouldMapItemsInGroup() { + var antragsdaten = mapToAntragsdaten(); + + assertThat(antragsdaten.getItem()).hasSize(2); + assertContainsItemsInGroup(antragsdaten.getItem()); + } + + private void assertContainsItemsInGroup(List<AntragsdatenItemType> items) { + var groupItem = items.stream().filter(item -> item instanceof AntragsdatenGroupType) + .map(item -> ((AntragsdatenGroupType) item)) + .map(AntragsdatenGroupType::getItem) + .flatMap(List::stream).findFirst(); + assertThat(groupItem).isPresent().get().usingRecursiveComparison().isEqualTo(createMultiValueField()); + + } + + private Antragsdaten mapToAntragsdaten() { + var eingang = EingangTestFactory.createBuilder().formData(FORM_DATA) + .antragsteller(AntragstellerTestFactory.createBuilder().otherData(OTHER_DATA).build()) + .build(); + var vorgangWithEingang = VorgangWithEingangTestFactory.createBuilder().eingang(eingang).build(); + var vorgangType = exportVorgangService.createVorgangType(vorgangWithEingang); + return (Antragsdaten) vorgangType.getAnwendungsspezifischeErweiterungXML().getAny().get(0); + } + } + } +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/ExportVorgangServiceTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/ExportVorgangServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..4bf5f5eaf384761f16046c10c23662a344ecabf8 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/ExportVorgangServiceTest.java @@ -0,0 +1,115 @@ +package de.ozgcloud.alfa.vorgang; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; + +import de.ozgcloud.alfa.export.AllgemeineMetadatenTypeTestFactory; +import de.ozgcloud.alfa.export.IdentifikationObjektTypeTestFactory; + +public class ExportVorgangServiceTest { + + private final static String VORGANG_ID = "DUMMY_ID"; + private final VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); + + @Spy + @InjectMocks + private ExportVorgangService exportVorgangService; + + @Mock + private VorgangService vorgangService; + + @Nested + class TestGetVorgang { + + @BeforeEach + void init() { + when(vorgangService.findVorgangWithEingang(VORGANG_ID)).thenReturn(vorgang); + } + + @Test + void shouldCallVorgangService() { + exportVorgangService.getVorgang(VORGANG_ID); + + verify(vorgangService).findVorgangWithEingang(VORGANG_ID); + } + + @Test + void shouldReturnVorgangWithEingang() { + assertThat(exportVorgangService.getVorgang(VORGANG_ID)).isEqualTo(vorgang); + } + } + + @Nested + class TestCreateAkteType { + + @Test + void shouldCallCreateIdentifikationObjektType() { + exportVorgangService.createAkteType(vorgang); + + verify(exportVorgangService).createIdentifikationObjektType(); + } + + @Test + void shouldSetIdentifikationObjektType() { + var identifikationObjektType = IdentifikationObjektTypeTestFactory.create(); + doReturn(identifikationObjektType).when(exportVorgangService).createIdentifikationObjektType(); + + var akteType = exportVorgangService.createAkteType(vorgang); + + assertThat(akteType.getIdentifikation()).isEqualTo(identifikationObjektType); + } + + @Test + void shouldCallCreateAllgemeineMetadatenType() { + exportVorgangService.createAkteType(vorgang); + + verify(exportVorgangService).createAllgemeineMetadatenType(vorgang); + } + + @Test + void shouldSetAllgemeineMetadatenType() { + var allgemeineMetadatenType = AllgemeineMetadatenTypeTestFactory.create(); + doReturn(allgemeineMetadatenType).when(exportVorgangService).createAllgemeineMetadatenType(vorgang); + + var akteType = exportVorgangService.createAkteType(vorgang); + + assertThat(akteType.getAllgemeineMetadaten()).isEqualTo(allgemeineMetadatenType); + } + } + + @Nested + class TestCreateIdentifikationObjektType { + + @Test + void shouldSetID() { + var identifikationObjektType = exportVorgangService.createIdentifikationObjektType(); + + assertThat(identifikationObjektType.getID()).isNotBlank(); + } + } + + @Nested + class TestCreateAllgemeineMetadatenType { + + @Test + void shouldSetKennzeichen() { + var allgemeineMetadatenType = exportVorgangService.createAllgemeineMetadatenType(vorgang); + + assertThat(allgemeineMetadatenType.getKennzeichen()).isEqualTo(VorgangHeaderTestFactory.AKTENZEICHEN); + } + + @Test + void shouldSetEmptyKennzeichen() { + var akteType = exportVorgangService.createAkteType(VorgangWithEingangTestFactory.createBuilder().aktenzeichen(null).build()); + + assertThat(akteType.getAllgemeineMetadaten().getKennzeichen()).isEmpty(); + } + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/FeldGruppeTypeCreatorTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/FeldGruppeTypeCreatorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a78cd333af20803b76a8324e731eba5d760b4e8c --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/FeldGruppeTypeCreatorTest.java @@ -0,0 +1,526 @@ +package de.ozgcloud.alfa.vorgang; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.Spy; + +import de.ozgcloud.alfa.common.DatentypCode; +import de.xoev.xdomea.DatentypCodeType; +import de.xoev.xdomea.FeldType; + +class FeldGruppeTypeCreatorTest { + + @Spy + private FeldGruppeTypeCreator creator; + + @Nested + class TestCreate { + + private final VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); + + @Test + void shouldHaveName() { + var created = creator.create(vorgang); + + assertThat(created.getName()).isEqualTo("FeldgruppeOZGCloudBasis"); + } + + @Test + void shouldHaveBeschreibung() { + var created = creator.create(vorgang); + + assertThat(created.getBeschreibung()).isEqualTo("Feldgruppe für OZGCloud Basis"); + } + + @Test + void shouldCreateFeldType() { + creator.create(vorgang); + + verify(creator).createFeldType(vorgang); + } + } + + @Nested + class TestCreateFeldType { + + private final VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); + + @DisplayName("LeikaId") + @Nested + class TestLeikaId { + + @Test + void shouldHaveName() { + var created = create(); + + assertThat(created).extracting(FeldType::getName).isEqualTo("LeikaID"); + } + + @Test + void shouldHaveBeschreibung() { + var created = create(); + + assertThat(created).extracting(FeldType::getBeschreibung).isEqualTo("ID einer Leistung aus dem OZG-Leistungskatalog"); + } + + @Test + void shouldHaveWert() { + var created = create(); + + assertThat(created).extracting(FeldType::getWert).isNull(); + } + + @DisplayName("DatentypCode") + @Nested + class TestDatentypCode { + + @Test + void shouldHaveCode() { + var created = create(); + + assertThat(created).extracting(FeldType::getDatentyp).extracting(DatentypCodeType::getCode) + .isEqualTo(DatentypCode.STRING.getCode()); + } + + @Test + void shouldHaveListURI() { + var created = create(); + + assertThat(created).extracting(FeldType::getDatentyp).extracting(DatentypCodeType::getListURI) + .isEqualTo("urn:xoev-de:xdomea:codeliste:datentyp"); + } + + @Test + void shouldHaveListVersionID() { + var created = create(); + + assertThat(created).extracting(FeldType::getDatentyp).extracting(DatentypCodeType::getListVersionID).isEqualTo("1.1"); + } + + } + + private FeldType create() { + return creator.createFeldType(vorgang).stream() + .filter(feldType -> feldType.getName().equals(ExportFelder.LEIKA_ID.getName())) + .toList().get(0); + } + } + + @DisplayName("Datum Antragseingang") + @Nested + class TestDatumAntragseingang { + + @Test + void shouldHaveName() { + var created = create(); + + assertThat(created).extracting(FeldType::getName).isEqualTo("DatumAntragseingang"); + } + + @Test + void shouldHaveBeschreibung() { + var created = create(); + + assertThat(created).extracting(FeldType::getBeschreibung).isEqualTo("Das Datum des Antragseingangs"); + } + + @Test + void shouldHaveWert() { + var created = create(); + + assertThat(created).extracting(FeldType::getWert).isEqualTo(VorgangHeaderTestFactory.CREATED_AT_STR); + } + + @DisplayName("DatentypCode") + @Nested + class TestDatentypCode { + + @Test + void shouldHaveCode() { + var created = create(); + + assertThat(created).extracting(FeldType::getDatentyp).extracting(DatentypCodeType::getCode) + .isEqualTo(DatentypCode.DATE.getCode()); + } + + @Test + void shouldHaveListURI() { + var created = create(); + + assertThat(created).extracting(FeldType::getDatentyp).extracting(DatentypCodeType::getListURI) + .isEqualTo("urn:xoev-de:xdomea:codeliste:datentyp"); + } + + @Test + void shouldHaveListVersionID() { + var created = create(); + + assertThat(created).extracting(FeldType::getDatentyp).extracting(DatentypCodeType::getListVersionID).isEqualTo("1.1"); + } + + } + + private FeldType create() { + return creator.createFeldType(vorgang).stream() + .filter(feldType -> feldType.getName().equals(ExportFelder.DATUM_ANTRAGSEINGANG.getName())) + .toList().get(0); + } + } + + @DisplayName("Name") + @Nested + class TestName { + + @Test + void shouldHaveName() { + var created = create(vorgang); + + assertThat(created).extracting(FeldType::getName).isEqualTo("Name"); + } + + @Test + void shouldNotHaveBeschreibung() { + var created = create(vorgang); + + assertThat(created).extracting(FeldType::getBeschreibung).isNull(); + } + + @Test + void shouldHaveWert() { + var created = create(vorgang); + + assertThat(created).extracting(FeldType::getWert).isEqualTo(AntragstellerTestFactory.NACHNAME); + } + + @Test + void shouldBeEmptyStringForNullEingang() { + var created = create(VorgangWithEingangTestFactory.createBuilder().eingang(null).build()); + + assertThat(created.getWert()).isEmpty(); + } + + @Test + void shouldBeEmptyStringForNullAntragsteller() { + var created = create( + VorgangWithEingangTestFactory.createBuilder().eingang(EingangTestFactory.createBuilder().antragsteller(null).build()) + .build()); + + assertThat(created.getWert()).isEmpty(); + } + + @Test + void shouldBeEmptyStringForNullNachname() { + var created = create( + VorgangWithEingangTestFactory.createBuilder().eingang( + EingangTestFactory.createBuilder().antragsteller(AntragstellerTestFactory.createBuilder().nachname(null).build()) + .build()) + .build()); + + assertThat(created.getWert()).isEmpty(); + } + + @DisplayName("DatentypCode") + @Nested + class TestDatentypCode { + + @Test + void shouldHaveCode() { + var created = create(vorgang); + + assertThat(created).extracting(FeldType::getDatentyp).extracting(DatentypCodeType::getCode) + .isEqualTo(DatentypCode.STRING.getCode()); + } + + @Test + void shouldHaveListURI() { + var created = create(vorgang); + + assertThat(created).extracting(FeldType::getDatentyp).extracting(DatentypCodeType::getListURI) + .isEqualTo("urn:xoev-de:xdomea:codeliste:datentyp"); + } + + @Test + void shouldHaveListVersionID() { + var created = create(vorgang); + + assertThat(created).extracting(FeldType::getDatentyp).extracting(DatentypCodeType::getListVersionID).isEqualTo("1.1"); + } + + } + + private FeldType create(VorgangWithEingang vorgang) { + return creator.createFeldType(vorgang).stream() + .filter(feldType -> feldType.getName().equals(ExportFelder.NAME.getName())) + .toList().get(0); + } + } + + @DisplayName("Vorname") + @Nested + class TestVorname { + + @Test + void shouldHaveName() { + var created = create(vorgang); + + assertThat(created).extracting(FeldType::getName).isEqualTo("Vorname"); + } + + @Test + void shouldHaveNotHaveBeschreibung() { + var created = create(vorgang); + + assertThat(created).extracting(FeldType::getBeschreibung).isNull(); + } + + @Test + void shouldHaveWert() { + var created = create(vorgang); + + assertThat(created).extracting(FeldType::getWert).isEqualTo(AntragstellerTestFactory.VORNAME); + } + + @Test + void shouldBeEmptyStringForNullEingang() { + var created = create(VorgangWithEingangTestFactory.createBuilder().eingang(null).build()); + + assertThat(created.getWert()).isEmpty(); + } + + @Test + void shouldBeEmptyStringForNullAntragsteller() { + var created = create( + VorgangWithEingangTestFactory.createBuilder().eingang(EingangTestFactory.createBuilder().antragsteller(null).build()) + .build()); + + assertThat(created.getWert()).isEmpty(); + } + + @Test + void shouldBeEmptyStringForNullVorname() { + var created = create( + VorgangWithEingangTestFactory.createBuilder().eingang( + EingangTestFactory.createBuilder().antragsteller(AntragstellerTestFactory.createBuilder().vorname(null).build()) + .build()) + .build()); + + assertThat(created.getWert()).isEmpty(); + } + + @DisplayName("DatentypCode") + @Nested + class TestDatentypCode { + + @Test + void shouldHaveCode() { + var created = create(vorgang); + + assertThat(created).extracting(FeldType::getDatentyp).extracting(DatentypCodeType::getCode) + .isEqualTo(DatentypCode.STRING.getCode()); + } + + @Test + void shouldHaveListURI() { + var created = create(vorgang); + + assertThat(created).extracting(FeldType::getDatentyp).extracting(DatentypCodeType::getListURI) + .isEqualTo("urn:xoev-de:xdomea:codeliste:datentyp"); + } + + @Test + void shouldHaveListVersionID() { + var created = create(vorgang); + + assertThat(created).extracting(FeldType::getDatentyp).extracting(DatentypCodeType::getListVersionID).isEqualTo("1.1"); + } + + } + + private FeldType create(VorgangWithEingang vorgang) { + return creator.createFeldType(vorgang).stream() + .filter(feldType -> feldType.getName().equals(ExportFelder.VORNAME.getName())) + .toList().get(0); + } + } + + @DisplayName("Geburtsdatum") + @Nested + class TestGeburtsdatum { + + @Test + void shouldHaveName() { + var created = create(vorgang); + + assertThat(created).extracting(FeldType::getName).isEqualTo("Geburtsdatum"); + } + + @Test + void shouldHaveNotHaveBeschreibung() { + var created = create(vorgang); + + assertThat(created).extracting(FeldType::getBeschreibung).isNull(); + } + + @Test + void shouldHaveWert() { + var created = create(vorgang); + + assertThat(created).extracting(FeldType::getWert).isEqualTo(AntragstellerTestFactory.GEBURTSDATUM_STR); + } + + @Test + void shouldBeEmptyStringForNullEingang() { + var created = create(VorgangWithEingangTestFactory.createBuilder().eingang(null).build()); + + assertThat(created.getWert()).isEmpty(); + } + + @Test + void shouldBeEmptyStringForNullAntragsteller() { + var created = create( + VorgangWithEingangTestFactory.createBuilder().eingang(EingangTestFactory.createBuilder().antragsteller(null).build()) + .build()); + + assertThat(created.getWert()).isEmpty(); + } + + @Test + void shouldBeEmptyStringForNullGeburtsdatum() { + var created = create( + VorgangWithEingangTestFactory.createBuilder().eingang( + EingangTestFactory.createBuilder().antragsteller(AntragstellerTestFactory.createBuilder().geburtsdatum(null).build()) + .build()) + .build()); + + assertThat(created.getWert()).isEmpty(); + } + + @DisplayName("DatentypCode") + @Nested + class TestDatentypCode { + + @Test + void shouldHaveCode() { + var created = create(vorgang); + + assertThat(created).extracting(FeldType::getDatentyp).extracting(DatentypCodeType::getCode) + .isEqualTo(DatentypCode.DATE.getCode()); + } + + @Test + void shouldHaveListURI() { + var created = create(vorgang); + + assertThat(created).extracting(FeldType::getDatentyp).extracting(DatentypCodeType::getListURI) + .isEqualTo("urn:xoev-de:xdomea:codeliste:datentyp"); + } + + @Test + void shouldHaveListVersionID() { + var created = create(vorgang); + + assertThat(created).extracting(FeldType::getDatentyp).extracting(DatentypCodeType::getListVersionID).isEqualTo("1.1"); + } + + } + + private FeldType create(VorgangWithEingang vorgang) { + return creator.createFeldType(vorgang).stream() + .filter(feldType -> feldType.getName().equals(ExportFelder.GEBURTSDATUM.getName())) + .toList().get(0); + } + } + + @DisplayName("Plz") + @Nested + class TestPlz { + + @Test + void shouldHaveName() { + var created = create(vorgang); + + assertThat(created).extracting(FeldType::getName).isEqualTo("PLZAntragsteller"); + } + + @Test + void shouldHaveNotHaveBeschreibung() { + var created = create(vorgang); + + assertThat(created).extracting(FeldType::getBeschreibung).isNull(); + } + + @Test + void shouldHaveWert() { + var created = create(vorgang); + + assertThat(created).extracting(FeldType::getWert).isEqualTo(AntragstellerTestFactory.PLZ); + } + + @Test + void shouldBeEmptyStringForNullEingang() { + var created = create(VorgangWithEingangTestFactory.createBuilder().eingang(null).build()); + + assertThat(created.getWert()).isEmpty(); + } + + @Test + void shouldBeEmptyStringForNullAntragsteller() { + var created = create( + VorgangWithEingangTestFactory.createBuilder().eingang(EingangTestFactory.createBuilder().antragsteller(null).build()) + .build()); + + assertThat(created.getWert()).isEmpty(); + } + + @Test + void shouldBeEmptyStringForNullPlz() { + var created = create( + VorgangWithEingangTestFactory.createBuilder().eingang( + EingangTestFactory.createBuilder().antragsteller(AntragstellerTestFactory.createBuilder().plz(null).build()) + .build()) + .build()); + + assertThat(created.getWert()).isEmpty(); + } + + @DisplayName("DatentypCode") + @Nested + class TestDatentypCode { + + @Test + void shouldHaveCode() { + var created = create(vorgang); + + assertThat(created).extracting(FeldType::getDatentyp).extracting(DatentypCodeType::getCode) + .isEqualTo(DatentypCode.STRING.getCode()); + } + + @Test + void shouldHaveListURI() { + var created = create(vorgang); + + assertThat(created).extracting(FeldType::getDatentyp).extracting(DatentypCodeType::getListURI) + .isEqualTo("urn:xoev-de:xdomea:codeliste:datentyp"); + } + + @Test + void shouldHaveListVersionID() { + var created = create(vorgang); + + assertThat(created).extracting(FeldType::getDatentyp).extracting(DatentypCodeType::getListVersionID).isEqualTo("1.1"); + } + + } + + private FeldType create(VorgangWithEingang vorgang) { + return creator.createFeldType(vorgang).stream() + .filter(feldType -> feldType.getName().equals(ExportFelder.PLZ.getName())) + .toList().get(0); + } + } + } +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/FormDataMapperTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/FormDataMapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..637eabe623a23b20161a6acf1cd103839c1bb3f1 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/FormDataMapperTest.java @@ -0,0 +1,468 @@ +package de.ozgcloud.alfa.vorgang; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.time.ZonedDateTime; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Spy; + +import de.ozgcloud.alfa.common.DateConverter; +import de.xoev.xdomea.AntragsdatenFieldType; +import de.xoev.xdomea.AntragsdatenGroupType; +import de.xoev.xdomea.AntragsdatenItemType; +import de.xoev.xdomea.AntragsdatenMultiValueFieldType; +import de.xoev.xdomea.AntragsdatenSingleValueFieldType; +import de.xoev.xdomea.DatatypeType; + +class FormDataMapperTest { + + @Spy + @InjectMocks + private FormDataMapper formDataMapper; + + @Mock + private DatatypeMapper datatypeMapper; + + @Nested + class TestToAntragsdaten { + + private final VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); + private final List<AntragsdatenFieldType> formDataItems = List.of(AntragsdatenItemTypeTestFactory.createSingleValueField(), + AntragsdatenItemTypeTestFactory.createSingleValueField()); + private final List<AntragsdatenFieldType> otherDataItems = List.of(AntragsdatenItemTypeTestFactory.createMultiValueField()); + + @Test + void shouldMapFormData() { + mockMapDataMethodsToReturnNotEmptyResults(); + + formDataMapper.toAntragsdaten(vorgang); + + verify(formDataMapper).mapFormData(vorgang); + } + + @Test + void shouldMapOtherData() { + mockMapDataMethodsToReturnNotEmptyResults(); + + formDataMapper.toAntragsdaten(vorgang); + + verify(formDataMapper).mapOtherData(vorgang); + } + + @Test + void shouldSetItemToEmptyListIfNoDataWasMapped() { + mockMapDataMethodsToReturnEmptyResults(); + + var antragsdaten = formDataMapper.toAntragsdaten(vorgang); + + assertThat(antragsdaten.getItem()).isEmpty(); + } + + @Test + void shouldAddMappedFormDataToAntragsdaten() { + mockMapDataMethodsToReturnNotEmptyResults(); + + var antragsdaten = formDataMapper.toAntragsdaten(vorgang); + + assertThat(antragsdaten.getItem()).containsAll(formDataItems); + } + + @Test + void shouldAddMappedOtherDataToAntragsdaten() { + mockMapDataMethodsToReturnNotEmptyResults(); + + var antragsdaten = formDataMapper.toAntragsdaten(vorgang); + + assertThat(antragsdaten.getItem()).containsAll(otherDataItems); + } + + private void mockMapDataMethodsToReturnNotEmptyResults() { + doReturn(formDataItems).when(formDataMapper).mapFormData(vorgang); + doReturn(otherDataItems).when(formDataMapper).mapOtherData(vorgang); + } + + private void mockMapDataMethodsToReturnEmptyResults() { + doReturn(List.of()).when(formDataMapper).mapFormData(vorgang); + doReturn(List.of()).when(formDataMapper).mapOtherData(vorgang); + } + } + + @Nested + class TestMapFormData { + + private VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); + private final List<AntragsdatenFieldType> mapDataResult = List.of(AntragsdatenItemTypeTestFactory.createSingleValueField(), + AntragsdatenItemTypeTestFactory.createSingleValueField()); + + @Test + void shouldReturnEmptyOnNullEingang() { + vorgang = VorgangWithEingangTestFactory.createBuilder().eingang(null).build(); + + var antragsdatenItemTypes = formDataMapper.mapFormData(vorgang); + + assertThat(antragsdatenItemTypes).isEmpty(); + } + + @ParameterizedTest + @NullAndEmptySource + void shouldReturnEmptyOnMissingFormData(Map<String, Object> formData) { + vorgang = VorgangWithEingangTestFactory.createBuilder() + .eingang(EingangTestFactory.createBuilder().formData(formData).build()) + .build(); + + var antragsdatenItemTypes = formDataMapper.mapFormData(vorgang); + + assertThat(antragsdatenItemTypes).isEmpty(); + } + + @Test + void shouldMapData() { + doReturn(List.of()).when(formDataMapper).mapData(EingangTestFactory.AS_MAP); + + formDataMapper.mapFormData(vorgang); + + verify(formDataMapper).mapData(EingangTestFactory.AS_MAP); + } + + @Test + void shouldReturnMappedData() { + doReturn(mapDataResult).when(formDataMapper).mapData(vorgang.getEingang().getFormData()); + + var antragsdatenItemTypes = formDataMapper.mapFormData(vorgang); + + assertThat(antragsdatenItemTypes).containsExactlyElementsOf(mapDataResult); + } + } + + @Nested + class TestMapOtherData { + + private VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); + private final List<AntragsdatenFieldType> mapDataResult = List.of(AntragsdatenItemTypeTestFactory.createSingleValueField(), + AntragsdatenItemTypeTestFactory.createSingleValueField()); + + @Test + void shouldReturnEmptyOnNullEingang() { + vorgang = VorgangWithEingangTestFactory.createBuilder().eingang(null).build(); + + var antragsdatenItemTypes = formDataMapper.mapOtherData(vorgang); + + assertThat(antragsdatenItemTypes).isEmpty(); + } + + @Test + void shouldReturnEmptyOnNullAntragsteller() { + vorgang = VorgangWithEingangTestFactory.createBuilder() + .eingang(EingangTestFactory.createBuilder().antragsteller(null).build()) + .build(); + + var antragsdatenItemTypes = formDataMapper.mapOtherData(vorgang); + + assertThat(antragsdatenItemTypes).isEmpty(); + } + + @ParameterizedTest + @NullAndEmptySource + void shouldReturnEmptyOnMissingOtherData(Map<String, Object> otherData) { + vorgang = VorgangWithEingangTestFactory.createBuilder() + .eingang(EingangTestFactory.createBuilder() + .antragsteller(AntragstellerTestFactory.createBuilder() + .otherData(otherData) + .build()) + .build()) + .build(); + + var antragsdatenItemTypes = formDataMapper.mapOtherData(vorgang); + + assertThat(antragsdatenItemTypes).isEmpty(); + } + + @Test + void shouldMapData() { + doReturn(List.of()).when(formDataMapper).mapData(AntragstellerTestFactory.OTHER_DATA); + + formDataMapper.mapOtherData(vorgang); + + verify(formDataMapper).mapData(AntragstellerTestFactory.OTHER_DATA); + } + + @Test + void shouldReturnMappedData() { + doReturn(mapDataResult).when(formDataMapper).mapData(AntragstellerTestFactory.OTHER_DATA); + + var antragsdatenItemTypes = formDataMapper.mapOtherData(vorgang); + + assertThat(antragsdatenItemTypes).containsExactlyElementsOf(mapDataResult); + } + } + + @Nested + class TestMapData { + + private final Map<String, Object> originalData = Map.of("orig-key1", "orig-value1", "orig-key2", "orig-value2"); + private final Map<String, Object> extractedData = Map.of("ext-key1", "ext-value1", "ext-key2", "ext-value2"); + private final List<AntragsdatenFieldType> mapDataResult = List.of(AntragsdatenItemTypeTestFactory.createSingleValueField(), + AntragsdatenItemTypeTestFactory.createSingleValueField()); + private MockedStatic<WrappedValueExtractor> wrappedValueExtractor; + + @BeforeEach + void init() { + wrappedValueExtractor = mockStatic(WrappedValueExtractor.class); + wrappedValueExtractor.when(() -> WrappedValueExtractor.extractWrappedValues(originalData)).thenReturn(extractedData); + doReturn(mapDataResult).when(formDataMapper).buildItems(extractedData); + } + + @AfterEach + void cleanup() { + wrappedValueExtractor.close(); + } + + @Test + void shouldCallWrappedValueExtractor() { + formDataMapper.mapData(originalData); + + wrappedValueExtractor.verify(() -> WrappedValueExtractor.extractWrappedValues(originalData)); + } + + @Test + void shouldCallBuildItemsWithExtractedData() { + formDataMapper.mapData(originalData); + + verify(formDataMapper).buildItems(extractedData); + } + + @Test + void shouldReturnBuildItemsResult() { + var mappedData = formDataMapper.mapData(originalData); + + assertThat(mappedData).isEqualTo(mapDataResult); + } + } + + @Nested + class TestBuildItems { + + private static final String FORMDATA_KEY = "key1"; + private static final String SINGLE_VALUE = "value"; + private static final List<Object> COLLECTION_OF_VALUES = List.of("value"); + private static final Map<String, Object> FORMDATA_SUBMAP = Map.of("key2", "value"); + + @Mock + private AntragsdatenItemType expectedAntragsdatenItem; + + @Test + void shouldReturnEmptyList() { + var items = formDataMapper.buildItems(Collections.emptyMap()); + + assertThat(items).isEmpty(); + } + + @Test + void shoulAddSubmap() { + doReturn(expectedAntragsdatenItem).when(formDataMapper).buildAntragsdatenGroup(FORMDATA_KEY, FORMDATA_SUBMAP); + + var items = formDataMapper.buildItems(Map.of(FORMDATA_KEY, FORMDATA_SUBMAP)); + + assertThat(items).hasSize(1).first().isEqualTo(expectedAntragsdatenItem); + } + + @Test + void shouldAddCollection() { + doReturn(expectedAntragsdatenItem).when(formDataMapper).buildMultiValueField(FORMDATA_KEY, COLLECTION_OF_VALUES); + + var items = formDataMapper.buildItems(Map.of(FORMDATA_KEY, COLLECTION_OF_VALUES)); + + assertThat(items).hasSize(1).first().isEqualTo(expectedAntragsdatenItem); + } + + @Test + void shouldAddSingleValue() { + doReturn(expectedAntragsdatenItem).when(formDataMapper).buildSingleValueField(FORMDATA_KEY, SINGLE_VALUE); + + var items = formDataMapper.buildItems(Map.of(FORMDATA_KEY, SINGLE_VALUE)); + + assertThat(items).hasSize(1).first().isEqualTo(expectedAntragsdatenItem); + } + } + + @Nested + class TestBuildAntragsdatenGroup { + + private static final String NAME = "name"; + private static final String FORMDATA_SUBMAP_VALUE = "value"; + private static final Map<String, Object> FORMDATA_SUBMAP = Map.of("key", FORMDATA_SUBMAP_VALUE); + private final List<AntragsdatenItemType> items = AntragsdatenItemTypeTestFactory.createAntragsdatenItemTypes(); + + @Test + void shouldSetName() { + mockFormatValue(); + + var antragsdatenGroup = formDataMapper.buildAntragsdatenGroup(NAME, FORMDATA_SUBMAP); + + assertThat(antragsdatenGroup.getName()).isEqualTo(NAME); + } + + @Test + void shouldSetItems() { + doReturn(items).when(formDataMapper).buildItems(FORMDATA_SUBMAP); + + var antragsdatenGroup = (AntragsdatenGroupType) formDataMapper.buildAntragsdatenGroup(NAME, FORMDATA_SUBMAP); + + assertThat(antragsdatenGroup.getItem()).containsExactlyElementsOf(items); + } + + @Test + void shouldCallBuildItems() { + mockFormatValue(); + + formDataMapper.buildAntragsdatenGroup(NAME, FORMDATA_SUBMAP); + + verify(formDataMapper).buildItems(FORMDATA_SUBMAP); + } + + private void mockFormatValue() { + when(datatypeMapper.from(FORMDATA_SUBMAP_VALUE)).thenReturn(DatatypeType.STRING); + doReturn(new Object()).when(formDataMapper).formatValue(DatatypeType.STRING, FORMDATA_SUBMAP_VALUE); + } + } + + @Nested + class TestBuildMultiValueField { + + private static final String NAME = "name"; + private static final List<String> FORMDATA_COLLECTION = List.of("value1"); + + @Test + void shouldSetName() { + when(datatypeMapper.from(FORMDATA_COLLECTION)).thenReturn(DatatypeType.STRING); + + var antragsdatenMultiValueFieldType = formDataMapper.buildMultiValueField(NAME, FORMDATA_COLLECTION); + + assertThat(antragsdatenMultiValueFieldType.getName()).isEqualTo(NAME); + } + + @Test + void shouldSetType() { + when(datatypeMapper.from(FORMDATA_COLLECTION)).thenReturn(DatatypeType.STRING); + + var antragsdatenMultiValueFieldType = (AntragsdatenFieldType) formDataMapper.buildMultiValueField(NAME, FORMDATA_COLLECTION); + + assertThat(antragsdatenMultiValueFieldType.getType()).isEqualTo(DatatypeType.STRING); + } + + @Test + void shouldSetValue() { + var formData = List.of(1, 2); + when(datatypeMapper.from(formData)).thenReturn(DatatypeType.INTEGER); + + var antragsdatenMultiValueFieldType = (AntragsdatenMultiValueFieldType) formDataMapper.buildMultiValueField(NAME, formData); + + assertThat(antragsdatenMultiValueFieldType.getValue()).containsExactlyElementsOf(formData); + } + + @Test + void shouldCallFormatValue() { + when(datatypeMapper.from(FORMDATA_COLLECTION)).thenReturn(DatatypeType.STRING); + + formDataMapper.buildMultiValueField(NAME, FORMDATA_COLLECTION); + + verify(formDataMapper).formatValue(DatatypeType.STRING, FORMDATA_COLLECTION.get(0)); + } + } + + @Nested + class TestBuildSingleValueField { + + private static final String NAME = "name"; + private static final String FORMDATA_VALUE = "value"; + + @Test + void shouldSetName() { + mockFormatValue(); + var antragsdatenSingleValueFieldType = formDataMapper.buildSingleValueField(NAME, FORMDATA_VALUE); + + assertThat(antragsdatenSingleValueFieldType.getName()).isEqualTo(NAME); + } + + @Test + void shouldSetType() { + when(datatypeMapper.from(FORMDATA_VALUE)).thenReturn(DatatypeType.STRING); + + var antragsdatenSingleValueFieldType = (AntragsdatenFieldType) formDataMapper.buildSingleValueField(NAME, FORMDATA_VALUE); + + assertThat(antragsdatenSingleValueFieldType.getType()).isEqualTo(DatatypeType.STRING); + } + + @Test + void shouldSetValue() { + mockFormatValue(); + + var antragsdatenSingleValueFieldType = (AntragsdatenSingleValueFieldType) formDataMapper.buildSingleValueField(NAME, FORMDATA_VALUE); + + assertThat(antragsdatenSingleValueFieldType.getValue()).isEqualTo(FORMDATA_VALUE); + } + + @Test + void shouldNotSetIfValueIsNull() { + formDataMapper.buildSingleValueField(NAME, null); + + verify(formDataMapper, never()).formatValue(DatatypeType.STRING, null); + } + + @Test + void shouldCallFormatValue() { + when(datatypeMapper.from(FORMDATA_VALUE)).thenReturn(DatatypeType.STRING); + + formDataMapper.buildSingleValueField(NAME, FORMDATA_VALUE); + + verify(formDataMapper).formatValue(DatatypeType.STRING, FORMDATA_VALUE); + } + + private void mockFormatValue() { + when(datatypeMapper.from(FORMDATA_VALUE)).thenReturn(DatatypeType.STRING); + doReturn(FORMDATA_VALUE).when(formDataMapper).formatValue(DatatypeType.STRING, FORMDATA_VALUE); + } + } + + @Nested + class TestFormatValue { + + @Test + void shouldFormatStringType() { + var value = formDataMapper.formatValue(DatatypeType.STRING, 1); + + assertThat(value).isEqualTo("1"); + } + + @Test + void shouldFormatDateTimeType() { + try (var dateConverter = mockStatic(DateConverter.class)) { + var dateTime = ZonedDateTime.now(); + + formDataMapper.formatValue(DatatypeType.DATETIME, dateTime); + + dateConverter.verify(() -> DateConverter.toXmlGregorianCalendar(dateTime)); + } + } + + @Test + void shouldFormatNull() { + var value = formDataMapper.formatValue(DatatypeType.STRING, null); + + assertThat(value).isEqualTo("null"); + } + } +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/GeburtTypeTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/GeburtTypeTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..1eff8f3fd7bca104f131c92d107fdebe1ed16b12 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/GeburtTypeTestFactory.java @@ -0,0 +1,10 @@ +package de.ozgcloud.alfa.vorgang; + +import de.xoev.xdomea.GeburtType; + +public class GeburtTypeTestFactory { + + public static GeburtType create() { + return new GeburtType(); + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/KontaktTypeCreatorTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/KontaktTypeCreatorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..400b0b1458aeb14c39ca8afec7fb35beb461f763 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/KontaktTypeCreatorTest.java @@ -0,0 +1,346 @@ +package de.ozgcloud.alfa.vorgang; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Optional; + +import javax.xml.datatype.XMLGregorianCalendar; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; +import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Spy; + +import de.ozgcloud.alfa.common.DateConverter; +import de.xoev.xdomea.GeburtType; +import de.xoev.xdomea.KontaktType; +import de.xoev.xdomea.NameNatuerlichePersonType; +import jakarta.annotation.Nullable; + +class KontaktTypeCreatorTest { + + @Spy + @InjectMocks + private KontaktTypeCreator creator; + + @Mock + private NameNatuerlichePersonTypeCreator nameNatuerlichePersonTypeCreator; + + @Nested + class TestCreate { + + @Nested + class TestWithAntragsteller { + + private final VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); + private final KontaktType kontaktType = KontaktTypeTestFactory.create(); + + @BeforeEach + void setUp() { + doReturn(Optional.of(vorgang.getEingang().getAntragsteller())).when(creator).getAntragstellerIfHasRequiredData(vorgang); + doReturn(kontaktType).when(creator).toKontaktType(vorgang.getEingang().getAntragsteller()); + } + + @Test + void shouldGetAntragsteller() { + callCreator(vorgang); + + verify(creator).getAntragstellerIfHasRequiredData(vorgang); + } + + @Test + void shouldMapToKontaktType() { + callCreator(vorgang); + + verify(creator).toKontaktType(vorgang.getEingang().getAntragsteller()); + } + + @Test + void shouldReturnKontakt() { + var kontakt = callCreator(vorgang); + + assertThat(kontakt).get().isEqualTo(kontaktType); + } + } + + @Nested + class TestWithoutAntragsteller { + + private final VorgangWithEingang vorgang = VorgangWithEingangTestFactory.createBuilder() + .eingang(EingangTestFactory.createBuilder().antragsteller(null).build()) + .build(); + + @BeforeEach + void setUp() { + doReturn(Optional.empty()).when(creator).getAntragstellerIfHasRequiredData(vorgang); + } + + @Test + void shouldBeEmpty() { + var kontakt = callCreator(vorgang); + + assertThat(kontakt).isEmpty(); + } + } + + private Optional<KontaktType> callCreator(VorgangWithEingang vorgang) { + return creator.create(vorgang); + } + } + + @Nested + class TestGeburtsdatumToISO { + + @Mock + private XMLGregorianCalendar geburtsdatum; + + private MockedStatic<DateConverter> dateConverter; + + private final Antragsteller antragsteller = AntragstellerTestFactory.create(); + + void setUpDateConverter() { + dateConverter = mockStatic(DateConverter.class); + dateConverter.when(() -> DateConverter.convertGermanFormatToISO(AntragstellerTestFactory.GEBURTSDATUM_STR)) + .thenReturn(Optional.of(geburtsdatum)); + } + + @BeforeEach + void setUp() { + setUpDateConverter(); + } + + @AfterEach + void cleanUp() { + dateConverter.close(); + } + + @Test + void shouldCallDateConverter() { + callGeburtsdatumToISO(antragsteller); + + dateConverter.verify(() -> DateConverter.convertGermanFormatToISO(antragsteller.getGeburtsdatum())); + } + + @Test + void shouldReturnGeburtsdatumIso() { + var result = callGeburtsdatumToISO(antragsteller); + + assertThat(result).isEqualTo(Optional.of(geburtsdatum)); + } + + private Optional<XMLGregorianCalendar> callGeburtsdatumToISO(Antragsteller antragsteller) { + return creator.geburtsdatumToISO(antragsteller); + } + + } + + @Nested + class TestToKontaktType { + + @Nested + class WhenHavingGeburtsdatum { + + @Mock + private XMLGregorianCalendar geburtsdatum; + + private MockedStatic<KontaktTypeCreator> mockStatic; + + private final VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); + private final Antragsteller antragsteller = vorgang.getEingang().getAntragsteller(); + private final NameNatuerlichePersonType nameNatuerlichePerson = NameNatuerlichePersonTypeTestFactory.create(); + private final GeburtType geburtType = GeburtTypeTestFactory.create(); + + @BeforeEach + void setUp() { + when(nameNatuerlichePersonTypeCreator.create(vorgang.getEingang().getAntragsteller())).thenReturn(nameNatuerlichePerson); + + mockStatic = mockStatic(KontaktTypeCreator.class); + mockStatic.when(() -> KontaktTypeCreator.geburtsdatumToISO(antragsteller)).thenReturn(Optional.of(geburtsdatum)); + + doReturn(geburtType).when(creator).createGeburtType(geburtsdatum); + } + + @AfterEach + void tearDown() { + mockStatic.close(); + } + + @Test + void shouldCreateNameNatuerlichePerson() { + callCreator(vorgang); + + verify(nameNatuerlichePersonTypeCreator).create(vorgang.getEingang().getAntragsteller()); + } + + @Test + void shouldHaveNameNatuerlichePerson() { + var kontakt = callCreator(vorgang); + + assertThat(kontakt.getName()).isEqualTo(nameNatuerlichePerson); + } + + @Test + void shouldCallDateConverter() { + callCreator(vorgang); + + verify(creator).createGeburtType(geburtsdatum); + } + + @Test + void shouldCreateGeburtType() { + callCreator(vorgang); + + verify(creator).createGeburtType(geburtsdatum); + } + + @Test + void shouldHaveGeburtType() { + var kontakt = callCreator(vorgang); + + assertThat(kontakt.getGeburt()).isEqualTo(geburtType); + } + } + + @Nested + class WhenHavingInvalidGeburtsdatum { + + @ParameterizedTest + @NullAndEmptySource + @ValueSource(strings = { "unreadable" }) + void shouldNotSetForInvalidGeburtsdatum(String geburtsdatum) { + var result = callCreator(createVorgangWithAntragstellerGeburtsdatum(geburtsdatum)); + + assertThat(result.getGeburt()).isNull(); + } + + @ParameterizedTest + @NullAndEmptySource + @ValueSource(strings = { "unreadable" }) + void shouldNotCallCreateGeburtType(String geburtsdatum) { + callCreator(createVorgangWithAntragstellerGeburtsdatum(geburtsdatum)); + + verify(creator, never()).createGeburtType(any()); + } + + } + + private VorgangWithEingang createVorgangWithAntragstellerGeburtsdatum(@Nullable String geburtsdatum) { + return VorgangWithEingangTestFactory.createBuilder().eingang( + EingangTestFactory.createBuilder().antragsteller( + AntragstellerTestFactory.createBuilder().geburtsdatum(geburtsdatum).build()).build()).build(); + } + + private KontaktType callCreator(VorgangWithEingang vorgang) { + return creator.toKontaktType(vorgang.getEingang().getAntragsteller()); + } + } + + @Nested + class TestCreateGeburtType { + + @Mock + private XMLGregorianCalendar geburtsdatum; + + private MockedStatic<DateConverter> dateConverter; + + @BeforeEach + void setUp() { + dateConverter = mockStatic(DateConverter.class); + dateConverter.when(() -> DateConverter.convertGermanFormatToISO(AntragstellerTestFactory.GEBURTSDATUM_STR)) + .thenReturn(Optional.of(geburtsdatum)); + } + + @AfterEach + void tearDown() { + dateConverter.close(); + } + + @Test + void shouldCreate() { + var geburtType = callCreator(geburtsdatum); + + assertThat(geburtType.getDatum()).isEqualTo(geburtsdatum); + } + + private GeburtType callCreator(XMLGregorianCalendar geburtsdatum) { + return creator.createGeburtType(geburtsdatum); + } + } + + @Nested + class TestGetAntragstellerIfHasRequiredData { + + @Mock + private XMLGregorianCalendar geburtsdatum; + + @Test + void shouldBeEmptyIfAntragstellerNull() { + var antragsteller = callCreator(buildVorgang(null)); + + assertThat(antragsteller).isEmpty(); + } + + @Test + void shouldBeEmptyIfNoneOfRequiredDataExists() { + try (var dateConverter = mockStatic(DateConverter.class)) { + dateConverter.when(() -> DateConverter.convertGermanFormatToISO(null)).thenReturn(Optional.empty()); + + var antragsteller = callCreator(buildVorgang(Antragsteller.builder().build())); + + assertThat(antragsteller).isEmpty(); + } + } + + @Test + void shouldNotBeEmptyIfHasVorname() { + var antragsteller = callCreator(buildVorgang(Antragsteller.builder().vorname(AntragstellerTestFactory.VORNAME).build())); + + assertThat(antragsteller).isNotEmpty(); + } + + @Test + void shouldNotBeEmptyIfHasNachname() { + var antragsteller = callCreator(buildVorgang(Antragsteller.builder().nachname(AntragstellerTestFactory.NACHNAME).build())); + + assertThat(antragsteller).isNotEmpty(); + } + + @Test + void shouldNotBeEmptyIfHasAnrede() { + var antragsteller = callCreator(buildVorgang(Antragsteller.builder().anrede(AntragstellerTestFactory.ANREDE).build())); + + assertThat(antragsteller).isNotEmpty(); + } + + @Test + void shouldNotBeEmptyIfHasGeburtsdatum() { + try (var dateConverter = mockStatic(DateConverter.class)) { + dateConverter.when(() -> DateConverter.convertGermanFormatToISO(AntragstellerTestFactory.GEBURTSDATUM_STR)) + .thenReturn(Optional.of(geburtsdatum)); + + var antragsteller = callCreator( + buildVorgang(Antragsteller.builder().geburtsdatum(AntragstellerTestFactory.GEBURTSDATUM_STR).build())); + + assertThat(antragsteller).isNotEmpty(); + } + } + + private Optional<Antragsteller> callCreator(VorgangWithEingang vorgang) { + return creator.getAntragstellerIfHasRequiredData(vorgang); + } + + private VorgangWithEingang buildVorgang(Antragsteller antragsteller) { + return VorgangWithEingangTestFactory.createBuilder().eingang(EingangTestFactory.createBuilder().antragsteller(antragsteller).build()) + .build(); + } + } + +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/KontaktTypeTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/KontaktTypeTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..964eb818e77f28b7fb396c3a4d1d33d0937c418f --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/KontaktTypeTestFactory.java @@ -0,0 +1,10 @@ +package de.ozgcloud.alfa.vorgang; + +import de.xoev.xdomea.KontaktType; + +public class KontaktTypeTestFactory { + + public static KontaktType create() { + return new KontaktType(); + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/KopfCreatorTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/KopfCreatorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..ad2a07d492a41a25956fe6032f940df5b82c0f9e --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/KopfCreatorTest.java @@ -0,0 +1,324 @@ +package de.ozgcloud.alfa.vorgang; + +import static de.ozgcloud.alfa.export.XdomeaPropertiesTestFactory.*; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.time.ZoneOffset; +import java.time.ZonedDateTime; + +import javax.xml.datatype.XMLGregorianCalendar; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Spy; + +import com.thedeanda.lorem.LoremIpsum; + +import de.ozgcloud.alfa.common.DateConverter; +import de.ozgcloud.alfa.common.UUIDConverter; +import de.ozgcloud.alfa.export.XdomeaProperties; +import de.xoev.xdomea.BehoerdenkennungType; +import de.xoev.xdomea.Code; +import de.xoev.xdomea.KontaktType; +import de.xoev.xdomea.NachrichtentypCodeType; +import de.xoev.xdomea.NkAbgabeType; +import de.xoev.xdomea.OrganisationseinheitType; +import de.xoev.xdomea.SystemType; + +class KopfCreatorTest { + + @Spy + @InjectMocks + private KopfCreator creator; + + @Mock + private XdomeaProperties xdomeaProperties; + + @Nested + class TestCreateKopf { + + static final ZonedDateTime CREATION_TIME = ZonedDateTime.now(); + + private MockedStatic<UUIDConverter> mockedUUIDConverter; + + @BeforeEach + void setUpUUIDMock() { + mockedUUIDConverter = mockStatic(UUIDConverter.class); + } + + @AfterEach + void tearDown() { + mockedUUIDConverter.close(); + } + + @Test + void shouldSetProcessId() { + var uuid = LoremIpsum.getInstance().getWords(1); + mockedUUIDConverter.when(() -> UUIDConverter.fromObjectId(VorgangHeaderTestFactory.ID)).thenReturn(uuid); + + var kopf = createKopf(); + + assertThat(kopf.getProzessID()).isEqualTo(uuid); + } + + @Test + void shouldSetNachrichtentyp() { + var expectedValue = new NachrichtentypCodeType(); + doReturn(expectedValue).when(creator).createNachrichtentyp(); + + var kopf = createKopf(); + + assertThat(kopf.getNachrichtentyp()).isEqualTo(expectedValue); + } + + @Test + void shouldSetErstellungszeitpunkt() { + try (var zonedDateTime = mockStatic(ZonedDateTime.class); var dateConverter = mockStatic(DateConverter.class)) { + zonedDateTime.when(() -> ZonedDateTime.now(ZoneOffset.UTC)).thenReturn(CREATION_TIME); + + var expectedValue = mock(XMLGregorianCalendar.class); + dateConverter.when(() -> DateConverter.toXmlGregorianCalendar(CREATION_TIME)).thenReturn(expectedValue); + + var kopf = createKopf(); + + assertThat(kopf.getErstellungszeitpunkt()).isEqualTo(expectedValue); + } + } + + @Test + void shouldSetAbsender() { + var expectedValue = new KontaktType(); + doReturn(expectedValue).when(creator).createAbsender(any()); + + var kopf = createKopf(); + + assertThat(kopf.getAbsender()).isEqualTo(expectedValue); + } + + @Test + void shouldSetEmpfaenger() { + var expectedValue = new KontaktType(); + doReturn(expectedValue).when(creator).createKontaktType(); + + var kopf = createKopf(); + + assertThat(kopf.getEmpfaenger()).isEqualTo(expectedValue); + } + + @Test + void shouldSetSendendesSystem() { + var sendendesSystem = new SystemType(); + doReturn(sendendesSystem).when(creator).createSendendesSystem(); + + var kopf = createKopf(); + + assertThat(kopf.getSendendesSystem()).isEqualTo(sendendesSystem); + } + + @Test + void shouldSetImportbestaetigung() { + var kopf = createKopf(); + + assertThat(kopf.isImportbestaetigung()).isTrue(); + } + + @Test + void shouldSetEmpfangsbestaetigung() { + var kopf = createKopf(); + + assertThat(kopf.isEmpfangsbestaetigung()).isTrue(); + } + + private NkAbgabeType createKopf() { + return creator.createKopf(VorgangWithEingangTestFactory.create()); + } + } + + @Nested + class TestCreateNachrichtentype { + + @Test + void shouldSetCode() { + var nachrichtentyp = creator.createNachrichtentyp(); + + assertThat(nachrichtentyp.getCode()).isEqualTo(KopfCreator.NACHRICHTENTYP_ABGABE_ABGABE_TYPE_CODE); + } + + @Test + void shouldSetListURI() { + var nachrichtentyp = creator.createNachrichtentyp(); + + assertThat(nachrichtentyp.getListURI()).isEqualTo(KopfCreator.NACHRICHTENTYP_CODE_TYPE_LIST_URI); + } + + @Test + void shouldSetListVersionID() { + var nachrichtentyp = creator.createNachrichtentyp(); + + assertThat(nachrichtentyp.getListVersionID()).isEqualTo(KopfCreator.NACHRICHTENTYP_CODE_TYPE_LIST_VERSION_ID); + } + } + + @Nested + class TestCreateAbsender { + + @Test + void shouldCallCreateKontaktType() { + creator.createAbsender(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEITEN_ID); + + verify(creator).createKontaktType(); + } + + @Test + void shouldSetOrganisationseinheitType() { + var expectedValue = new OrganisationseinheitType(); + doReturn(expectedValue).when(creator).createOrganisationseinheitType(any()); + + var absender = creator.createAbsender(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEITEN_ID); + + assertThat(absender.getOrganisationseinheit()).isEqualTo(expectedValue); + } + } + + @Nested + class TestCreateKontaktType { + + @Nested + class OnBehoerdenschluesselNotSet { + + @ParameterizedTest + @NullAndEmptySource + void shouldNotCreateBehoerdenkennung(String behoerdenschluessel) { + when(xdomeaProperties.getBehoerdenschluessel()).thenReturn(behoerdenschluessel); + + creator.createKontaktType(); + + verify(creator, never()).createBehoerdenkennung(); + } + + @ParameterizedTest + @NullAndEmptySource + void shouldNotSetBehoerdenkennung(String behoerdenschluessel) { + when(xdomeaProperties.getBehoerdenschluessel()).thenReturn(behoerdenschluessel); + + var kontaktType = creator.createKontaktType(); + + assertThat(kontaktType.getBehoerdenkennung()).isNull(); + } + } + + @Nested + class OnBehoerdenschluesselSet { + + private static final BehoerdenkennungType expectedValue = new BehoerdenkennungType(); + + @BeforeEach + void init() { + when(xdomeaProperties.getBehoerdenschluessel()).thenReturn(BEHOERDENSCHLUESSEL); + doReturn(expectedValue).when(creator).createBehoerdenkennung(); + } + + @Test + void shouldCreateBehoerdenkennung() { + creator.createKontaktType(); + + verify(creator).createBehoerdenkennung(); + } + + @Test + void shouldSetBehoerdenkennung() { + var kontaktType = creator.createKontaktType(); + + assertThat(kontaktType.getBehoerdenkennung()).isEqualTo(expectedValue); + } + } + } + + @Nested + class TestCreateOrganisationseinheitType { + + @Test + void shouldSetName() { + var organisationseinheitType = creator.createOrganisationseinheitType(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEITEN_ID); + + assertThat(organisationseinheitType.getName()).isEqualTo(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEITEN_ID); + } + } + + @Nested + class TestCreateBehoerdenkennung { + + private final Code expectedBehoerdenschluessel = new Code(); + + @BeforeEach + void init() { + doReturn(expectedBehoerdenschluessel).when(creator).createBehoerdenschluessel(); + } + + @Test + void shouldcreateBehoerdenschluessel() { + creator.createBehoerdenkennung(); + + verify(creator).createBehoerdenschluessel(); + } + + @Test + void shouldSetBehoerdenschluessel() { + var behoerdenkennungType = creator.createBehoerdenkennung(); + + assertThat(behoerdenkennungType.getBehoerdenschluessel()).isEqualTo(expectedBehoerdenschluessel); + } + } + + @Nested + class TestCreateBehoerdenschlussel { + + @BeforeEach + void init() { + when(xdomeaProperties.getBehoerdenschluessel()).thenReturn(BEHOERDENSCHLUESSEL); + when(xdomeaProperties.getBehoerdenschluesselUri()).thenReturn(BEHOERDENSCHLUESSEL_URI); + when(xdomeaProperties.getBehoerdenschluesselVersion()).thenReturn(BEHOERDENSCHLUESSEL_VERSION); + } + + @Test + void shouldSetCode() { + var behoerdenschlussel = creator.createBehoerdenschluessel(); + + assertThat(behoerdenschlussel.getCode()).isEqualTo(BEHOERDENSCHLUESSEL); + } + + @Test + void shouldSetListURI() { + var behoerdenschlussel = creator.createBehoerdenschluessel(); + + assertThat(behoerdenschlussel.getListURI()).isEqualTo(BEHOERDENSCHLUESSEL_URI); + } + + @Test + void shouldSetListVersionID() { + var behoerdenschlussel = creator.createBehoerdenschluessel(); + + assertThat(behoerdenschlussel.getListVersionID()).isEqualTo(BEHOERDENSCHLUESSEL_VERSION); + } + } + + @Nested + class TestCreateSendendesSystem { + + @Test + void shouldSetSystemName() { + var sendendesSystem = creator.createSendendesSystem(); + + assertThat(sendendesSystem.getProduktname()).isEqualTo(KopfCreator.PRODUKT_NAME); + } + } +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/NameNatuerlichePersonTypeCreatorTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/NameNatuerlichePersonTypeCreatorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..04bed62960387ee3ebef07bcc2cc59156371547d --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/NameNatuerlichePersonTypeCreatorTest.java @@ -0,0 +1,91 @@ +package de.ozgcloud.alfa.vorgang; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; + +import de.xoev.xdomea.NameNatuerlichePersonType; + +class NameNatuerlichePersonTypeCreatorTest { + + @InjectMocks + private NameNatuerlichePersonTypeCreator creator; + + @Nested + class TestCreate { + + @Test + void shouldHaveAnrede() { + var nameNatuerlichePerson = callCreator(AntragstellerTestFactory.create()); + + assertThat(nameNatuerlichePerson.getAnrede()).isEqualTo(AntragstellerTestFactory.ANREDE); + } + + @Test + void shouldHaveEmptyAnrede() { + var nameNatuerlichePerson = callCreator(AntragstellerTestFactory.createBuilder().anrede(null).build()); + + assertThat(nameNatuerlichePerson.getAnrede()).isEmpty(); + } + + @Test + void shouldHaveVorname() { + var nameNatuerlichePerson = callCreator(AntragstellerTestFactory.create()); + + assertThat(nameNatuerlichePerson.getVorname().getName()).isEqualTo(AntragstellerTestFactory.VORNAME); + } + + @Test + void shouldHaveEmptyVorname() { + var nameNatuerlichePerson = callCreator(AntragstellerTestFactory.createBuilder().vorname(null).build()); + + assertThat(nameNatuerlichePerson.getVorname().getName()).isEmpty(); + } + + @Test + void shouldHaveFamilienname() { + var nameNatuerlichePerson = callCreator(AntragstellerTestFactory.create()); + + assertThat(nameNatuerlichePerson.getFamilienname().getName()).isEqualTo(AntragstellerTestFactory.NACHNAME); + } + + @Test + void shouldHaveEmptyFamilienname() { + var nameNatuerlichePerson = callCreator(AntragstellerTestFactory.createBuilder().nachname(null).build()); + + assertThat(nameNatuerlichePerson.getFamilienname().getName()).isEmpty(); + } + + @Nested + class TestWhenNullAntragsteller { + + @Test + void shouldHaveEmptyAnrede() { + var nameNatuerlichePerson = callCreator(null); + + assertThat(nameNatuerlichePerson.getAnrede()).isEmpty(); + } + + @Test + void shouldHaveEmptyVorname() { + var nameNatuerlichePerson = callCreator(null); + + assertThat(nameNatuerlichePerson.getVorname().getName()).isEmpty(); + } + + @Test + void shouldHaveEmptyFamilienname() { + var nameNatuerlichePerson = callCreator(null); + + assertThat(nameNatuerlichePerson.getFamilienname().getName()).isEmpty(); + } + } + + private NameNatuerlichePersonType callCreator(Antragsteller antragsteller) { + return creator.create(antragsteller); + } + } + +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/NameNatuerlichePersonTypeTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/NameNatuerlichePersonTypeTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..09b861eca1903f844baf2075c85fd3f9b01219ae --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/NameNatuerlichePersonTypeTestFactory.java @@ -0,0 +1,10 @@ +package de.ozgcloud.alfa.vorgang; + +import de.xoev.xdomea.NameNatuerlichePersonType; + +public class NameNatuerlichePersonTypeTestFactory { + + public static NameNatuerlichePersonType create() { + return new NameNatuerlichePersonType(); + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/VorgangTypeCreatorTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/VorgangTypeCreatorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..47ec3761ac84e0351a9cae1dcea008c995cb80a3 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/VorgangTypeCreatorTest.java @@ -0,0 +1,197 @@ +package de.ozgcloud.alfa.vorgang; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Optional; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; + +import de.ozgcloud.alfa.common.AlfaTestUtils; +import de.ozgcloud.alfa.export.AllgemeineMetadatenTypeTestFactory; +import de.ozgcloud.alfa.export.IdentifikationObjektTypeTestFactory; +import de.xoev.xdomea.AllgemeineMetadatenType; +import de.xoev.xdomea.AnwendungsspezifischeErweiterungType; +import de.xoev.xdomea.AnwendungsspezifischeErweiterungXMLType; +import de.xoev.xdomea.IdentifikationObjektType; +import de.xoev.xdomea.KontaktType; +import de.xoev.xdomea.VorgangType; + +class VorgangTypeCreatorTest { + + @Spy + @InjectMocks + private VorgangTypeCreator creator; + + @Mock + private AnwendungsspezifischeErweiterungTypeCreator anwendungsspezifischeErweiterungTypeCreator; + + @Mock + private AnwendungsspezifischeErweiterungXMLTypeCreator anwendungsspezifischeErweiterungXMLTypeCreator; + + @Mock + private KontaktTypeCreator kontaktTypeCreator; + + @Nested + class TestCreate { + + private final VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); + + private final IdentifikationObjektType identifikationObjekt = IdentifikationObjektTypeTestFactory.create(); + private final AllgemeineMetadatenType allgemeineMetadaten = AllgemeineMetadatenTypeTestFactory.create(); + private final AnwendungsspezifischeErweiterungType anwendungsspezifischeErweiterung = AnwendungsspezifischeErweiterungTypeTestFactory.create(); + private final AnwendungsspezifischeErweiterungXMLType anwendungsspezifischeErweiterungXML = new AnwendungsspezifischeErweiterungXMLType(); + private final KontaktType kontakt = KontaktTypeTestFactory.create(); + + @BeforeEach + void init() { + doReturn(identifikationObjekt).when(creator).createIdentifikation(); + doReturn(allgemeineMetadaten).when(creator).createAllgemeineMetadaten(vorgang); + + when(anwendungsspezifischeErweiterungTypeCreator.create(vorgang)).thenReturn(anwendungsspezifischeErweiterung); + when(anwendungsspezifischeErweiterungXMLTypeCreator.create(vorgang)).thenReturn(anwendungsspezifischeErweiterungXML); + when(kontaktTypeCreator.create(vorgang)).thenReturn(Optional.of(kontakt)); + } + + @Test + void shouldCallAnwendungsspezifischeErweiterungTypeCreator() { + callCreator(); + + verify(anwendungsspezifischeErweiterungTypeCreator).create(vorgang); + } + + @Test + void shouldHaveAnwendungsspezifischeErweiterungType() { + var vorgangType = callCreator(); + + assertThat(vorgangType.getAnwendungsspezifischeErweiterung()).isEqualTo(anwendungsspezifischeErweiterung); + } + + @Test + void shouldCallAnwendungsspezifischeErweiterungXMLTypeCreator() { + callCreator(); + + verify(anwendungsspezifischeErweiterungXMLTypeCreator).create(vorgang); + } + + @Test + void shouldHaveAnwendungsspezifischeErweiterungXMLType() { + var vorgangType = callCreator(); + + assertThat(vorgangType.getAnwendungsspezifischeErweiterungXML()).isEqualTo(anwendungsspezifischeErweiterungXML); + } + + @Test + void shouldCallCreateIdentifikation() { + callCreator(); + + verify(creator).createIdentifikation(); + } + + @Test + void shouldHaveIdentifikation() { + var vorgangType = callCreator(); + + assertThat(vorgangType.getIdentifikation()).isEqualTo(identifikationObjekt); + } + + @Test + void shouldCallCreateAllgemeineMetadaten() { + callCreator(); + + verify(creator).createAllgemeineMetadaten(vorgang); + } + + @Test + void shouldHaveAllgemeineMetadaten() { + var vorgangType = callCreator(); + + assertThat(vorgangType.getAllgemeineMetadaten()).isEqualTo(allgemeineMetadaten); + } + + @Test + void shouldCallKontaktTypeCreator() { + callCreator(); + + verify(kontaktTypeCreator).create(vorgang); + } + + @Test + void shouldHaveKontakt() { + var vorgangType = callCreator(); + + assertThat(vorgangType.getKontakt()).containsExactly(kontakt); + } + + @Test + void shouldNotHaveKontakt() { + when(kontaktTypeCreator.create(vorgang)).thenReturn(Optional.empty()); + var vorgangType = callCreator(); + + assertThat(vorgangType.getKontakt()).isEmpty(); + } + + private VorgangType callCreator() { + return creator.create(vorgang); + } + } + + @Nested + class TestCreateAllgemeineMetadaten { + + private final VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); + + @Test + void shouldHaveBetreff() { + var allgemeineMetadaten = creator.createAllgemeineMetadaten(vorgang); + + assertThat(allgemeineMetadaten.getBetreff()).isEqualTo(VorgangHeaderTestFactory.NAME); + } + + @Test + void shouldHaveKennzeichen() { + var allgemeineMetadaten = creator.createAllgemeineMetadaten(vorgang); + + assertThat(allgemeineMetadaten.getKennzeichen()).isEqualTo(VorgangHeaderTestFactory.NUMMER); + } + + @Test + void shouldHaveBemerkung() { + var allgemeineMetadaten = creator.createAllgemeineMetadaten(vorgang); + + assertThat(allgemeineMetadaten.getBemerkung()).isEmpty(); + } + + @Test + void shouldHaveMedium() { + var allgemeineMetadaten = creator.createAllgemeineMetadaten(vorgang); + + assertThat(allgemeineMetadaten.getMedium().getCode()).isEqualTo(VorgangTypeCreator.ALLGEMEINE_METADATEN_MEDIUM_CODE); + } + + } + + @Nested + class TestCreateIdentifikation { + + @Test + void shouldHaveId() { + var identifikation = creator.createIdentifikation(); + + assertThat(identifikation.getID()).matches(AlfaTestUtils.UUID_REGEX); + } + + @Test + void shouldHaveNummerImUebergeordnetenContainer() { + var identifikation = creator.createIdentifikation(); + + assertThat(identifikation.getNummerImUebergeordnetenContainer()).isEqualTo(VorgangTypeCreator.NUMMER_IM_UEBERGEORDNETEN_CONTAINER); + } + } + +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/VorgangTypeTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/VorgangTypeTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..45ca4e476144809edd9e1b2a064a884bef92d68d --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/VorgangTypeTestFactory.java @@ -0,0 +1,10 @@ +package de.ozgcloud.alfa.vorgang; + +import de.xoev.xdomea.VorgangType; + +public class VorgangTypeTestFactory { + + public static VorgangType create() { + return new VorgangType(); + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/WrappedValueExtractorITCase.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/WrappedValueExtractorITCase.java new file mode 100644 index 0000000000000000000000000000000000000000..2235bb23d85ac3e6a812a49aa88b2ec107a32ea7 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/WrappedValueExtractorITCase.java @@ -0,0 +1,55 @@ +package de.ozgcloud.alfa.vorgang; + +import static de.ozgcloud.alfa.vorgang.WrappedValueExtractor.*; +import static org.assertj.core.api.Assertions.*; + +import java.util.Map; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +public class WrappedValueExtractorITCase { + + @Nested + class TestExtractWrappedValues { + + @Test + void shouldPreserveWrapperKeyWithoutParent() { + Map<String, Object> formData = Map.of(WRAPPER_KEY, "Kiel"); + + var formDataWithoutValueKeys = WrappedValueExtractor.extractWrappedValues(formData); + + assertThat(formDataWithoutValueKeys).isEqualTo(formData); + } + + @Test + void shouldEliminateWrapperKeyWithoutSiblings() { + Map<String, Object> formData = Map.of("ort", Map.of(WRAPPER_KEY, "Kiel")); + Map<String, Object> expected = Map.of("ort", "Kiel"); + + var formDataWithoutValueKeys = WrappedValueExtractor.extractWrappedValues(formData); + + assertThat(formDataWithoutValueKeys).isEqualTo(expected); + } + + @Test + void shouldPreserveWrapperKeyIfHasSiblings() { + Map<String, Object> formData = Map.of("ort", Map.of(WRAPPER_KEY, "Kiel", "value2", "Kiel")); + + var formDataWithoutValueKeys = WrappedValueExtractor.extractWrappedValues(formData); + + assertThat(formDataWithoutValueKeys).isEqualTo(formData); + } + + @Test + void shouldPreserveNonWrapperKeys() { + Map<String, Object> formData = Map.of("empfangendestelle", + Map.of(WRAPPER_KEY, Map.of("OrganisationseinheitenAuswahl", Map.of(WRAPPER_KEY, "123456")))); + Map<String, Object> expected = Map.of("empfangendestelle", Map.of("OrganisationseinheitenAuswahl", "123456")); + + var formDataWithoutValueKeys = WrappedValueExtractor.extractWrappedValues(formData); + + assertThat(formDataWithoutValueKeys).isEqualTo(expected); + } + } +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/WrappedValueExtractorTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/WrappedValueExtractorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..419c371d6aaf4f8a75904ec986814ffa4187881b --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/WrappedValueExtractorTest.java @@ -0,0 +1,176 @@ +package de.ozgcloud.alfa.vorgang; + +import static de.ozgcloud.alfa.vorgang.WrappedValueExtractor.*; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Map; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.MockedStatic; + +public class WrappedValueExtractorTest { + + @Nested + class TestExtractWrappedValues { + + private static final String KEY1 = "key1"; + private static final String KEY2 = "key2"; + private static final String KEY3 = "key3"; + + @Captor + private ArgumentCaptor<Object> valueCaptor; + private final Map<String, Object> originalData = Map.of(KEY1, "value1", KEY2, true, KEY3, 100); + private final Map<String, Object> extractedData = Map.of(KEY1, "extracted1", KEY2, "extracted2", KEY3, "extracted3"); + + @Test + void shouldCallReplaceWrappedValueWithDirectValue() { + try (MockedStatic<WrappedValueExtractor> wrappedValueExtractor = mockStatic(WrappedValueExtractor.class)) { + unmockMethodUnderTest(wrappedValueExtractor); + + WrappedValueExtractor.extractWrappedValues(originalData); + + wrappedValueExtractor.verify(() -> WrappedValueExtractor.replaceWrappedValueWithDirectValue(valueCaptor.capture()), times( + originalData.size())); + assertThat(valueCaptor.getAllValues()).containsExactlyElementsOf(originalData.values()); + } + } + + @Test + void shouldReturnMapWithReplacedValues() { + try (MockedStatic<WrappedValueExtractor> wrappedValueExtractor = mockStatic(WrappedValueExtractor.class)) { + unmockMethodUnderTest(wrappedValueExtractor); + wrappedValueExtractor.when(() -> WrappedValueExtractor.replaceWrappedValueWithDirectValue(originalData.get(KEY1))).thenReturn(extractedData.get(KEY1)); + wrappedValueExtractor.when(() -> WrappedValueExtractor.replaceWrappedValueWithDirectValue(originalData.get(KEY2))).thenReturn(extractedData.get(KEY2)); + wrappedValueExtractor.when(() -> WrappedValueExtractor.replaceWrappedValueWithDirectValue(originalData.get(KEY3))).thenReturn(extractedData.get(KEY3)); + + var result = WrappedValueExtractor.extractWrappedValues(originalData); + + assertThat(result).isEqualTo(extractedData); + } + } + + private void unmockMethodUnderTest(MockedStatic<WrappedValueExtractor> wrappedValueExtractor) { + wrappedValueExtractor.when(() -> WrappedValueExtractor.extractWrappedValues(any())).thenCallRealMethod(); + } + } + + @Nested + class TestReplaceWrappedValueWithDirectValue { + + private final String simpleValue = "simple value"; + private final Map<String, Object> mapValue = Map.of("key1", "value1", "key2", "value2"); + private final Map<String, Object> wrappedValue = Map.of(WRAPPER_KEY, "value1"); + + @Test + void shouldReturnValue() { + try (MockedStatic<WrappedValueExtractor> wrappedValueExtractor = mockStatic(WrappedValueExtractor.class)) { + unmockMethodUnderTest(wrappedValueExtractor); + + var result = WrappedValueExtractor.replaceWrappedValueWithDirectValue(simpleValue); + + assertThat(result).isEqualTo(simpleValue); + } + } + + @Test + void shouldCallIsWrappedValue() { + try (MockedStatic<WrappedValueExtractor> wrappedValueExtractor = mockStatic(WrappedValueExtractor.class)) { + unmockMethodUnderTest(wrappedValueExtractor); + + WrappedValueExtractor.replaceWrappedValueWithDirectValue(mapValue); + + wrappedValueExtractor.verify(() -> WrappedValueExtractor.isWrappedValue(mapValue)); + } + } + + @Test + void shouldCallItself() { + try (MockedStatic<WrappedValueExtractor> wrappedValueExtractor = mockStatic(WrappedValueExtractor.class)) { + unmockMethodUnderTest(wrappedValueExtractor); + wrappedValueExtractor.when(() -> WrappedValueExtractor.isWrappedValue(wrappedValue)).thenReturn(true); + + WrappedValueExtractor.replaceWrappedValueWithDirectValue(wrappedValue); + + wrappedValueExtractor.verify(() -> WrappedValueExtractor.replaceWrappedValueWithDirectValue(wrappedValue.get(WRAPPER_KEY))); + } + } + + @Test + void shouldReturnResultOfCallingItself() { + try (MockedStatic<WrappedValueExtractor> wrappedValueExtractor = mockStatic(WrappedValueExtractor.class)) { + unmockMethodUnderTest(wrappedValueExtractor); + wrappedValueExtractor.when(() -> WrappedValueExtractor.isWrappedValue(wrappedValue)).thenReturn(true); + + var result = WrappedValueExtractor.replaceWrappedValueWithDirectValue(wrappedValue); + + assertThat(result).isEqualTo(wrappedValue.get(WRAPPER_KEY)); + } + } + + @Test + void shouldCallExtractWrappedValues() { + try (MockedStatic<WrappedValueExtractor> wrappedValueExtractor = mockStatic(WrappedValueExtractor.class)) { + unmockMethodUnderTest(wrappedValueExtractor); + wrappedValueExtractor.when(() -> WrappedValueExtractor.isWrappedValue(mapValue)).thenReturn(false); + + WrappedValueExtractor.replaceWrappedValueWithDirectValue(mapValue); + + wrappedValueExtractor.verify(() -> WrappedValueExtractor.extractWrappedValues(mapValue)); + } + } + + @Test + void shouldReturnResultOfExtractWrappedValues() { + final Map<String, Object> extractVrappedValuesResult = Map.of("resultKey", "resultValue"); + try (MockedStatic<WrappedValueExtractor> wrappedValueExtractor = mockStatic(WrappedValueExtractor.class)) { + unmockMethodUnderTest(wrappedValueExtractor); + wrappedValueExtractor.when(() -> WrappedValueExtractor.isWrappedValue(mapValue)).thenReturn(false); + wrappedValueExtractor.when(() -> WrappedValueExtractor.extractWrappedValues(any())).thenReturn(extractVrappedValuesResult); + + var result = WrappedValueExtractor.replaceWrappedValueWithDirectValue(mapValue); + + assertThat(result).isEqualTo(extractVrappedValuesResult); + } + } + + private void unmockMethodUnderTest(MockedStatic<WrappedValueExtractor> wrappedValueExtractor) { + wrappedValueExtractor.when(() -> WrappedValueExtractor.replaceWrappedValueWithDirectValue(any())).thenCallRealMethod(); + } + } + + @Nested + class TestIsWrappedValue { + + @Test + void shouldReturnTrueIfWrapped() { + var result = WrappedValueExtractor.isWrappedValue(Map.of(WRAPPER_KEY, "value1")); + + assertThat(result).isTrue(); + } + + @Test + void shouldReturnFalseIfHasMultipleEntries() { + var result = WrappedValueExtractor.isWrappedValue(Map.of(WRAPPER_KEY, "value1", "key2", "value2")); + + assertThat(result).isFalse(); + } + + @Test + void shouldReturnFalseIfNotWrapped() { + var result = WrappedValueExtractor.isWrappedValue(Map.of("key1", "value1")); + + assertThat(result).isFalse(); + } + + @Test + void shouldReturnFalseIfEmpty() { + var result = WrappedValueExtractor.isWrappedValue(Map.of()); + + assertThat(result).isFalse(); + } + } +} diff --git a/alfa-xdomea/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension b/alfa-xdomea/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension new file mode 100644 index 0000000000000000000000000000000000000000..79b126e6cdb86bec1f4f08c205de8961bde1934a --- /dev/null +++ b/alfa-xdomea/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension @@ -0,0 +1 @@ +org.mockito.junit.jupiter.MockitoExtension \ No newline at end of file diff --git a/alfa-xdomea/src/test/resources/application-itcase.yaml b/alfa-xdomea/src/test/resources/application-itcase.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c6f85b1e94d61d1ee6c5992b97cbac70b7260e24 --- /dev/null +++ b/alfa-xdomea/src/test/resources/application-itcase.yaml @@ -0,0 +1,5 @@ +ozgcloud: + xdomea: + behoerdenschluessel: ABC + behoerdenschluesselUri: http://meine.behoer.de + behoerdenschluesselVersion: 1.0.15b \ No newline at end of file diff --git a/alfa-xdomea/src/test/resources/junit-platform.properties b/alfa-xdomea/src/test/resources/junit-platform.properties new file mode 100644 index 0000000000000000000000000000000000000000..1cebb76d5a58ac034b2627d12411d82d1e85821e --- /dev/null +++ b/alfa-xdomea/src/test/resources/junit-platform.properties @@ -0,0 +1 @@ +junit.jupiter.extensions.autodetection.enabled = true \ No newline at end of file diff --git a/alfa-xdomea/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/alfa-xdomea/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 0000000000000000000000000000000000000000..ca6ee9cea8ec189a088d50559325d4e84ff8ad09 --- /dev/null +++ b/alfa-xdomea/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file diff --git a/pom.xml b/pom.xml index e1e8d8fc73a898af035a72f0cee6eed9f3c434a8..b94a9aeca3933d3690cf4dfe516a54515f43d240 100644 --- a/pom.xml +++ b/pom.xml @@ -42,6 +42,7 @@ <modules> <module>alfa-client</module> <module>alfa-server</module> + <module>alfa-xdomea</module> <module>alfa-service</module> </modules> @@ -54,7 +55,6 @@ <ozgcloud-common-pdf.version>3.0.1</ozgcloud-common-pdf.version> <user-manager.version>2.8.0</user-manager.version> <zufi-manager.version>1.5.0</zufi-manager.version> - <archive-manager.version>0.1.0-SNAPSHOT</archive-manager.version> <spring-cloud-config-client.version>4.1.3</spring-cloud-config-client.version> <!-- TODO: die Version über ozgcloud-common ziehen --> @@ -140,11 +140,6 @@ </exclusion> </exclusions> </dependency> - <dependency> - <groupId>de.ozgcloud.archive</groupId> - <artifactId>archive-manager-interface</artifactId> - <version>${archive-manager.version}</version> - </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> diff --git a/release-startdev.sh b/release-startdev.sh index 960b59df8fb9a765221405fe7166050d4a5d6e9d..1a0b61139aba8cad4e1b13f77bcb9f9382148b8c 100755 --- a/release-startdev.sh +++ b/release-startdev.sh @@ -17,7 +17,8 @@ echo # PROJECTS="pom.xml:main alfa-service/pom.xml:parent - alfa-server/pom.xml:parent + alfa-xdomea/pom.xml:parent + alfa-server/pom.xml:parent alfa-client/pom.xml:parent " for PROJECT in $PROJECTS; diff --git a/src/main/helm/templates/_helpers.tpl b/src/main/helm/templates/_helpers.tpl index d372c36a7bf03ba41f97df64697eda36d8ecf120..35797e518111a96685b6f6af018c73ac614727df 100644 --- a/src/main/helm/templates/_helpers.tpl +++ b/src/main/helm/templates/_helpers.tpl @@ -53,10 +53,6 @@ app.kubernetes.io/namespace: {{ include "app.namespace" . }} {{ printf "dns:///%s.%s:9090" ( coalesce .Values.vorgangManagerName "vorgang-manager" ) .Release.Namespace | replace "+" "_" | trunc 63 | trimSuffix "-" }} {{- end -}} -{{- define "app.grpc_client_archive_manager_address" -}} -{{ printf "dns:///%s.%s:9090" ( coalesce .Values.archiveManagerName "vorgang-manager" ) .Release.Namespace | replace "+" "_" | trunc 63 | trimSuffix "-" }} -{{- end -}} - {{- define "app.grpc_client_user-manager_address" -}} {{ printf "dns:///%s.%s:9000" ( coalesce .Values.usermanagerName "user-manager" ) .Release.Namespace }} {{- end -}} diff --git a/src/main/helm/templates/deployment.yaml b/src/main/helm/templates/deployment.yaml index 91335d88865df4177cdc971a2585193d9811cf61..585408d9e599665f5ac4777b117051c601ebeaec 100644 --- a/src/main/helm/templates/deployment.yaml +++ b/src/main/helm/templates/deployment.yaml @@ -78,10 +78,6 @@ spec: value: {{ include "app.grpc_client_user-manager_address" . }} - name: grpc_client_user-manager_negotiationType value: {{ (.Values.userManager).grpcClientNegotiationType | default "TLS" }} - - name: grpc_client_archive-manager_address - value: {{ include "app.grpc_client_archive_manager_address" . }} - - name: grpc_client_archive-manager_negotiationType - value: {{ (.Values.archiveManager).grpcClientNegotiationType | default "TLS" }} - name: spring_profiles_active value: {{ include "app.envSpringProfiles" . }} - name: keycloak_realm diff --git a/src/test/helm/deployment_defaults_env_test.yaml b/src/test/helm/deployment_defaults_env_test.yaml index ec868f133c64569d5ddf0cf73c8dc2c1cde3e9b8..9bdb30b9dcc2621609553f09a9fcefb01a63fcfa 100644 --- a/src/test/helm/deployment_defaults_env_test.yaml +++ b/src/test/helm/deployment_defaults_env_test.yaml @@ -54,11 +54,6 @@ tests: content: name: grpc_client_user-manager_address value: dns:///user-manager.sh-helm-test:9000 - - contains: - path: spec.template.spec.containers[0].env - content: - name: grpc_client_archive-manager_address - value: dns:///vorgang-manager.sh-helm-test:9090 - it: should have service binding root set: @@ -155,21 +150,3 @@ tests: content: name: grpc_client_vorgang-manager_negotiationType value: TLS - - - it: should set archive-manager negotiationType plaintext - set: - archiveManager.grpcClientNegotiationType: PLAINTEXT - asserts: - - contains: - path: spec.template.spec.containers[0].env - content: - name: grpc_client_archive-manager_negotiationType - value: PLAINTEXT - - - it: should contain default archive-manager negotiationType tls - asserts: - - contains: - path: spec.template.spec.containers[0].env - content: - name: grpc_client_archive-manager_negotiationType - value: TLS