Giter VIP home page Giter VIP logo

wearefrank / zaakbrug Goto Github PK

View Code? Open in Web Editor NEW
5.0 6.0 5.0 94.83 MB

An app for Dutch municipalities that supports the transition from "zaak- en documentatieservices" (zds) to "zaakgericht werken" (zgw).

Home Page: https://zaakbrug.nl

License: European Union Public License 1.2

XSLT 91.86% Smarty 0.90% Shell 0.47% Dockerfile 0.76% JavaScript 1.63% MDX 1.57% TypeScript 2.14% CSS 0.67%
frank frank-framework zds zgw zaakbrug

zaakbrug's Introduction

zaakbrug-banner-small.png

Successor of Open-ZaakBrug, an app for Dutch municipalities that supports the transition from "zaak- en documentatieservices" (zds) to "zaakgericht werken" (zgw).

Dutch municipalities provide services that are delivered many times. An example of such a service is to provide passports. This service is delivered many times because each citizen needs a passport or an ID card. An instance of a service that is provided multiple times is referred by the Dutch word "zaak" (case).

There is a new specification named "zaakgericht werken" (zgw) for case register systems. Zgw is part of the Common Ground specification for software used by Dutch municipalities. Zgw will replace an old specification called "zaak- en documentatieservices" (zds). The municipality of Súdwest Fryslân wants to migrate to the zgw standard without having to invest in zds interfaces. To this end, the municipality has built the system Open-ZaakBrug (brug means bridge). It acts as an interface between a zgw case register system on the one hand and zds systems connecting to the case register system on the other hand. The Open-ZaakBrug source code is hosted on GitHub Sudwest-Fryslan/OpenZaakBrug. For a comparison of zgw and zds see API-standaarden voor Zaakgericht Werken vergeleken met de Zaak- en Documentservices.

This project, ZaakBrug, is meant to be a successor of Open-ZaakBrug. It leverages the Frank!Framework and its debugger Ladybug. The debugger shows for each incoming request which steps are executed to process the message. If there are errors, this information can be used for easy debugging. ZaakBrug does not only connect zds systems with case register system OpenZaak, but with any case register system that implements zgw.

Starting ZaakBrug

Development in Visual Studio Code

When you are doing development work on ZaakBrug, you may want to boot it using WeAreFrank!'s Frank!Runner. When you use the Frank!Runner, you can boot ZaakBrug from within your Integrated Development Environment (IDE); we support the two IDEs Visual Studio Code and Eclipse.

To boot ZaakBrug using the Frank!Runner, you need version control system Git. Choose or create some empty directory in which you can clone Git repositories. For the sake of the argument, we assume it to be work. Please do the following:

  1. Open a command prompt and change directory to work.

  2. Clone the Frank!Runner: git clone https://github.com/ibissource/frank-runner.

  3. Clone ZaakBrug: git clone https://github.com/ibissource/zaakbrug.

  4. Start the Frank!Runner with one of the boot scripts in the Frank!Runner checkout directory: start.bat or restart.bat for Windows or start.sh or restart.sh for Linux or Mac. This step lets the Frank!Runner download Ant, a build tool for Java applications.

  5. Configure your IDE as described in the Frank!Runner's documentation, see https://github.com/ibissource/frank-runner. For VS Code, these instructions let you install the Task Explorer plugin by Scott Meesseman.

  6. If your IDE is Visual Studio Code, you should have a link to open ZaakBrug, see number 2 in the figure below. Use the menu option number 1 to get access to the link. Click the link to open ZaakBrug using the Frank!Runner.

    antJobVsCode.jpg

Running with Docker

In a production environment it is recommended to run ZaakBrug with Docker. Ensure that Docker is installed on your computer and proceed as follows:

  1. Clone GitHub project https://github.com/ibissource/zaakbrug if you have not done so yet.

  2. Open a command prompt and change directory to the checkout directory.

  3. Build your Docker image from the source code using a command like the following: docker build -t zaakbrug:test ..

  4. Run ZaakBrug using a command like the following: docker run -p 8080:8080 -e dtap.stage=LOC --name=zaakbrug zaakbrug:test.

  5. To see the user interface of ZaakBrug, open a webbrowser and visit http://localhost:8080.

  6. ZaakBrug provides an automated health check. You can run it with the following command: docker inspect --format='{{json .State.Health.Status}}' zaakbrug.

    Warning: In a DOS command window under Windows, the string after --format= has to be enclosed between "". You have docker inspect --format="{{json .State.Health.Status}}" zaakbrug.

    Info: If you know the Frank!Framework, the following information may be helpful. If the health check produces the value healthy, it is guarenteed that all adapters in the Frank configuration have booted without errors.

Configuration

Zaak- and Documentidentificatie

The properties zaakbrug.zgw.zaak-identificatie-template and zaakbrug.zgw.document-identificatie-template can be configured to specify how the zaak- and documentidentificatie should be generated and formatted. The syntax for variable substitution is as follows {[variable-name][:formatting-string]}

Variable Description
id Auto-incrementing identifier with 'D' as formatting option, indicating the amount of digits.
Example: {id:D5} with id-123 will result in '00123'.
datetime The current date and time with '[Y]' as formatting option, according to XSLT datetime formatting.
Examples:
  • {datetime:[Y]} with datetime=14-03-2023 produces '2023'
  • {datetime:[Y0001]} with datetime=14-03-2023 produces '2023'
  • {datetime:[Y][M][D]} with datetime=14-03-2023 produces '2023314'
  • {datetime:[Y0001][M01][D01]} with datetime=14-03-2023 produces '20230314'
  • {datetime:[Y][M01][D]} with datetime=14-03-2023 produces '20230314'

Translation Profiles

Closing zaak with updateZaak message

Closing a zaak' refers to the action of setting the EindStatus (Last Status) to the zaak itself. EindStatus refers to a status created with a Status Type where the 'isEindStatus' field is set to true. When a zaak has such EindStatus then it means the zaak is closed. To be able to close a zaak, the zaak must have a Resultaat(Result) value as well. In case the zaak doesn't have a Resultaat value, then one of the dummy values in Profile.json file (if exists) will be used as explained below.

There are three ways of closing a zaak.

  1. Setting EindDatum (End Date) When EindDatum field is set in updateZaak message and if the zaak already has a Resultaat then EindStatus (Last Status) is automatically set to the zaak so the zaak is closed. However, if the zaak doesn't have a Resultaat when EindDatum field is set, then a Resultaat with the dummy value under 'endCaseEndDate' in Profile.json file (translation profile) is set to zaak. After that, EindStatus is automatically set to the zaak so the zaak is closed. 'endCaseEndDate' property should be at the same level of the 'zaakTypeIdentificatie' property which is the Zaaktype of the zaak in the profile so that it could be fetched by using the 'zaakTypeIdentificatie' from Profile.json file.

  2. Setting EindStatus(LastStatus) There is no specifically EindStatus field in updateZaak (or any other) message. However, the fields under 'Heeft' element in updateZaak message are used to create an EindStatus. When an updateZaak message is sent and if the 'Heeft' element has the required fields and if the zaak has a Resultaat, then EindStatus is created and set to the Zaak so the zaak is closed. In case the zaak doesn't have a Resultaat, the dummy value under 'endDateAndResultLastStatus' in Profile.json file is used to create one. 'endDateAndResultLastStatus' property should be at the same level of the 'zaakTypeIdentificatie' property which is the Zaaktype of the zaak in the profile so that it could be fetched by using the 'zaakTypeIdentificatie' from Profile.json file.

  3. Setting both EindDatum (End Date) and EindStatus(Last Status) In case of having both EindDatum and EindStatus(meaning having required fields under 'Heeft' element) in updateZaak message, first EindStatus path is used to close a zaak. If Zaak doesn't have a Resultaat and if there is no dummy value under 'endDateAndResultLastStatus' in Profile.json then EindDatum path is used to close the zaak.

Closing zaak with actualiseerZaakStatus message (Configurable)

A zaak can also be closed with actualiseerZaakStatus message with eindStatus in it unless the ignoreEindStatusInActualiseerZaakStatus property is set true in profiles.json file (translation profile).

As default the property is falsy so a zaak can be close by actualiseerZaakStatus. If ignoring the eindStatus in actualiseerZaakStatus message is wanted, then add the property ignoreEindStatusInActualiseerZaakStatus with value "true" into the profileDefaults section in profiles.json file. Then zaak closure with actualiseerZaakStatus message will not be allowed for any zaaktype.

It is also possible to add ignoreEindStatusInActualiseerZaakStatus property to a specific zaaktype as well if different behaviour is desired.

If a zaaktype is not listed in profiles or the profile of a specific zaaktype doesn't have the ignoreEindStatusInActualiseerZaakStatus property, then always the one in profileDefaults section is used. If ignoreEindStatusInActualiseerZaakStatus is not set at all in any section of profile.json file, then it will be counted as false so zaak closure with actualiseerZaakStatus message will be allowed.

Example configuration:

{
    "profileDefaults": {
        "ignoreEindStatusInActualiseerZaakStatus": "true"
    },
    "profile": [
        {
            "zaakTypeIdentificatie": "B9999",
            "endCaseEndDate": {
                "coalesceResultaat": "Onbekend"
            },
            "endDateAndResultLastStatus": {
                "coalesceResultaat": "Onbekend"
            }
        },
        {
            "zaakTypeIdentificatie": "B1210",
            "ignoreEindStatusInActualiseerZaakStatus": "false",
            "endDateAndResultLastStatus": {
                "coalesceResultaat":"Vergunningvrij" 
            }
        },
        {
            "zaakTypeIdentificatie": "B1026",
            "endCaseEndDate": {
                "coalesceResultaat": "Toegekend"
            }
        }
    ]
}

Will result in:

{
    "profile": [
        {
            "zaakTypeIdentificatie": "B9999",
            "ignoreEindStatusInActualiseerZaakStatus": "true",
            "endCaseEndDate": {
                "coalesceResultaat": "Onbekend"
            },
            "endDateAndResultLastStatus": {
                "coalesceResultaat": "Onbekend"
            }
        },
        {
            "zaakTypeIdentificatie": "B1210",
            "ignoreEindStatusInActualiseerZaakStatus": "false",
            "endDateAndResultLastStatus": {
                "coalesceResultaat":"Vergunningvrij" 
            }
        },
        {
            "zaakTypeIdentificatie": "B1026",
            "ignoreEindStatusInActualiseerZaakStatus": "true",
            "endCaseEndDate": {
                "coalesceResultaat": "Toegekend"
            }
        }
    ]
}

Profile Defaults

Profile defaults can be used to configure common translation profile settings. The settings configured in the profileDefaults section are applied to all zaaktypen. When a regular translation profile for a specific zaaktype is also configured, the settings are merged together. The more specific per zaaktype translation profile will always override any overlapping settings from the profileDefaults section. Items in array's like valuesOverrides will be combined instead, unless there is an overlapping key. Here the more specific per zaaktype translation profile will also always override any overlapping keys from the ones in the profileDefaults section.

For example, the following configuration:

{
    "profileDefaults": {
        "endCaseEndDate": {
            "coalesceResultaat": "Onbekend"
        },
        "valueOverrides": [
            {
                "key": "zgw.zaken-api.zaken.zaak.toelichting",
                "value": "toelichting from profileDefaults"
            }
        ]
    },
    "profile": [
        {
            "zaakTypeIdentificatie": "B9999",
            "endDateAndResultLastStatus": {
                "coalesceResultaat": "Onbekend"
            },
            "valueOverrides": [
                {
                    "key": "zgw.zaken-api.zaken.zaak.communicatiekanaal",
                    "value": "http://example.com"
                }
            ]
        },
        {
            "zaakTypeIdentificatie": "B1026",
            "endCaseEndDate": {
                "coalesceResultaat": "Toegekend"
            },
            "valueOverrides": [
                {
                    "key": "zgw.zaken-api.zaken.zaak.toelichting",
                    "value": "toelichting from specific translation profile"
                }
            ]
        }
    ]
}

Will result in:

{
    "profile": [
        {
            "zaakTypeIdentificatie": "B9999",
            // highlight-start
            "endCaseEndDate": {
                "coalesceResultaat": "Onbekend",
            },
            // highlight-end
            "endDateAndResultLastStatus": {
                "coalesceResultaat": "Onbekend"
            },
            "valueOverrides": [
                // highlight-start
                {
                    "key": "zgw.zaken-api.zaken.zaak.toelichting",
                    "value": "toelichting from profileDefaults"
                },
                // // highlight-end
                {
                    "key": "zgw.zaken-api.zaken.zaak.communicatiekanaal",
                    "value": "http://example.com"
                }
            ]
        },
        {
            "zaakTypeIdentificatie": "B1026",
            "endCaseEndDate": {
                // highlight-next-line
                "coalesceResultaat": "Toegekend"
            },
            "valueOverrides": [
                {
                    "key": "zgw.zaken-api.zaken.zaak.toelichting",
                    // highlight-next-line
                    "value": "toelichting from specific translation profile"
                }
            ]
        }
    ]
}

Value Overrides

The translations from ZDS/StUF to ZGW are made to be as neutral as possible. With value overrides it is possible to diverge from the generic translation defaults or add static properties.

Value overrides can be configured in src/main/configurations/Translate/profiles.json or in the zaakbrug.profiles section of the Helm chart.

The keys for the the different properties can be deducted from the OpenApi specification of the API's. The keys follow the following format: zgw.<api-name>.<collection-name>.<object-name>.<property>. For example the key for the zaak property betalingsindicatie would be: zgw.zaken-api.zaken.zaak.betalingsindicatie. In the translation profile this would look like this:

{
    "profile": [
        {
            "zaakTypeIdentificatie": "example",
            "valueOverrides": [
                {
                    "key": "zgw.zaken-api.zaken.zaak.betalingsindicatie",
                    "value": "nvt"
                }
            ]
        }
    ]
}

A value override is only applied if the property's value after the translation from ZDS/StUF to ZGW is not present, empty string or null.

Currently this feature implemented for:

  • (zaken-api) zaak

Local Development Docusaurus

  1. Navigate to "docusaurus" subfolder with cd ./docusaurus.
  2. Install dependencies with npm install.
  3. Serve Docusaurus webserver locally with docusaurus start. By default it is served at http://localhost:3000/.
  4. Basic guide on how to use Docusaurus and a styleguide can be found at ./docusaurus/docs/_README.md.

zaakbrug's People

Contributors

bibi0803 avatar checkiecheck avatar delanowaf avatar dependabot[bot] avatar diedekerkhof avatar htou avatar jacodg avatar mericakgul avatar mhdirkse avatar mikeerkemey avatar mlenterman avatar nielslam avatar philipsens avatar rayetsena avatar sauringithub1 avatar semantic-release-bot avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

zaakbrug's Issues

Error message not returned to CLO when Open Zaak returns error message in for each pipe with parallel="false"

For example with ForEachChildElementPipe PostStatusIterator in https://github.com/ibissource/zaakbrug/blob/master/src/main/configurations/Translate/Configuration_SetResultaatAndStatus.xml we have seen sender PostZgwStatus return:

{"type":"https://xxx/ref/fouten/ValidationError/","code":"invalid","title":"Invalid input.","status":400,"detail":"","instance":"urn:uuid:xxx","invalidParams":[{"name":"nonFieldErrors","code":"archiefactiedatum-error","reason":"Geen besluiten aan zaak gekoppeld om brondatum uit af te leiden."}]}

With parallel="true" this doesn't throw an exception and at the end a SOAP message is returned: that doesn't contain an error message

Expand zaak- en document identification generation with the ability to use the date and time

Blocked by #31

At the minimum the ability to handle d, dd, M, MM, yy, yyyy, HH, mm, ss

{[variable-name][:formatting-string]}

Examples:
{datetime:yyyy-MM-dd} -> Current date&time formatted as 2023-02-03
{datetime:HH:mm} -> Current date&time formatted as 12:03
ZK{datetime:yyyy}-{id:D5} -> Composite with the year being 2023 and id being 123, it would produce "ZK2023-00123"

As reference for syntax: https://learn.microsoft.com/en-us/dotnet/standard/base-types/composite-formatting
As reference for syntax with date&time following ISO standard: https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings

Maybe there are better alternatives or standards?

Errors thrown in ForEachChildElementPipe should not be ignored

Currently a F!F bug is causing ForEachChildElementPipe to ignore errors in the child adapters when parallel=true. The most important part is to make sure that errors are not ignored anymore. A quickfix is to simply set parallel to false, but that impacts performances. Preferably find a way to keep parallel=true.

Mike had a possible solution in mind for this.

Make it possible to configure "Globals" and "Profiles" directly from within the values.yaml

Now the user has to make his own configMap with the data for Globals.json and Profiles.json.

That wouldn't be the case if we create a configMap within the chart. This is possible by doing something like:

{{ include "my_tpl" . | fromYaml | toJson }}

Then the user can add all info to the values instead of creating a json and putting it into a configMap.

Example:

{
    "organizations": [
		{
			"gemeenteNaam": "Haarlem",
			"gemeenteCode": "0392",
			"RSIN": "001005650"
		}
	],
    "rolMapping": {
        "heeftBetrekkingOp": "BetrekkingOp",
        "heeftAlsBelanghebbende": "Belanghebbende",
        "heeftAlsInitiator": "Initiator",
        "heeftAlsUitvoerende": "Uitvoerende",
        "heeftAlsVerantwoordelijke": "Verantwoordelijke",
        "heeftAlsGemachtigde": "Gemachtigde",
        "heeftAlsOverigBetrokkene": "OverigeBetrokkene"
    }
}

Would change to:

      globalsConfigMap:
        organizations:
          - gemeenteNaam: "Haarlem"
            gemeenteCode: "0392"
            RSIN: "001005650"
        rolMapping:
          heeftBetrekkingOp: "BetrekkingOp",
          heeftAlsBelanghebbende: "Belanghebbende",
          heeftAlsInitiator: "Initiator",
          heeftAlsUitvoerende: "Uitvoerende",
          heeftAlsVerantwoordelijke: "Verantwoordelijke",
          heeftAlsGemachtigde: "Gemachtigde",
          heeftAlsOverigBetrokkene: "OverigeBetrokkene"

ZaakBrug does not correctly relate zaken to each other

This issue was discovered while debugging the Gidso SoapUI test. That test makes a zaak. Then it creates another zaak and includes in that other zaak that it is related to the first. When you look in OpenZaak after the test, you see that the relation between the two zaken is not present.

zaakBrug lost connection with Postgresql (and didn't reconnect)

On two occasions this week we had a "this connection has been closed" in ladybug calling when calling "genereerDocumentIdentificatie_Di02". Resulting in an erromessage to the calling application.

Generating a zaakIdentificatie had the same problem.

One incident on our test-environment and one incident on our production environment.

The problem was mitigated by restarting the server.

Other servers in the same Azure cloud using Postgresql never seem to have these issues.

Due to the immediate restart, logs are not available any more.

Create CONTRIBUTING.md with instructions on how to configure a local environment

With Docker-Compose:

  • How to run the Docker-Compose. Use docker-compose build or docker-compose up --build.
  • Configure credentials in OpenZaak
  • Import and publish catalog in OpenZaak
  • Import SoapUI end-to-end project
  • Validate environment by running the SoapUI test-suites against ZaakBrug

With Frank!Runner:

  • How to run OpenZaak docker-compose
  • Configure credentials in OpenZaak
  • Import and publish catalog in OpenZaak
  • Configure DeploymentSpecifics zgw base url to OpenZaak
  • Run the Frank!Runner with ZaakBrug
  • Import SoapUI end-to-end project
  • Validate environment by running the SoapUI test-suites against ZaakBrug

Add the ability to generate zaak and documenten identifiers from a configurable interpolated string with variables

At the minimum the ability to replace the current mechanism with something like zaak-identificatie="1900{id:D5}"

{[variable-name][:formatting-string]}

{id:D5} -> auto-incrementing id formatted as decimal with fixed 5 digits (123 == 00123)

As reference I'm currently using: https://learn.microsoft.com/en-us/dotnet/standard/base-types/composite-formatting
Maybe there are better alternatives or standards?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.