pkONE® : BLPK Documentation

1. MapForce Integration

1.1. Overview

BLPK mutation validation

1.2. MapForce communication

1.2.1. MapForce engine (testing)

For testing the engine is provided as download, having to use licenses (valid for 30 days).

MapForce engine structure

Different approaches so far:

  1. Install full MapForce service (download, via docker, …​): This is cumbersome for testing, need license every time we need to test.

  2. New and preferred: Use the MapForce API implementation (only REST service) with or without the contract to have just this for local testing. This would just be easy REST API mocking without any hassle. No need even for docker, just mocking according APIs.

1.3. Use cases

1.3.1. AG Upload

Some AGs deliver mutations including "old" mutations of the current year, some only deliver "new".

  • Verarbeitung: Mit jeder Uebergabe an MF wird ein neuer Verarbeitungslauf gestartet (pro AG / pro Lauf neue Nummer)

  • Scharfschaltung: Pro AG, ueber Konfig

1.3.1.1. Schritte
  1. pkONE generating Mutation in DB, trigger Event / Service

  2. Trasmit/Uebermittlung an Mapforce per REST API

  3. pkONE REST API: response from server

  4. Ueberschreiben der Mutationen, anhand von mapforce: Setzen Status, neues Feld (systeminfo): setzen Bemerkung

  5. Ueberpruefung des Ergebnis der Meldungsverarbeitung/Validierung (MapForce) durch AG

  6. Benachrichtigungs-Mail (event-triggered) mit Status: Text Erledigt / Review (Batch ID = Verarbeitungslauf, 500 Mut sind in einem VerLauf)

    1. Nachricht an AG

    2. Nachricht an SB

    3. Variante mit Statistiks: Records verarbeitet, records skipped, …​

    4. Luxus: Highchart png

Asynchrone Verarbeitung (hohe Datenmengen): Job duration 3 secs - 6 hours

1.3.2. AG Online Mutation

Synchron variant with direct feedback in the response: FeedbackMeldung von MF direkt in pkONE (gelbes Feedback wie bisher) und x-Iterationen durch Benutzer. Connection timeout: if service is not reachable, use normal processing like now, with pkONE validation if MF not available.

State S_VALIDATED/ATTENTION: Text as returned by MF in new field. Additional: "please wait, wir werden weitere Validierung vornehmen"

State S_REJECTED/S_SKIPPED: Text as returned by MF in new field. Additional: "contact your BLPK contact in case of …​ for REOPENING"

Synchrone Verarbeitung: Request duration: 5 secs

1.3.3. Generelle Bemerkungen zum Austausch

Tel. FS 22.01.2026

  • MF schickt STM Daten in Mutationen IMMER zurueck

  • MutationsUpload: Mutationen koennen mehrere Typen (LOM und STM) beinhalten, werden in pkONE 1:1 (mehrere Typen pro Mutation moeglich) abgebildet

  • EIN mit allem schicken (STM), schickt mit STM zurueck

  • AUS mit allem schicken (STM), schickt mit STM zurueck

  • Bemerkungen

    • 3 mal EIN an MF, gibt 3 mal gleiches Ergebnis (nicht verarbeitet, wie in pkONE)

    • Texte werden "uebersetzt" zurueckgegeben, 1 Zeile

Tel. FS 27.04.2026

  • STM: Nicht an MF senden, sondern direkt intern verarbeiten

1.3.3.1. Changes gegenueber Standardverarbeitung

Die Mutationsverarbeitung, die fuer Clan genutzt wird, soll 1:1 uebernommen werden. Es gibt aber folgende Ausnahmen/Anpassungen, da die Mutationsmeldungen an MF in pkONE verarbeitet werden, die Meldungen an Clan jedoch "fire and forget" sind.

  • LOM: STM bei LOM an Clan geloescht, an MF gemeldet (muessen STM zurueckgegeben werden, sonst geloescht in pkONE)

  • STM: in MF geprueft wenn enthalten (PLZ geprueft, separate Liste erstellt). Wenn nicht korrekt, dann mit entsprechender Meldung an pkONE zurueck

  • AUS: Grund an Clan nur 1 liefern, an MF (1 = AUS, 2 = Pensionierung) 1:1 uebergeben

1.3.4. pkONE States

pkONE state sync/async Existing Final state Description

NEW

sync

yes

no

Mutation is recorded and saved

SUBMITTED

sync

yes

no

Mutation is submitted / resubmitted from the AG, after changes/verification pass on mutation to BLPK

VALIDATING

async

no

no

State after upload mutations into pkONE - subject to validation or in validation (e.g. Mapforce). Mutation is not visible for employer. Result is either state PENDING, CONFIRMED or REJECTED.

PENDING

async

yes

no

- Sync mode: Mutation is waiting for further processing after creation (FUM) or validation.
- Async mode: Mutation needs review by employer (other semantic than NEW)

CONFIRMED

sync

yes

no

Mutation was confirmed after evaluation and can be checked by the contact or transferred

MANUAL_PROCESS / DONE

sync

yes

yes

Mutation has to be manually completed

MARKED_AS_PROCESSED

sync

yes

yes

Mutation was manually completed

TRANSFERED

sync

yes

yes

Message transfer to backend was executed

REJECTED

sync

yes

yes

Mutation was rejected as being not valid

1.3.5. Mapforce States

MF state pkONE state SB/Contact interaction State after interaction Action after processing Visible by AG Description Text returned

-

VALIDATING

-

-

-

no

Mutation was handed over to MF, waiting for feedback

CONFIRMED

NEW

-

-

-

yes

Mutation confirmed, ready for further processing

ALREADY_PROCESSED

MARKED_AS_PROCESSED

-

-

-

no

Mutation has already been reported (UNI Basel, Canton), e.g. delivered in a previous upload

FEEDBACK

NEW

-

-

-

yes

Mutation must be revised by the employer

"…​ please review your changes"

ATTENTION

MANUAL_PROCESS

Make further decision

MANUAL_PROCESS

Notify CONTACT?

yes

CONTACT must make decision/revise, will not be transferred to backend, but manually processed

"…​ please wait, wir werden weitere Validierungen vornehmen"

SKIPPED

REJECTED

Reopen

NEW

-

yes

Mutation was ignored (insurance not possible, report irrelevant). Option: reopen by SB, status NEW. Visible also for the employer/AG

REJECTED

REJECTED

-

-

-

yes

Mutation rejected, will be kept in state

"…​ contact your BLPK contact in case of …​ for REOPENING"

Upload:

  • MF SKIPPED/REJECTED: Unsinnige Mutationen (Lohn gleich wie bisher, etc.) → forward to REJECTED

  • MF ALREADY_PROCESSED: Mutationen, die immer wieder, das ganze Jahr ueber geschickt werden → forward to MARKED_AS_PROCESSED

1.3.6. pkONE / mapforce State diagram

MapForce integration states

1.4. pkONE changes

  • Field validationAnnotation: Storing the feedback from the MapForce engine

  • New state PENDING: Verify existing logic if there is any logic that does an automatic state change from NEW to CONFIRMED. This would have to be changed from PENDING to CONFIRMED as the AG first has to submit/hand in the mutation.

  • New state VALIDATING

1.5. Besprechung Fabian 23. April

  • Vorgehen am Anfang: Manuelle Eingabe und Tests um MF testen zu koennen

  • Fazit: Ist sehr aufwendig und zeitraubend (oftmals nur 500 error), Mutationen noch nicht implementiert, geaenderte Implementierungen

  • Erkenntnis: RegressionsTests bei Aenderungen in pkONE/MapForce-Service sind manuell nicht machbar

    • Groesste Herausforderung: manuelle User-Eingabe vs. maschine-produziertem FileUpload von Grosskunden, gutes Beispiel: DepartmentNummer nur numerisch

      • Feld vergessen, Typo → es kommt nur 500 Error

    • Uebergabe Array/Liste Mutationen in sync-mode hat nicht geklappt

  • Deswegen

    • Einfuehrung von Validation-Flows: External vs Internal Flow

    • Test-Automation:

      • Definition der Faelle in Markdown

      • Automatisierter Vergleich von JSON Strukturen expected vs actual

  • Problem 500 Error - Loesungen

    • Pre-Validierung in pkONE

      • Da pkONE UI korrekte Stelle (File Upload von HR ist schon vor-geprueft)

      • Neben Ext/Internal Flow einen Pre-Validation-Flow

      • Da evtl. spaeter eh Abloesung durch pkONE

      • Verwaltung Test-Cases in Markdown

    • Loesung: Einbindung von BLPK custom rules, werden vor der Validierung ausgefuehrt: Ticket BLPK customer business rules

    • Anreicherung MF Service

1.6. Referencing tickets

1.7. History

Date Description Author

08.10.2025

Format, toc, …​

M. Meixner

06.10.2025

Added action column to the table

S. Faur

03.10.2025

Adding pkONE changes, MF / pkONE states

M. Meixner

03.10.2025

Update/consolidate states, add use cases sync/async processing, new fields

M. Meixner

03.10.2025

Added mapforce engine integration, REST API

M. Meixner

03.10.2025

Copy from ticket

M. Meixner

1.8. JSON specification

Following the specification of the JSON used to exchange data between pkONE and MF:

  • All values should be string, no typed values

  • Upper-/lowercase does not matter

  • Date notation dd.mm.jjjj

  • MF only providing content type text/plain instead of application/json

{
  "title": "mutations",
  "description": "array von mutations-objekten im lowercase-format",
  "type": "array",
  "items": {
    "additionalProperties": true,
    "properties": {
      "mutation_id": { "type": "string" },
      "mandant": { "type": "string", "description" : "mandantNo, e.g. 85000.1" },
      "department": { "type": "string", "description" : "Abteilung"  },
      "penum": { "type": "string", "description" : "pkNo" },
      "penum2": { "type": "string", "description" : "personalNo AG" },
      "last_name": { "type": "string" },
      "first_name": { "type": "string" },
      "ahvnr": { "type": "string" },
      "sovnr": { "type": "string" },
      "birth_date": { "type": "string" },
      "civil_status": { "type": "string" },
      "gender": { "type": "string" },
      "salutation": { "type": "string", "description": "Anrede" },
      "language": { "type": "string", "description": "als Code geliefert" },
      "entry_date": { "type": "string", "description": "Eintrittsdatum Firma" },
      "entry_date_vs": { "type": "string", "description": "Eintrittsdatum Versicherung" },
      "exit_date": { "type": "string" },
      "exit_reason": { "type": "string", "description": "1 = Austritt, (2 = Pensionierung)" },
      "valuta": { "type": "string", "description": "Valuta Datum" },
      "total_earnings": { "type": "string", "description": "grossIncome, Gehalt" },
      "wage_type": { "type": "string", "description" : "salaryType, immer 1" },
      "bonus": { "type": "string" },
      "workload": { "type": "string", "description" : "Pensum" },
      "inability_degree": { "type": "string", "description" : "iv Grad" },
      "disability_degree": { "type": "string", "description" : "Grad Arbeitsunfaehigkeit" },
      "fil1cd": { "type": "string" },
      "adr1": { "type": "string" },
      "adr2": { "type": "string" },
      "adr3": { "type": "string" },
      "country_code": { "type": "string" },
      "postal_code": { "type": "string" },
      "city": { "type": "string" },
      "marriage_date": { "type": "string" },
      "mutation_type": { "type": "string" },
      "mutation_comment": { "type": "string", "description" : "Bemerkungen vom User" },
      "mutation_system_info": { "type": "string", "description" : "MF Rueckmeldung fuer Benutzer -> UI" },
      "mutation_state": { "type": "string" },
      "correlationId": { "type": "string" },
      "uuid": { "type": "string" }
    }
  }
}

2. ContributionCalculation

Specs describes the process of ContributionCalculation processing and distribution.

2.1. Overview

  • Relevant job: TransferFakturaGenerationJob

  • Relevant directory: /opt/pkonedirectories/blpk/transfer/faktura

  • Distribution: /opt/pkonedirectories/blpk/transfer/faktura -> /opt/pkonedirectories/blpk/distribution

2.2. Mapping Table

The following mapping table describes the mapping of types (Beitragsart) in the BLPK system across different clients.

For new customer 82200 internal Beitragsarten are used (no mapping defined). Those are skipped range between P9000 and P9200! They are logged, counted and printed.

Beitragsart BLPK Bezeichnung Umsetzung für Mandant 85020.1 Umsetzung für Mandant 85040.2 Umsetzung für Mandant 85000.1 Umsetzung für Mandant 90300.1 Umsetzung für Mandant 82200.1

P10

Sparbeitrag AN

6005

6005 unverän

6511

7010

6520

P100

VK AG

6007

6007 unverän

8548

7081

8524

P105

VK z.L. AN bei UBU

6024

6024

6522

7082

6525

P110

VK AN

6029

6013

6548

7080

6524

P20

Risikoprämie AN

6000

6000 unverän

6550

7000

6522

P40

Sparbeitrag AG

6006

6006 unverän

8501

7011

8520

P45

Sparbeitrag AG z.L. AN bei UBU

6022

6022

6521

7014

6521

P50

Risikoprämie AG

6001

6001 unverän

8510

7001

8522

P55

Risikobeitrag AG z.L. AN bei UBU

6023

6023

6551

7004

6523

P701

Beitrag Teuerungsfonds AG

6008

6008

8530

7084

8527

P705

Beitrag Teuerungsfonds z.L. AN bei UBU

6025

6025

6523

7083

6527

P800

Sanierungsbeitrag AN

6021

6002

6560

7085

6528

P801

Sanierungsbeitrag AG

6027

6009

8531

7087

8528

P805

Sanierungsbeitrag AG z.L. AN bei UBU

6026

6026

6524

7086

6529

P920

Umlagebeitrag AG

6030

6027

8575

7089

8526

P925

Umlagebeitrag AG z.L. AN

6031

6028

6525

7088

6526

Beitragsarten nicht relevant (skipped)

/opt/pkonedirectories/blpk/transfer/faktura:test# less 20260123-09.01.32_ContributionCalculation_82200.1_Export.txt.log | grep "o mapping" | sort|uniq
No mapping for beitragsArt: P9000
No mapping for beitragsArt: P9001
No mapping for beitragsArt: P9010
No mapping for beitragsArt: P9011
No mapping for beitragsArt: P9020
No mapping for beitragsArt: P9021
No mapping for beitragsArt: P9030
No mapping for beitragsArt: P9031
No mapping for beitragsArt: P9040
No mapping for beitragsArt: P9041
No mapping for beitragsArt: P9050
No mapping for beitragsArt: P9051
No mapping for beitragsArt: P9060
No mapping for beitragsArt: P9061

2.3. Version History

Date Description Author

2025-11-12

Initial table

Paul

2.4. Referencing Tickets

2.5. Notes

  • "unverän" indicates unchanged mapping from previous mandate version

  • "z.L." = zulasten (at the expense of)

  • "AN" = Arbeitnehmer (employee)

  • "AG" = Arbeitgeber (employer)

  • "UBU" = Überobligatorisch (above mandatory)

  • "VK" = Verwaltungskosten (administrative costs)

3. Interfaces MutationUpload

Table of contents

3.1. Interface KPD

3.1.1. File configuration

<file-configuration>
    <!-- KPD: 85020.1 -->
    <file-name>\d{8}-\d\d.\d\d.\d\d_Upload_(85020\.0|85020\.1)\.(txt|csv)</file-name>

    <!-- Parser types, s. DataCrawler.EntryParser -->
    <processor-type>4</processor-type>
    <processor-configuration>
        <entry>
            <entry-type>REPEATABLE</entry-type>
            <check-for-binary>true</check-for-binary>
            <encoding>ISO-8859-1</encoding>
            <!-- projector-command-id has to be a unique text identifier for the used command -->
            <projector>
                <projector-id>standard</projector-id>
                <projector-class>
                    ch.optimizeit.datacrawlerblpk.projection.NonKantonMutationProjector
                </projector-class>
            </projector>

            <!-- field list -->
            <field id="1">
                <field-name>bookingYear</field-name>
                <field-type>not-used</field-type>
                <field-regex>\d{4}</field-regex>
            </field>
            <field id="2">
                <field-name>bookingMonth</field-name>
                <field-type>not-used</field-type>
                <field-regex>\d{2}</field-regex>
            </field>
            <field id="3">
                <field-name>mandantNo</field-name>
                <field-type>string</field-type>
                <field-regex>(.{7})</field-regex>
            </field>
            <field id="4">
                <field-name>departmentNo</field-name>
                <field-type>string</field-type>
                <field-regex>(\d{6})</field-regex>
            </field>
            <field id="5">
                <field-name>personalNo</field-name>
                <field-type>string</field-type>
                <field-regex>(.{18})</field-regex>
            </field>
            <field id="6">
                <field-name>pkNo</field-name>
                <field-type>string</field-type>
                <field-regex>(\d{6})</field-regex>
            </field>
            <field id="7">
                <field-name>ahvNo</field-name>
                <field-type>string</field-type>
                <field-regex>(\d{11}|\s{11})</field-regex>
            </field>
            <field id="8">
                <field-name>mutationsCode</field-name>
                <field-type>not-used</field-type>
                <field-regex>\d{2}</field-regex>
            </field>
            <field id="9">
                <field-name>lastName</field-name>
                <field-type>string</field-type>
                <field-regex>(.{25})</field-regex>
            </field>
            <field id="10">
                <field-name>firstName</field-name>
                <field-type>string</field-type>
                <field-regex>(.{20})</field-regex>
            </field>
            <field id="11">
                <field-name>valutaDate</field-name>
                <field-type>bigEndianDate</field-type>
                <field-regex>(\d{8})</field-regex>
            </field>
            <field id="12">
                <field-name>grossIncome</field-name>
                <field-type>double</field-type>
                <field-regex>(\d{7})</field-regex>
            </field>
            <field id="13">
                <field-name>pensum</field-name>
                <field-type>decimal3</field-type>
                <field-regex>(\d{6})</field-regex>
            </field>
            <field id="14">
                <field-name>versicherungsTyp</field-name>
                <field-type>not-used</field-type>
                <field-regex>[\d\s]{1}</field-regex>
            </field>
            <field id="15">
                <field-name>birthday</field-name>
                <field-type>bigEndianDate</field-type>
                <field-regex>(\d{8})</field-regex>
            </field>
            <field id="16">
                <field-name>sex</field-name>
                <field-type>integer</field-type>
                <field-regex>(\d{1})</field-regex>
            </field>
            <field id="17">
                <field-name>civilStatus</field-name>
                <field-type>integer</field-type>
                <field-regex>(\d{1})</field-regex>
            </field>
            <field id="18">
                <field-name>entryDate</field-name>
                <field-type>bigEndianDate</field-type>
                <field-regex>(\d{8})</field-regex>
            </field>
            <field id="19">
                <field-name>austrittsGrund</field-name>
                <field-type>not-used</field-type>
                <field-regex>.{1}</field-regex>
            </field>
            <field id="20">
                <field-name>street1</field-name>
                <field-type>string</field-type>
                <field-regex>(.{35})</field-regex>
            </field>
            <field id="21">
                <field-name>street2</field-name>
                <field-type>string</field-type>
                <field-regex>(.{35})</field-regex>
            </field>
            <field id="22">
                <field-name>zip</field-name>
                <field-type>string</field-type>
                <field-regex>(.{8})</field-regex>
            </field>
            <field id="23">
                <field-name>city</field-name>
                <field-type>string</field-type>
                <field-regex>(.{26})</field-regex>
            </field>
            <field id="24">
                <field-name>countryCode</field-name>
                <field-type>string</field-type>
                <field-regex>(.{3})</field-regex>
            </field>
            <field id="25">
                <field-name>spouseLastname</field-name>
                <field-type>not-used</field-type>
                <field-regex>.{25}</field-regex>
            </field>
            <field id="26">
                <field-name>spouseFirstname</field-name>
                <field-type>not-used</field-type>
                <field-regex>.{20}</field-regex>
            </field>
            <field id="27">
                <field-name>spouseBirthday</field-name>
                <field-type>not-used</field-type>
                <field-regex>.{8}</field-regex>
            </field>
            <field id="28">
                <field-name>marriageDate</field-name>
                <field-type>bigEndianDate</field-type>
                <field-regex>(\d{8})</field-regex>
            </field>
            <field id="29">
                <field-name>numberChildren</field-name>
                <field-type>not-used</field-type>
                <field-regex>.{2}</field-regex>
            </field>
            <field id="30">
                <field-name>internalNumber</field-name>
                <field-type>not-used</field-type>
                <field-regex>.{5}</field-regex>
            </field>
            <field id="31">
                <field-name>exitDate</field-name>
                <field-type>bigEndianDate</field-type>
                <field-regex>(\d{8})</field-regex>
            </field>
            <field id="32">
                <field-name>sovNo</field-name>
                <field-type>string</field-type>
                <field-regex>(\d{13})</field-regex>
            </field>

            <!-- specify output builder name -->
            <!-- multipleEntry processor can have multiple csv builder, therefore a list of builders must be
                passed to the processor -->
            <outputbuilder>
                <outputbuilder-id>
                    clanOnlineMutationOutputBuilder
                </outputbuilder-id>
            </outputbuilder>
        </entry>
    </processor-configuration>

    <!-- distributor configuration -->
    <distributor-configuration>
        <distributor-id>fileDistributor</distributor-id>
        <destination-filename-strategies>
            <destination-filename-strategy>
                <strategy>change-suffix</strategy>
                <parameter>.txt</parameter>
                <parameter>.csv</parameter>
            </destination-filename-strategy>
        </destination-filename-strategies>
    </distributor-configuration>
</file-configuration>

3.1.2. Projector

    public String doProjection(HashMap<String, Object> fieldsAndValues)
{
    String explanation = null;

    // Add exit reason = 1 if an exitdate exists
    Date exitDate = (Date) fieldsAndValues.get("exitDate");
    if (exitDate != null)
    {
        fieldsAndValues.put("exitReason", "1");
    }
    else
    {
        fieldsAndValues.put("exitReason", "");
    }

    // Check if the record adresses the correct mandantNo. If not return with
    // error message.
    if ((explanation = ProjectionHelper.checkMandantNoValid(fieldsAndValues)) != null)
    {
        return explanation;
    }

    // Add sovnr for future compatibility
    String sovNo = (String) fieldsAndValues.get("sovNo");
    if (sovNo.equals("0") || sovNo.equals("0000000000000"))
    {
        fieldsAndValues.put("sovNo", "");
    }

    // Map civil status
    // AGs Non Kanton: 1=ledig, 2=verheiratet, 3=geschieden, 4=verwitwet,
    // 5=Konkubinate, 6=eingetragene Partnerschaft
    // Clan: 0=ledig, 1=verheiratet, 2=geschieden, 3=verwitwet, 4=getrennt,
    // 6=eingetragene Partnerschaft, 7=aufgeloeste Partnerschaft, 8=Konkubinat
    int civilStatus = ((Integer) fieldsAndValues.get("civilStatus")).intValue();

    _log.trace("Received civilStatus: {} ", civilStatus);

    switch (civilStatus)
    {
        case 1:
        case 2:
        case 3:
        case 4:
            civilStatus--;
            break;

        case 5:
            civilStatus = 8;
            break;

        default:
            explanation = "No mapping for civilStatus: " + civilStatus;
            _log.error(explanation);
            break;
    }
    if (_log.isTraceEnabled())
        _log.trace("Computed civilStatus: " + civilStatus);
    fieldsAndValues.put("civilStatus", Integer.valueOf(civilStatus));

    // TODO: Map country code
    // ONLY for testing purposes. In production the ISO standard should be used
    // so no mapping must be applied.
    String countryCode = (String) fieldsAndValues.get("countryCode");
    if (countryCode.equalsIgnoreCase("deu") || countryCode.equalsIgnoreCase("fra"))
    {
        if (_log.isTraceEnabled())
            _log.trace("Received countryCode: " + countryCode);
        countryCode = countryCode.substring(0, 2);
        if (_log.isTraceEnabled())
            _log.trace("Computed countryCode: " + countryCode);
        fieldsAndValues.put("countryCode", countryCode);
    }

    // Add Anrede/title
    fieldsAndValues.put("title", fieldsAndValues.get("sex"));

    // Add valutaDate if it is null
    Date valutaDate = (Date) fieldsAndValues.get("valutaDate");
    if (valutaDate == null)
    {
        Calendar cal = Calendar.getInstance();
        cal.clear();
        cal.set(2008, 0, 1);
        valutaDate = cal.getTime();
        fieldsAndValues.put("valutaDate", valutaDate);
    }

    // Add Sprache/language
    fieldsAndValues.put("language", Integer.valueOf(1));

    // Add entryInsuranceDate = entryDate
    fieldsAndValues.put("entryInsuranceDate", fieldsAndValues.get("entryDate"));

    // Add salaryType
    fieldsAndValues.put("salaryType", "1");

    // Add missing fields not provided by source
    fieldsAndValues.put("street3", "");

    // Added as of version 10.7.0
    fieldsAndValues.put("divorceDateNew", "");
    fieldsAndValues.put("annotations", "");

    // Added as of version 10.7.8
    fieldsAndValues.put("unpaidHolidaysFrom", "");
    fieldsAndValues.put("unpaidHolidaysTo", "");

    // Newly required field, but not delivered via interface
    fieldsAndValues.put("ivGrad", null);
    fieldsAndValues.put("code", null);

3.1.3. Output builder

<outputbuilder-configuration>
    <!-- field delimiter -->
    <field-delimiter>;</field-delimiter>

    <!-- fields -->
    <field id="1">
        <field-name>mandantNo</field-name>
        <field-type>string</field-type>
    </field>
    <field id="2">
        <field-name>departmentNo</field-name>
        <field-type>string</field-type>
    </field>
    <field id="3">
        <field-name>pkNo</field-name>
        <field-type>string</field-type>
    </field>
    <field id="4">
        <field-name>personalNo</field-name>
        <field-type>string</field-type>
    </field>
    <field id="5">
        <field-name>lastName</field-name>
        <field-type>string</field-type>
    </field>
    <field id="6">
        <field-name>firstName</field-name>
        <field-type>string</field-type>
    </field>
    <field id="7">
        <field-name>ahvNo</field-name>
        <field-type>string</field-type>
    </field>
    <field id="8">
        <field-name>sovNo</field-name>
        <field-type>string</field-type>
    </field>
    <field id="9">
        <field-name>birthday</field-name>
        <field-type>germanLittleEndianDate</field-type>
    </field>
    <field id="10">
        <field-name>civilStatus</field-name>
        <field-type>string</field-type>
    </field>
    <field id="11">
        <field-name>sex</field-name>
        <field-type>string</field-type>
    </field>
    <field id="12">
        <field-name>title</field-name>
        <field-type>string</field-type>
    </field>
    <field id="13">
        <field-name>language</field-name>
        <field-type>string</field-type>
    </field>
    <field id="14">
        <field-name>entryDate</field-name>
        <field-type>germanLittleEndianDate</field-type>
    </field>
    <field id="15">
        <field-name>entryInsuranceDate</field-name>
        <field-type>germanLittleEndianDate</field-type>
    </field>
    <field id="16">
        <field-name>exitDate</field-name>
        <field-type>germanLittleEndianDate</field-type>
    </field>
    <field id="17">
        <field-name>exitReason</field-name>
        <field-type>string</field-type>
    </field>
    <field id="18">
        <field-name>valutaDate</field-name>
        <field-type>germanLittleEndianDate</field-type>
    </field>
    <field id="19">
        <field-name>grossIncome</field-name>
        <field-type>double</field-type>
    </field>
    <field id="20">
        <field-name>salaryType</field-name>
        <field-type>string</field-type>
    </field>
    <field id="21">
        <field-name>bonus</field-name>
        <field-type>empty</field-type>
    </field>
    <field id="22">
        <field-name>pensum</field-name>
        <field-type>double</field-type>
    </field>
    <field id="23">
        <field-name>vspbgrd</field-name>
        <field-type>empty</field-type>
    </field>
    <field id="24">
        <field-name>ivGrad</field-name>
        <field-type>double</field-type>
    </field>
    <field id="25">
        <field-name>fil1cd</field-name>
        <field-type>empty</field-type>
    </field>
    <field id="26">
        <field-name>street1</field-name>
        <field-type>string</field-type>
    </field>
    <field id="27">
        <field-name>street2</field-name>
        <field-type>string</field-type>
    </field>
    <field id="28">
        <field-name>street3</field-name>
        <field-type>string</field-type>
    </field>
    <field id="29">
        <field-name>countryCode</field-name>
        <field-type>string</field-type>
    </field>
    <field id="30">
        <field-name>zip</field-name>
        <field-type>string</field-type>
    </field>
    <field id="31">
        <field-name>city</field-name>
        <field-type>string</field-type>
    </field>
    <field id="32">
        <field-name>marriageDate</field-name>
        <field-type>germanLittleEndianDate</field-type>
    </field>
    <field id="33">
        <field-name>code</field-name>
        <field-type>string</field-type>
    </field>
    <field id="34">
        <field-name>divorceDateNew</field-name>
        <field-type>germanLittleEndianDate</field-type>
    </field>
    <field id="35">
        <field-name>annotations</field-name>
        <field-type>string</field-type>
    </field>
    <!-- Added as of version 10.7.8 -->
    <field id="36">
        <field-name>unpaidHolidaysFrom</field-name>
        <field-type>string</field-type>
    </field>
    <field id="37">
        <field-name>unpaidHolidaysTo</field-name>
        <field-type>string</field-type>
    </field>
</outputbuilder-configuration>

4. Beitrags- und Faktura-Simulation

4.1. Overview

This document describes the two-step simulation flow for simulations: EIN and LOM

Both are modeled as 2 step flows, basic flow consists of:

  1. Pre-calculation step
    User enters only the valuta date → system sends this to the simulation service → receives base constraints (min/max dates, allowed salary ranges, etc.).

  2. Final simulation step
    User enters LOM or EIN information → system sends full input → receives final simulation output ( pension values, taxes, monthly fees, etc.).

4.2. Sequence Diagram

EINtritts Simulation (for LOMution only the data in the "Enter full data" step changes)

sequenceDiagram
    participant User
    participant UI
    participant SimulationService
    User ->> UI: Enter valuta date
    UI ->> SimulationService: POST /precalculate { valutaDate }
    SimulationService -->> UI: Base constraints (minEntryDate, maxSalary...)
    UI -->> User: Display base data
    User ->> UI: Enter full data (name, salary, pensum...)
    UI ->> SimulationService: POST /simulate { ...all input... }
    SimulationService -->> UI: Simulation results (pension, taxes...)
    UI -->> User: Display final results

4.3. Preconditions / Annahmen

  • Simulationen werden anhand bestehender Simulationen (Clan xsd based) durchgeführt

  • Format ist XML (Date yyyy-mm-dd)

4.4. Conditions / Restrictions

  • Hinweis auf Simulationsliste im Header? -> Mehrere LOM nicht möglich (soll heissen?)

  • Versichertenwahl

    • anhand zugeordneter Mandanten möglich

    • nur AKTIVE VS auswählbar

wenn vor neuester LOM >> nicht mehrere Anpassungen gleichzeitig)
Datum vor aktuell in pkONE gemeldetem Datum (Berechnungsdatum kommt in SS) nicht möglich für Simulation: Meldung - Bitte bei BLPK melden

4.5. Step-by-Step Flow Documentation

4.5.1. Step 1 – Enter valuta date

Item Description

Purpose

Determine initial constraints and allowable ranges for later user inputs.

Trigger

User enters valuta date of event (entry date).

4.5.1.1. Input Data
Field Feldtyp Type Required Clan-Variable Description Condition

ValutaDatum

Datepicker

date

VALUTA_NEU ???

EIN (entry) date into company/pension fundLOM (salary change date) date

4.5.1.2. Output

Output EIN

No fields calculated

Field Variable Type Description

Output LOM

Field Feldtyp Type Clan-Variable Format Description Condition

Aktueller Lohn

String

numeric

???

Aktueller Beschäftgigungsgrad

String

numeric (percentage)

???

0-1

0 - 99%

Jüngstes Valuta / letzte Berechnung

String

date

???

yyyy-mm-dd

4.5.2. Step 2 – Simulation

Item Description

Purpose

Calculate full simulation results including pension, taxes, and employer costs.

Trigger

User enters personal + employment details.

4.5.2.1. Input EIN
Field Feldtyp Type Required Clan-Variable Format Description Condition

salary

Textfield

number

LOM_LOHN

Annual salary

pensum

Textfield

number

LOM_PENSUM

0-1

Work percentage

Mit Fakturasimulation? (FSML)

Checkbox

boolean

Status???

Mandant

Dropdown

string

MANDANT

Gemäss eingeloggtem User???, s. Fragen

Name

Textfield

string

???

Vorname

Textfield

string

???

Geschlecht

Dropdown

numeric

???

Geburtsdatum

Datepicker

date

???

yyyy-mm-dd

Eintrittsdatum

Datepicker

date

???

yyyy-mm-dd

Adresse

Textfield

string

???

PLZ

Textfield

string

???

ORT

Textfield

string

???

Lohn neu

Textfield

numeric

???

LOM_LOHN

Feld FSML = true, dann enabled, sonst disabled ???

Beschäftigungsgrad neu

Textfield

numeric

???

LOM_PENSUM

Feld FSML = true, dann enabled, sonst disabled ???

ValutaDatum

Datepicker

date

LOM_VALUTA

yyyy-mm-dd

Entry date

Feld FSML = true, dann enabled, sonst disabled ??? Datum darf nicht vor aktuell in pkONE gemeldetem Datum (Berechnungsdatum/issue date) liegen für Simulation, sonst Meldung analog "Bitte bei BLPK melden"

4.5.2.2. Input LOM
Field Feldtyp Type Required Clan-Variable Description Condition

-

string

MANDANT

Abgeleitetes Feld Versicherter

-

number

PKNR

Abgeleitetes Feld Versicherter

Versicherter

Autocomplete

string

-

Auswahl des Versicherten

Faktura-Simulation mit Lohnmutation? (FSML)

Checkbox

boolean

-

Lohn neu

Textfield

numeric

LOM_LOHN

Feld FSML = true, dann enabled, sonst disabled

Beschäftigungsgrad neu

Textfield

numeric

LOM_PENSUM

Feld FSML = true, dann enabled, sonst disabled

Gültig ab neu

Datepicker

numeric

LOM_VALUTA

Feld FSML = true, dann enabled, sonst disabledDatum darf nicht vor aktuell in pkONE gemeldetem Datum (Berechnungsdatum/issue date) liegen für Simulation, sonst Meldung analog "Bitte bei BLPK melden"

4.5.2.3. Output EIN / LOM Simulation

Anzeige der Tabelle FAKTURA-WERTE

  • Werte zum direkten Vergleich gegenübergestellt

  • für beide Simulationen identisch

  • durchgestrichene Werte nicht berücksichtigt in UI

Property Label Regulärer Wert (tagesaktuell) Simulation (mit Lohnmutation) Korrektur

property.simulation.ag.P10.name

Sparbeitrag AN

P10-FAKT-REG

P10-FAKT-SIM

P10-FAKT-KORR

property.simulation.ag.P100.name

Verwaltungskostenbeitrag AG

P100-FAKT-REG

P100-FAKT-SIM

P100-FAKT-KORR

property.simulation.ag.P1000.name

Risikobeitrag AN z.L. VoWe

P1000-FAKT-REG

P1000-FAKT-SIM

P1000-FAKT-KORR

property.simulation.ag.P1001.name

Risikobeitrag AN z.L. VoWe BuHa

P1001-FAKT-REG

P1001-FAKT-SIM

P1001-FAKT-KORR

property.simulation.ag.P1010.name

Risikobeitrag AG z.L. VoWe

P1010-FAKT-REG

P1010-FAKT-SIM

P1010-FAKT-KORR

property.simulation.ag.P1011.name

Risikobeitrag AG z.L. VoWe BuHa

P1011-FAKT-REG

P1011-FAKT-SIM

P1011-FAKT-KORR

property.simulation.ag.P105.name

Verwaltungskostenbeitrag AG zul. AN

P105-FAKT-REG

P105-FAKT-SIM

P105-FAKT-KORR

property.simulation.ag.P110.name

Verwaltungskostenbeitrag AN

P110-FAKT-REG

P110-FAKT-SIM

P110-FAKT-KORR

property.simulation.ag.P20.name

Risikobeitrag AN

P20-FAKT-REG

P20-FAKT-SIM

P20-FAKT-KORR

property.simulation.ag.P40.name

Sparbeitrag AG

P40-FAKT-REG

P40-FAKT-SIM

P40-FAKT-KORR

property.simulation.ag.P45.name

Sparbeitrag AG zulasten AN

P45-FAKT-REG

P45-FAKT-SIM

P45-FAKT-KORR

property.simulation.ag.P50.name

Risikobeitrag AG

P50-FAKT-REG

P50-FAKT-SIM

P50-FAKT-KORR

property.simulation.ag.P55.name

Risikobeitrag AG zulasten AN

P55-FAKT-REG

P55-FAKT-SIM

P55-FAKT-KORR

property.simulation.ag.P701.name

Teuerungsfonds AG

P701-FAKT-REG

P701-FAKT-SIM

P701-FAKT-KORR

property.simulation.ag.P705.name

Teuerungsfonds AG zul. AN

P705-FAKT-REG

P705-FAKT-SIM

P705-FAKT-KORR

property.simulation.ag.P800.name

Sanierungsbeiträge AN

P800-FAKT-REG

P800-FAKT-SIM

P800-FAKT-KORR

property.simulation.ag.P801.name

Sanierungsbeiträge AG

P801-FAKT-REG

P801-FAKT-SIM

P801-FAKT-KORR

property.simulation.ag.P805.name

Sanierungsbeiträge AG zul. AN

P805-FAKT-REG

P805-FAKT-SIM

P805-FAKT-KORR

property.simulation.ag.P900.name

Gesmntbeitrag bei Freiw. Versicherung

P900-FAKT-REG

P900-FAKT-SIM

P900-FAKT-KORR

property.simulation.ag.P9000.name

Sparbeitrag AN z.L. Risikopool

P9000-FAKT-REG

P9000-FAKT-SIM

P9000-FAKT-KORR

property.simulation.ag.P9001.name

Sparbeitrag AN z.L. Risikopool BuHa

P9001-FAKT-REG

P9001-FAKT-SIM

P9001-FAKT-KORR

property.simulation.ag.P901.name

FAKT VVP Anteil AG

P901-FAKT-REG

P901-FAKT-SIM

P901-FAKT-KORR

property.simulation.ag.P9010.name

Sparbeitrag AG z.L. Risikopool

P9010-FAKT-REG

P9010-FAKT-SIM

P9010-FAKT-KORR

property.simulation.ag.P9011.name

Sparbeitrag AG z.L. Risikopool BuHa

P9011-FAKT-REG

P9011-FAKT-SIM

P9011-FAKT-KORR

property.simulation.ag.P9020.name

Risikobeitrag AN z.L. Risikopool

P9020-FAKT-REG

P9020-FAKT-SIM

P9020-FAKT-KORR

property.simulation.ag.P9021.name

Risikobeitrag AN z.L. Risikopool BuHa

P9021-FAKT-REG

P9021-FAKT-SIM

P9021-FAKT-KORR

property.simulation.ag.P9030.name

Risikobeitrag AG z.L. Risikopool

P9030-FAKT-REG

P9030-FAKT-SIM

P9030-FAKT-KORR

property.simulation.ag.P9031.name

Risikobeitrag AG z.L. Risikopool BuHa

P9031-FAKT-REG

P9031-FAKT-SIM

P9031-FAKT-KORR

property.simulation.ag.P9040.name

VW Beitrag AN z.L. Risikopool

P9040-FAKT-REG

P9040-FAKT-SIM

P9040-FAKT-KORR

property.simulation.ag.P9041.name

VW Beitrag AN z.L. Risikopool BuHa

P9041-FAKT-REG

P9041-FAKT-SIM

P9041-FAKT-KORR

property.simulation.ag.P9050.name

VW Beitrag AG z.L. Risikopool

P9050-FAKT-REG

P9050-FAKT-SIM

P9050-FAKT-KORR

property.simulation.ag.P9051.name

VW Beitrag AG z.L. Risikopool BuHa

P9051-FAKT-REG

P9051-FAKT-SIM

P9051-FAKT-KORR

property.simulation.ag.P9060.name

Umlagebeitrag AG z.L. Risikopool

P9060-FAKT-REG

P9060-FAKT-SIM

P9060-FAKT-KORR

property.simulation.ag.P9061.name

Umlagebeitrag AG z.L. Risikopool BuHa

P9061-FAKT-REG

P9061-FAKT-SIM

P9061-FAKT-KORR

property.simulation.ag.P9070.name

Umlagebeitrag Besitzstd z.L. Risikopool

P9070-FAKT-REG

P9070-FAKT-SIM

P9070-FAKT-KORR

property.simulation.ag.P9071.name

Umlagebeitrag Besitzstd z.L. RiPo BuHa

P9071-FAKT-REG

P9071-FAKT-SIM

P9071-FAKT-KORR

property.simulation.ag.P9080.name

Sanierungsbeitrag AN z.L. Risikopool

P9080-FAKT-REG

P9080-FAKT-SIM

P9080-FAKT-KORR

property.simulation.ag.P9081.name

Sanierungsbeitrag AN z.L. RiPo BuHa

P9081-FAKT-REG

P9081-FAKT-SIM

P9081-FAKT-KORR

property.simulation.ag.P9090.name

Sanierungsbeitrag AG z.L. Risikopool

P9090-FAKT-REG

P9090-FAKT-SIM

P9090-FAKT-KORR

property.simulation.ag.P9091.name

Sanierungsbeitrag AG z.L. RiPo BuHa

P9091-FAKT-REG

P9091-FAKT-SIM

P9091-FAKT-KORR

property.simulation.ag.P9100.name

Teuerungsfond AG z.L. Risikopool

P9100-FAKT-REG

P9100-FAKT-SIM

P9100-FAKT-KORR

property.simulation.ag.P9101.name

Teuerungsfond AG z.L. Risikopool BuHa

P9101-FAKT-REG

P9101-FAKT-SIM

P9101-FAKT-KORR

property.simulation.ag.P920.name

Umlagebeitrag AG monatlich

P920-FAKT-REG

P920-FAKT-SIM

P920-FAKT-KORR

property.simulation.ag.P925.name

Umlagebeitrag Anteil Besitzstand

P925-FAKT-REG

P925-FAKT-SIM

P925-FAKT-KORR

Summenbildung Arbeitgeberbeiträge TOTAL-VARBEZ-1
Summenbildung Arbeitnehmerbeiträge TOTAL-VARBEZ-2

4.6. Workbook Reference

The original spreadsheet is available as LOM_FAK.xlsx.

The tables below extract the workbook content into readable AsciiDoc for the documentation.

4.7. Sheet EIN_FAK

4.7.1. Portal Input And Defaults

Portal field Input / default Portal action

Mit Fakturasimulation?

Checkbox

Eingabe Portal

Mandant

Gemäss eingeloggtem User

Name

Eingabe

Vorname

Eingabe

Geschlecht

Eingabe

Geburtsdatum

Eingabe

Eintrittsdatum

Eingabe

Adresse

Simulationsstrasse 1

PLZ

4410

ORT

Liestal

Jahreslohn

Eingabe

Pensum

Eingabe

Valuta

=Eintrittsdatum

4.7.2. Clan Processing Overview

Step Workbook note

Startprozess

Erfassung Sim Clan

Eintritt Simulation (analog Swing Client) gemäss Daten Portal

Request Clan

Berechnen

Eintritt berechnen

Berechnen

Fakturasimulation

Anzeige Portal

Simulation Einzelfaktura Versicherte

Nächste Periode automatisch durch PV-Clan gewählt

4.8. Sheet LOM_FAK

4.8.1. Portal Input And Defaults

Portal field Anzeige / current value Input / target value Notes

Versichertenauswahl durch User

Auswahl gem. Versicherten Liste

Nur aktive Versicherte auswählbar

Fakturasimulation mit Lohnmutation?

Eingabe Checkbox

Eingabe Portal

Wenn mit LOM

Aktueller Lohn

Lohn neu

Wenn mit LOM

Aktueller Beschäftigungsgrad

Beschäftigungsgrad neu

Wenn mit LOM

Jüngstes Valuta / letzte Berechnung

Gültig ab neu

Nur im aktuellen Jahr; Hinweis wenn vor neuester LOM keine mehreren Anpassungen gleichzeitig möglich sind

4.8.2. Clan Processing Overview

Step Workbook note

Startprozess

Erfassung Sim Clan

Gemäss Daten Onlineportal

Request Clan

Berechnen

Kettensimulation Lohnmutation(en)

Übergabewerte

MANDANT, PKNR, Status = Aktiv, LOM_VALUTA, LOM_PENSUM, LOM_LOHN

Berechnen

100 Kettensimulation Fakturasimulation

Simulation Einzelfaktura Versicherte

Nächste Periode automatisch durch PV-Clan gewählt

Anzeige Portal

4.8.3. Workbook Sample Output

The workbook also contains detailed sample output blocks named FAKTURAWERTE and KORREKTUREN for both EIN_FAK and LOM_FAK. The handbook section above already documents the target output structure; use the original workbook for the full spreadsheet example.

4.9. Offene Fragen

  • Ist diese Bemerkung für uns relevant: "Frage JWA: Massensimulation 2% Lohnerhöhung > Dokumentoutput?"

  • Simu EIN - Variable Mandant: "Gemäss eingeloggtem User" …​ kann es aber sein, dass der Benutzer mehrere zugewiesene Mandaten hat? -> MandantenAuswahl nötig

  • Die Kommunikation zwischen Clan-OIT geschieht File-basiert oder per Rest-API?

5. AGB Management in pkONE

5.1. Kernfunktionalität

5.1.1. Digitalisierung des bestehenden Prozesses:

Dieses Modul digitalisiert den Prozess der AGB-Bestätigung und löst den manuellen Aufwand rund um die Portal-Nutzungsbestimmungen vollständig ab. Unter anderem entfallen dadurch alle manuellen Schritte des administrativen Prozesses:

  • Erstellung und Formatierung der AGBs

  • Kuvertierung und Postversand

  • Manuelle überwachung des Rücklaufs

  • Manuelle Bearbeitung und Archivierung der zurückgesendeten Dokumente

5.1.2. Vereinfachung des Prozesses bei Anpassung der AGBs - durch Versionierung:

Die Steuerung erfolgt über eine AGB-Versionsnummer, die vom Administrator in den Einstellungen angepasst werden kann. Sobald diese Nummer geändert wird, erkennt das System die AGB für alle Benutzer als „nicht bestätigt“. In der Folge werden die User beim nächsten Login automatisch aufgefordert, die neuen Bedingungen zu akzeptieren. Nach der Bestätigung wird die aktuelle Version direkt in einem Attribut des Benutzers gespeichert und der Zugriff auf das Portal freigegeben.

5.2. Der Benutzer-Workflow

Sobald sich ein Benutzer anmeldet, prüft das System den Status:

  1. Prüfung: Hat der User die Version (s. Einstellungen "AGB Version") bereits bestätigt?

  2. Popup-Erzwingung: Falls nein, erscheint das vorbereitete modale Fenster (Popup).

    • Sperre: Das Fenster kann nicht einfach geschlossen werden. Eine Navigation im Hintergrund ist blockiert.

    • Interaktion: Checkbox zur Akzeptanz + Button "Akzeptieren".

  3. Freigabe: Erst nach erfolgreichem Klick wird Zugriff auf das Portal gewährt.

Das System stellt sicher, dass kein Benutzer Zugriff auf das Portal erhält, ohne die aktuellste Version der Allgemeinen Geschäftsbedingungen (AGB) akzeptiert zu haben.

  • Trigger: Der Prozess wird bei jedem Login-Vorgang geprüft.

  • Abhängigkeit: Vergleich zwischen der in pkONE hinterlegten Versionsnummer und auf dem User gespeicherten Attribut. Sobald die Version in den Einstellungen angepasst wird, wird der Prozess im Hintergrund neu getriggert.

5.3. Design & Konfiguration

Das System ist zweistufig aufgebaut:

  • Design-Vorlage: Die grundlegende Struktur, das Layout des Popups werden initial durch das OIT-Team vorbereitet. Dies stellt sicher, dass das Corporate Design optimal umgesetzt ist.

  • Property-Steuerung: Nach der initialen Erstellung können die Inhalte selbstständig über Properties angepasst werden.

    • Inhaltsanpassung: Texte können ohne Release geändert werden

    • Steuerung: Anpassung der Versions-ID erfolgt über die Einstellungen (durch Admin)

AGBs Beispiel

6. DocumentStore - Verbesserte Benutzerführung und UI

6.1. Ausgangslage & Problemanalyse

Der DocumentStore soll verbessert werden. Ziel ist es, dass Kunden intuitiv erkennen, welche Dokumente neu zur Verfügung gestellt wurden und welche Dokumente schon bezogen wurden. Zudem soll das Layout übersichtlicher gestaltet werden.

Gründe für die mangelnde Benutzerführung:

  • UI & Layout: Kategorien werden in einem Drop-Down angezeigt, was die Orientierung erschwert

  • Erweiterung DokumentStatus: Da ein klarer „Gelesen“- oder „Heruntergeladen“-Status fehlt, erkennt der Benutzer nicht, welche Dokumente im DocumentStore noch nicht gelesen/heruntergeladen wurden

6.2. Funktionale Anpassungen

6.2.1. UI und Layout: Kategorien-Management & UI Redesign

Wechsel vom alten BLPK-Design auf das neue Design:

  • Seitenpanel: Kategorien werden links in einem Panel angezeigt (statt Dropdown) somit werden auf einen Blick alle Kategorien präsentiert. Dadurch wird die Übersicht für den Benutzer deutlich erhöht. Ausserdem ist diese Anpassung Grundlage dafür, dass Badges angebracht werden können (siehe 2.2).

  • Tabellen-Layout: Optimierung der Breite, bessere Anordnung der Spalten, Grössere Schrift, nicht benötigte Spalten entfernen (z.B Grösse)

6.2.2. UI und Layout: Status-Tracking & Badges

Einführung von Badges und neue Dokument Stati:

  • Badges auf Kategorie: Auf der Kategorie (z. B. "Rechnungen") erscheint ein Badge mit der Anzahl der ungelesenen Dokumente, sodass für den Benutzer sofort ersichtlich wird, in welcher Kategorie neue Dokumente verteilt wurden.

  • Schriftart auf ungelesenem Dokument: Ein ungelesenes Dokument wird farblich hervorgehoben (fette Schrift, dunklere Schrift, oranges Icon, etc.), um den Benutzer noch klarer zu führen.

  • Neue Dokument Stati - Anpassung der Icon-Logik:

    • Ungelesenes Dokument: Geschlossener Briefumschlag

    • Gelesenes Dokument: Geöffneter Briefumschlag

      • Trigger: Der Status wechselt von "ungelesen" auf "gelesen", sobald das Dokument heruntergeladen oder als gelesen markiert wurde (Klick auf Icon)

    • Heruntergeladenes Dokument: Download Icon (to be defined)

      • Trigger: Der Status wechselt von "gelesen/ungelesen" auf "heruntergeladen", sobald das Dokument mittels Aktion "herunterladen" geladen wurde.

DocumentStore mockup

Das folgende Mockup zeigt die geplante Neugestaltung des DocumentStores. Bitte beachten, dass es sich um einen Entwurf handelt, deren finale Umsetzung von dieser Darstellung abweichen kann.

6.3. Transparente Dokumentenbearbeitung bei grösseren Arbeitgeberanschlüssen

Problemstellung Bei grösseren Arbeitgeberanschlüssen ist oft unklar, ob ein Dokument bereits durch Teamkollegen bearbeitet wurde. Um diese Benutzer optimal zu unterstützen, muss die Bearbeitung wichtiger Dokumente (z. B. Faktura) transparent gestaltet werden. Eine rein visuelle Anpassung der Benutzeroberfläche (siehe 2.1 und 2.2) reicht hierfür nicht aus.

Lösung Hierfür wird das Modul „MyTasks“ eingeführt und um spezifische Dokumententypen erweitert. Wird ein als „wichtig“ markiertes Dokument verteilt, löst das System automatisch für alle Benutzer des entsprechenden Mandanten einen Task aus, der im neuen Panel auf der Homepage erscheint. Sobald einer der berechtigten Benutzer die Aufgabe erledigt, wird der Task synchron bei allen anderen Benutzern entfernt. Dies stellt sicher, dass das Team jederzeit den aktuellen Bearbeitungsstatus sieht und verhindert redundante Aufwände.

  • Konfiguration pro Dokumenttyp: Im Backend kann pro Dokumenttyp (z.B. Typ "Faktura") definiert werden: Erzeugt Task = Ja/Nein.

  • Workflow: Wird ein solches Dokument via Distribution verteilt, erscheint auf dem Open Tasks Panel (auf Startseite) des Arbeitgebers automatisch ein neuer Task (z.B. "Neue Rechnung zur Prüfung").

  • Deep-Link: Der Task führt direkt zum gefilterten DocumentStore.

  • Abschluss: Der Task verschwindet erst, wenn das Dokument im DocumentStore geöffnet/heruntergeladen/erledigt gesetzt wurde (to be defined)

7. MyTasks

7.1. Vision & Zielsetzung

Das Panel „Meine Aufgaben“ optimiert die Benutzerführung im Portal für Arbeitgeber, Versicherte und Sachbearbeiter. Durch die zentrale Anzeige aller offenen Aufgaben wird der Nutzer optimal durch seine anstehenden Arbeiten geführt – von einfachen Mutationen über den Erhalt neuer Dokumente bis hin zur Lohnerfassung.

Besonders bei komplexen Geschäftsfällen wie zum Beispiel Meldung von Arbeitsunfähigkeit, Invalidität oder Todesfällen bietet das neue Panel Unterstützung durch optimale Führung des Benutzers. So können beispielweise umfangreiche Prozesse in übersichtliche Einzelschritte und Subtasks aufgebrochen werden. Diese Führung stellt sicher, dass auch komplexe Prozesse korrekt und effizient bearbeitet werden. Durch diese verbesserte Benutzerführung können zukünftig auch komplexe Mutationen vollständig ins Portal übertragen werden.

Darüber hinaus bietet das Panel folgende Vorteile:

  • Volle Transparenz: Benutzer sehen auf einen Blick welche Aufgaben im Portal noch erledigt werden müssen

  • Aktive Prozesssteuerung: Durch die direkte Zuweisung werden Pendenzen schneller abgearbeitet und Prozesse aktiv vorangetrieben

  • Gezielte Nutzerführung und Effizienz: Der Benutzer wird strukturiert durch seine ToDos geführt und kann seine Aufgaben so effizient im Portal abarbeiten

Das neue Panel wird eine wertvolle Komponente in pkONE, hier ein paar Beispiele:

Rolle Task Use Case

AG

Mutation

Offene Mutationen werden angezeigt und so nicht vergessen

AG

Lohnerfassung

Sobald die Jährliche Lohnmeldung initialisiert wird, wird ein Task ausgelöst

AG

Lohnerfassung

Folgemutationen innerhalb der Lohnerfassung lösen einen Tasks aus, werden so nicht vergessen

AG

Mutation (mit Flag)

Komplexe Mutationen, die einen erweiterten Prozess erfordern (z.B Arbeitsunfähigkeit) lösen eine Aufgabe aus

AG

Document Task

Verteilung eines bestimmten DokumentTyps löst einen Task aus, sodass sichergestellt wird, dass das Dokument verarbeitet wurde, sinnvoll bei wichtigen Dokumenten (Faktura) oder grösseren Arbeitgeberanschlüssen

VS

Mutation

Bei Neueineintritt wird ein Task zur Wahl des Sparplans generiert

VS

Validierung

Versicherte werden über Task informiert, wenn Kontaktdaten verifiziert werden müssen

usw…​

MyTasks panel mockup 1

7.2. Task-Hierarchie & Struktur

Um komplexe Geschäftsprozesse übersichtlich abzubilden, nutzt das System eine zweistufige Task-Architektur

  • Haupttask (Parent): Repräsentiert den übergeordneten Prozess (z.B. "Lohnerfassung" oder eine reguläre "Mutation Austritt").

  • Untertask (Children): Steht für granulare Aktionen innerhalb eines Prozesses (z.B. " Verhandelbare Folgemutation").

  • Verknüpfung: Jeder Untertask ist technisch zwingend mit einem Haupttask als "Parent" verlinkt.

7.3. UI & Anzeige-Verhalten

7.3.1. Basis-Design und Interaktion

  • Standard-Ansicht: Das Panel zeigt initial ausschliesslich Aufgaben mit dem Status offen.

  • Navigation: Ein Klick auf "Aufgabe öffnen" führt via Deep Link (Action-Framework) direkt zur Ziel-Entität (z.B. Mutations-Detailseite oder Dokument, InAppMail etc.).

  • Scroll-Verhalten: Das Panel erhält eine Maximalhöhe mit vertikalem Scrollbar für die Aufgabenliste.

7.3.2. Kontextuelle Einbindung

  • Startseite (Dashboard): Zeigt global alle offenen Haupttasks über sämtliche Typen hinweg an. Untertasks werden hier ausgeblendet, um die Übersichtlichkeit zu wahren.

  • Themenbezogene Einbettung: Das Panel kann themenbezogen auf anderen Seiten eingebettet werden. Am Beispiel der Maske "Lohnerfassung": Hier ist das Panel erst sichtbar, sobald ein Mandant ausgewählt wurde. Es ist gefiltert auf den Typ "Lohnerfassung" und zeigt den Haupttask sowie die zugehörigen Untertasks (offene, verhandelbare Folgemutationen) an.

  • Das Panel kann an diversen weiteren Stellen im Portal eingeblendet werden

7.4. Logik, Lebenszyklus & Automatisierung

7.4.1. Trigger für die Aufgabenerstellung

  • Einfache Mutationen: Mutationen die gespeichert werden, aber nicht eingereicht, generieren automatisch einen Task

  • Prozess-Initialisierung: Beispielsweise löst die Initialisierung der Lohnerfassung den LOM-Haupttask aus.

  • Komplexe Mutationen (AUF/Todesfall): Speichert oder meldet der Arbeitgeber eine Mutation, die weitere Aktionen erfordert (geflaggte Mutationen), generiert das System sofort einen Task. Benötigte Formulare werden vom Sachbearbeiter/System direkt im DocumentStore mit der Mutation verknüpft (tbd) und einem Task zugewiesen.

  • Dokument-Task: Sobald spezifische Dokumente (z.B. Rechnungen, Informationsschreiben mit Lesebestätigung) verteilt werden, entsteht eine Aufgabe im Portal (konfigurierbar über DokumentTyp).

7.4.2. Fälligkeiten (Due Dates)

  • Tasks können ein Due Date (Fälligkeitsdatum) anzeigen.

  • Bei der Lohnerfassung entspricht dies dem Enddatum der für den Mandanten freigeschalteten Periode.

    • Ist für einen Mandanten keine Periode hinterlegt, entfällt das Due Date (oder greift auf einen noch zu definierenden Standardwert zurück).

7.4.3. Erledigung und Löschung (Abschluss)

Anzeige: Tasks verschwinden standardmässig aus der "Offen"-Ansicht, sobald der Status auf erledigt wechselt.

  • Explizit: Manuelles Markieren als "erledigt" / "done" durch den User.

  • Implizit: Das System schliesst Tasks automatisch, wenn eine Bedingung erfüllt ist (z.B. ein zwingendes Dokument wurde heruntergeladen oder eine Mutation eingereicht).

7.4.4. Benachrichtigung

Jeder Task hat eine Benachrichtigungsdefinition hinterlegt: So kann für den jeweiligen Task konfiguriert werden, wie viele Notifizierungen in welchen Abständen verschickt werden sollen.

7.5. Spezialfall: Jährliche Lohnerfassung (LE)

Die LE unterliegt einer abweichenden, zeitgesteuerten Anzeigelogik.

  • Sichtbarkeit: Der LE-Haupttask (auf Dashboard) wird während der aktiven Periode angezeigt.

  • Abschluss-Verhalten: Werden alle LE-Datensätze (und offenen Folgemutationen) bestätigt, gilt die LE als erledigt.

  • Persistenz: Im Gegensatz zu regulären Tasks verschwindet der LE-Haupttask nach Erledigung nicht sofort. Er bleibt bis zum Ende der Periode sichtbar und wird farblich als "abgeschlossen/eingereicht" markiert.

MyTasks panel mockup 2

7.6. Technische Beschreibung

Task

  • Offene Aufgabe, Attribute

    • Status: offen/geschlossen

    • Bezeichnung

    • Beschreibung

    • Fällig am (due date)

    • Erstellt am (created date)

    • Erledigt an (done date)

    • Erledigt durch

Action

Einführung von Actions als 1st class Entity: Ist eine Verlinkung innerhalb pkONE, die über Parameter eine spezifische Entity adressieren kann. Eine Action kann von überall her getriggert werden, siehe auch ActionToClassNavigationMapping - definiert aktuelles Mapping Bsp:

  • IAM: Aufruf einer IAM mit vorgewähltem Topic, Subject und Content

  • Mutation: Öffnen einer Mutation mit entsprechender Sektion geöffnet

Maintenance

  • Alle erledigten Tasks werden nach x Tagen gelöscht

7.7. Roadmap & Versionierung

Version Geplante Funktionen

V1 (Aktuell)

- Einführung Panel im Arbeitgeberportal (HomeScreen) / Mandantentasks- Einbindung in Lohnerfassungsmaske- Parent-Child Hierarchie- LOM-Speziallogik- Action-Framework

V2 (Zukunft - basierend auf Kundenanforderungen)

- Anzeige Panel an weiteren Stellen im Arbeitgeberportal- Aktives Benachrichtigungssystem (E-Mail/Push-Notifikationen bei Generierung neuer Tasks)- explizite Erledigung Task- Erweiterung der Dokumenten-Trigger (via DocumentTypes-Konfiguration)- Panel für Sachbearbeiter (welche LE sind noch offen, welche Mandantendaten geändert,…​ etc)- Panel für Versichertenportal

8. Simulationen - Generelle Spezifikationen

8.1. Simulationsliste

  • Die Einstiegsseite für alle Simulationen ist die Seite „SimulationList“. Dort werden alle für den Arbeitgeber verfügbaren Simulationen angezeigt.

  • Die Liste wird als Akkordeon-Komponente angezeigt, analog zum folgenden Screenshot

Simulation list
  • Jeder Eintrag kann erweitert werden und enthält

    • Eine Überschrift für die Simulation

    • Einen Abschnitt zur Beschreibung der Simulation (kann so ziemlich alles enthalten, sogar über den DocumentStore hochgeladene Dokumente (Leitfaden, Info-Paper))

    • Das für die jeweilige Simulation zu wählende Valutadatum, das das Datum des Eintrags, der Gehaltsänderung usw. darstellt

    • Eine Schaltfläche zum Starten einer Simulation

8.2. Simulation-Detail

8.2.1. Header Sektion

Die Seite Simulation Detail enthält in der Regel einen Kopfbereich (Informationen über die versicherte Person/den Kunden (Mandant)).

8.2.2. Input Sektion

Danach Informationen zu den für die eigentliche Simulation berechneten Variablen (vom Simulations-Service im 1. Schritt bezogen).

Im Anschluss die Eingabe-Sektion mit allen für die Simulation zu erfassenden Werten

8.2.3. Output Sektion

In dieser Sektion werden die berechneten Werte aufbereitet, meist in tabellarischer Form.

Die Output-Sektion unterstützt konditionales Ein-/Ausblenden von Werten und Textblöcken.

Die berechneten Werte können ebenfalls in Charts/Diagrammen (alle erdenklichen Chart-Typen, s. Apache ECharts library) dargestellt werden.

Beispiel für eine Detail-Seite:

Simulation detail