taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit 88b60afc513eaa08c6a89d4ab8f19a23ce65fa0d
parent 8885175ca4f7800cb448ec28cd1f0143389ac0b7
Author: Florian Dold <dold@taler.net>
Date:   Sun, 23 Aug 2026 12:56:12 +0200

web-util: remove obsolete forms and add personal info story

Diffstat:
Mpackages/taler-exchange-kyc-webui/src/forms.json | 365-------------------------------------------------------------------------------
Mpackages/taler-harness/src/integrationtests/merchant-kyc-auth-helper.ts | 32++++++++------------------------
Mpackages/taler-harness/src/integrationtests/test-exchange-kyc-auth.ts | 8++++----
Mpackages/taler-harness/src/integrationtests/test-exchange-merchant-kyc-auth.ts | 8++++----
Mpackages/taler-harness/src/integrationtests/test-kyc-merchant-deposit-form.ts | 2+-
Mpackages/taler-harness/src/integrationtests/test-kyc-wallet-deposit-abort.ts | 8++++----
Dpackages/web-util/src/forms/TimePicker.tsx | 244-------------------------------------------------------------------------------
Dpackages/web-util/src/forms/gana/gls_merchant_onboarding.stories.tsx | 44--------------------------------------------
Dpackages/web-util/src/forms/gana/gls_merchant_onboarding.ts | 377-------------------------------------------------------------------------------
Dpackages/web-util/src/forms/gana/gls_wallet_confirmation.stories.tsx | 44--------------------------------------------
Dpackages/web-util/src/forms/gana/gls_wallet_confirmation.ts | 46----------------------------------------------
Mpackages/web-util/src/forms/gana/index.stories.ts | 4+---
Apackages/web-util/src/forms/gana/personal-info.stories.tsx | 39+++++++++++++++++++++++++++++++++++++++
Mpackages/web-util/src/forms/index.ts | 8--------
Mpackages/web-util/src/utils/select-ui-lists.ts | 533+------------------------------------------------------------------------------
15 files changed, 62 insertions(+), 1700 deletions(-)

diff --git a/packages/taler-exchange-kyc-webui/src/forms.json b/packages/taler-exchange-kyc-webui/src/forms.json @@ -209,371 +209,6 @@ } ] } - }, - { - "label": "GLS Onboarding form", - "id": "gls-onboarding", - "version": 1, - - "config": { - "type": "double-column", - "design": [ - { - "title": "Personal information", - "description": "this form is still working in progress, fields need to be validated.", - "fields": [ - { - "type": "text", - "id": "PERSON_FULL_NAME", - "label": "Full name", - "required": true - }, - { - "type": "text", - "id": "PERSON_LAST_NAME", - "label": "Last name", - "required": true - }, - { - "type": "text", - "id": "CONTACT_PHONE", - "label": "Phone" - }, - { - "type": "text", - "id": "CONTACT_EMAIL", - "label": "E-Mail" - }, - { - "type": "toggle", - "id": "ACCEPTED_TERMS_OF_SERVICE", - "label": "I accept terms of service", - "required": true - } - ] - }, - { - "title": "Business information", - "fields": [ - { - "type": "text", - "id": "BUSINESS_DISPLAY_NAME", - "label": "Name", - "required": true - }, - { - "type": "selectOne", - "id": "BUSINESS_TYPE", - "label": "The company type is", - "required": true, - "choices": [ - { - "label": "GmbH", - "value": "GMBH" - }, - { - "label": "ug", - "value": "UG" - }, - { - "label": "an operation legal entity or partnership", - "value": "OPERATIONAL" - }, - { - "label": "ohg", - "value": "OHG" - }, - { - "label": "kg", - "value": "KG" - }, - { - "label": "eg", - "value": "EG" - }, - { - "label": "eV", - "value": "EV" - }, - { - "label": "PartG", - "value": "PARTG" - }, - { - "label": "ek", - "value": "EK" - }, - { - "label": "AG (nicht börsennotiert)", - "value": "AGNB" - }, - { - "label": "AG (börsennotiert)", - "value": "AGB" - }, - { - "label": "GbR", - "value": "GBR" - }, - { - "label": "n.e.V.", - "value": "NEV" - }, - { - "label": "Partei", - "value": "PARTEI" - }, - { - "label": "GmbH i.G.", - "value": "GMBHIG" - }, - { - "label": "eG. i.G.", - "value": "EGIG" - }, - { - "label": "e.V. i.G.", - "value": "EVIG" - }, - { - "label": "Other", - "value": "OTHER" - } - ] - }, - { - "type": "text", - "id": "BUSINESS_REGISTRATION_ID", - "label": "Registration ID", - "required": true - }, - { - "type": "text", - "id": "BUSINESS_LEGAL_JURISDICTION", - "label": "Legal jurisdiction", - "required": true - }, - { - "type": "text", - "id": "BUSINESS_REGISTRATION_DATE", - "label": "Founding date", - "required": true - }, - { - "type": "toggle", - "id": "BUSINESS_IS_NON_PROFIT", - "label": "I this company a non-profit?", - "required": true - } - ] - }, - { - "title": "Business industry", - "fields": [ - { - "type": "selectMultiple", - "id": "BUSINESS_INDUSTRY", - "label": "Industry", - "unique": true, - "max": 2, - "choices": [ - { - "label": "Car", - "value": "CAR" - }, - { - "label": "Food", - "value": "FOOD" - }, - { - "description": "preventing... not doing it", - "label": "Money laundry", - "value": "MONEY" - } - ], - "required": true - } - ] - }, - { - "title": "Adress", - "fields": [ - { - "type": "text", - "id": "ADDRESS_STREET_NAME", - "label": "Street name", - "required": true - }, - { - "type": "text", - "id": "ADDRESS_STREET_NUMBER", - "label": "Street number", - "required": true - }, - { - "type": "text", - "id": "ADDRESS_BUILDING_NAME", - "label": "Building name" - }, - { - "type": "text", - "id": "ADDRESS_BUILDING_NUMBER", - "label": "Building number" - }, - { - "type": "textArea", - "id": "ADDRESS_LINES", - "label": "Additional address reference" - }, - { - "type": "text", - "id": "ADDRESS_TOWN_LOCATION", - "label": "Town location" - }, - { - "type": "text", - "id": "ADDRESS_TOWN_DISTRICT", - "label": "Town district" - }, - { - "type": "text", - "id": "ADDRESS_COUNTRY_SUBDIVISION", - "label": "Country subdivision" - }, - { - "type": "selectOne", - "id": "ADDRESS_COUNTRY_CC", - "label": "Country", - "choices": [ - { - "label": "Germany", - "value": "DE" - }, - { - "label": "Switzerland", - "value": "CH" - }, - { - "label": "Spain", - "value": "ES" - }, - { - "label": "Argentina", - "value": "AR" - } - ] - } - ] - }, - { - "title": "Tax information", - "fields": [ - { - "type": "text", - "id": "TAX_COUNTRY_CC", - "label": "Country tax", - "required": true - }, - { - "type": "text", - "id": "TAX_ID", - "label": "Tax identifier", - "required": true - }, - { - "type": "toggle", - "id": "TAX_IS_USA_LAW", - "label": "Is business founded or under USA law?", - "required": true - }, - { - "type": "toggle", - "id": "TAX_IS_ACTIVE", - "label": "Is the business economically active?", - "required": true - }, - { - "type": "toggle", - "id": "TAX_IS_DEDUCTED", - "label": "Is the business economically active", - "required": true - } - ] - }, - { - "title": "Representatives", - "fields": [ - { - "type": "array", - "id": "BUSINESS_LEGAL_REPRESENTATIVES", - "labelFieldId": "CONTACT_PHONE", - "label": "List of natural persons that are legal representatives or shareholders", - "fields": [ - { - "type": "text", - "id": "PERSON_FULL_NAME", - "label": "Name", - "required": true - }, - { - "type": "text", - "id": "PERSON_DATE_OF_BIRTH", - "label": "Date of birth", - "required": true - }, - { - "type": "text", - "id": "CONTACT_PHONE", - "label": "Phone", - "required": true - }, - { - "type": "text", - "id": "CONTACT_EMAIL", - "label": "E-Mail", - "required": true - }, - { - "type": "text", - "id": "PERSON_NATIONALITY_CC", - "label": "Nationality", - "required": true - }, - { - "id": "PERSON_BUSINESS_REPRESENTATIVE_TYPE", - "label": "Full name", - "required": true, - "type": "choiceStacked", - "choices": [ - { - "label": "Individual", - "value": "INDIVIDUAL" - }, - { - "label": "Authorized to represent", - "value": "AUTHORIZED" - }, - { - "label": "Majority", - "value": "MAJORITY" - }, - { - "label": "In pair", - "value": "IN_PAIR" - }, - { - "label": "Other", - "value": "OTHERS" - } - ] - } - ], - "required": true - } - ] - } - ] - } } ], "not_yet_supported": [] diff --git a/packages/taler-harness/src/integrationtests/merchant-kyc-auth-helper.ts b/packages/taler-harness/src/integrationtests/merchant-kyc-auth-helper.ts @@ -44,16 +44,16 @@ COMMAND = taler-exchange-helper-measure-inform-investigate ENABLED = YES FALLBACK = freeze-investigate -[kyc-check-form-gls-merchant-onboarding] +[kyc-check-form-generic-note] TYPE = FORM -FORM_NAME = gls-merchant-onboarding -DESCRIPTION = "GLS Merchant Onboarding" +FORM_NAME = generic_note +DESCRIPTION = "Generic note" DESCRIPTION_I18N = {} OUTPUTS = FALLBACK = freeze-investigate [kyc-measure-merchant-onboarding] -CHECK_NAME = form-gls-merchant-onboarding +CHECK_NAME = form-generic-note PROGRAM = inform-investigate CONTEXT = {} VOLUNTARY = NO @@ -77,26 +77,10 @@ export function configureMerchantDepositKyc( config.setString("KYC-RULE-DEPOSIT-LIMIT", "threshold", threshold); config.setString("KYC-RULE-DEPOSIT-LIMIT", "timeframe", "1 days"); if (includeInformInvestigateSuccessor) { - config.setString( - "KYC-MEASURE-INFORM-INVESTIGATE", - "check_name", - "SKIP", - ); - config.setString( - "KYC-MEASURE-INFORM-INVESTIGATE", - "program", - "NONE", - ); - config.setString( - "KYC-MEASURE-INFORM-INVESTIGATE", - "voluntary", - "no", - ); - config.setString( - "KYC-MEASURE-INFORM-INVESTIGATE", - "context", - "{}", - ); + config.setString("KYC-MEASURE-INFORM-INVESTIGATE", "check_name", "SKIP"); + config.setString("KYC-MEASURE-INFORM-INVESTIGATE", "program", "NONE"); + config.setString("KYC-MEASURE-INFORM-INVESTIGATE", "voluntary", "no"); + config.setString("KYC-MEASURE-INFORM-INVESTIGATE", "context", "{}"); } } diff --git a/packages/taler-harness/src/integrationtests/test-exchange-kyc-auth.ts b/packages/taler-harness/src/integrationtests/test-exchange-kyc-auth.ts @@ -64,16 +64,16 @@ COMMAND = taler-exchange-helper-measure-inform-investigate ENABLED = YES FALLBACK = freeze-investigate -[kyc-check-form-gls-merchant-onboarding] +[kyc-check-form-generic-note] TYPE = FORM -FORM_NAME = gls-merchant-onboarding -DESCRIPTION = "GLS Merchant Onboarding" +FORM_NAME = generic_note +DESCRIPTION = "Generic note" DESCRIPTION_I18N = {} OUTPUTS = FALLBACK = freeze-investigate [kyc-measure-merchant-onboarding] -CHECK_NAME = form-gls-merchant-onboarding +CHECK_NAME = form-generic-note PROGRAM = inform-investigate CONTEXT = {} VOLUNTARY = NO diff --git a/packages/taler-harness/src/integrationtests/test-exchange-merchant-kyc-auth.ts b/packages/taler-harness/src/integrationtests/test-exchange-merchant-kyc-auth.ts @@ -56,16 +56,16 @@ COMMAND = taler-exchange-helper-measure-inform-investigate ENABLED = YES FALLBACK = freeze-investigate -[kyc-check-form-gls-merchant-onboarding] +[kyc-check-form-generic-note] TYPE = FORM -FORM_NAME = gls-merchant-onboarding -DESCRIPTION = "GLS Merchant Onboarding" +FORM_NAME = generic_note +DESCRIPTION = "Generic note" DESCRIPTION_I18N = {} OUTPUTS = FALLBACK = freeze-investigate [kyc-measure-merchant-onboarding] -CHECK_NAME = form-gls-merchant-onboarding +CHECK_NAME = form-generic-note PROGRAM = inform-investigate CONTEXT = {} VOLUNTARY = NO diff --git a/packages/taler-harness/src/integrationtests/test-kyc-merchant-deposit-form.ts b/packages/taler-harness/src/integrationtests/test-kyc-merchant-deposit-form.ts @@ -205,7 +205,7 @@ export async function runKycMerchantDepositFormTest(t: GlobalTestState) { "Content-Type": "application/json", }, body: { - FORM_ID: "gls-merchant-onboarding", + FORM_ID: "generic_note", FORM_VERSION: 1, }, }, diff --git a/packages/taler-harness/src/integrationtests/test-kyc-wallet-deposit-abort.ts b/packages/taler-harness/src/integrationtests/test-kyc-wallet-deposit-abort.ts @@ -54,16 +54,16 @@ COMMAND = taler-exchange-helper-measure-inform-investigate ENABLED = YES FALLBACK = freeze-investigate -[kyc-check-form-gls-merchant-onboarding] +[kyc-check-form-generic-note] TYPE = FORM -FORM_NAME = gls-merchant-onboarding -DESCRIPTION = "GLS Merchant Onboarding" +FORM_NAME = generic_note +DESCRIPTION = "Generic note" DESCRIPTION_I18N = {} OUTPUTS = FALLBACK = freeze-investigate [kyc-measure-merchant-onboarding] -CHECK_NAME = form-gls-merchant-onboarding +CHECK_NAME = form-generic-note PROGRAM = inform-investigate CONTEXT = {} VOLUNTARY = NO diff --git a/packages/web-util/src/forms/TimePicker.tsx b/packages/web-util/src/forms/TimePicker.tsx @@ -1,244 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2025 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -import { AbsoluteTime } from "@gnu-taler/taler-util"; -import { getHours, getMinutes, getSeconds, setHours } from "date-fns"; -import { Fragment, VNode, h } from "preact"; -import { useTranslationContext } from "../context/translation.js"; - -export function TimePicker({ - value, - onChange, - onConfirm, -}: { - value: AbsoluteTime | undefined; - onChange: (v: AbsoluteTime) => void; - onConfirm: () => void; -}): VNode { - const date = !value ? new Date() : new Date(AbsoluteTime.toStampMs(value)); - const hours = getHours(date) % 12; - const minutes = getMinutes(date); - const seconds = getSeconds(date); - - const { i18n } = useTranslationContext(); - - return ( - <Fragment> - <div class="flex flex-col bg-white rounded-t-sm justify-around"> - {/* time selection */} - <div - id="" - class="bg-[#3b71ca] dark:bg-zinc-700 h-24 rounded-t-lg p-12 flex flex-row items-center justify-center" - > - <div class="flex w-full justify-evenly"> - <div class=""> - <span class="relative h-full"> - <button - type="button" - class="py-1 px-3 text-[3.75rem] font-light leading-[1.2] text-white opacity-[.54] border-none bg-transparent p-0 cursor-pointer hover:bg-[#00000026] hover:outline-none focus:bg-[#00000026] focus:outline-none " - style="pointer-events: none;" - > - {new String(hours).padStart(2, "0")} - </button> - </span> - <span - type="button" - class="font-light leading-[1.2] text-[3.75rem] opacity-[.54] border-none bg-transparent p-0 text-white " - > - : - </span> - <span class="relative h-full"> - <button - type="button" - class="py-1 px-3 text-[3.75rem] font-light leading-[1.2] text-white opacity-[.54] border-none bg-transparent p-0 cursor-pointer hover:bg-[#00000026] hover:outline-none focus:bg-[#00000026] focus:outline-none " - > - {new String(minutes).padStart(2, "0")} - </button> - </span> - <span - type="button" - class="font-light leading-[1.2] text-[3.75rem] opacity-[.54] border-none bg-transparent p-0 text-white " - > - : - </span> - <span class="relative h-full"> - <button - type="button" - class="py-1 px-3 text-[3.75rem] font-light leading-[1.2] text-white opacity-[.54] border-none bg-transparent p-0 cursor-pointer hover:bg-[#00000026] hover:outline-none focus:bg-[#00000026] focus:outline-none " - > - {new String(seconds).padStart(2, "0")} - </button> - </span> - </div> - <div class="flex flex-col justify-center text-[18px] text-[#ffffff8a] "> - <button - type="button" - class="py-1 px-3 bg-transparent border-none text-white cursor-pointer hover:bg-[#00000026] hover:outline-none focus:bg-[#00000026] focus:outline-none" - > - AM - </button> - <button - type="button" - class="py-1 px-3 bg-transparent border-none text-white cursor-pointer hover:bg-[#00000026] hover:outline-none focus:bg-[#00000026] focus:outline-none" - > - PM - </button> - </div> - </div> - </div> - {/* clock */} - <div - id="" - class="mt-2 min-w-[310px] max-w-[325px] min-h-[305px] overflow-x-hidden h-full flex justify-center mx-auto flex-col items-center dark:bg-zinc-500" - > - <div class="relative rounded-[100%] w-[260px] h-[260px] cursor-default my-0 mx-auto bg-[#00000012] dark:bg-zinc-600/50 animate-[show-up-clock_350ms_linear]"> - <span class="top-1/2 left-1/2 w-[6px] h-[6px] -translate-y-1/2 -translate-x-1/2 rounded-[50%] bg-[#3b71ca] absolute"></span> - <div - class="bg-[#3b71ca] bottom-1/2 h-2/5 left-[calc(50%-1px)] rtl:!left-auto origin-[center_bottom_0] rtl:!origin-[50%_50%_0] w-[2px] absolute" - style={{ transform: "rotateZ(60deg)", height: "calc(35% + 1px)" }} - > - {/* <div class="-top-[21px] -left-[15px] w-[4px] border-[14px] border-solid border-[#3b71ca] h-[4px] box-content rounded-[100%] absolute" style="background-color: rgb(25, 118, 210);"></div> */} - </div> - - <span - onClick={() => - onChange(AbsoluteTime.fromStampMs(setHours(date, 12).getTime())) - } - class="absolute rounded-[100%] w-[32px] h-[32px] text-center cursor-pointer text-[1.1rem] bg-transparent flex justify-center items-center font-light focus:outline-none selection:bg-transparent data-[selected=true]:text-white data-[selected=true]:bg-[#3b71ca] data-[selected=true]:font-normal" - style="left: 114px; bottom: 224px;" - > - <span>0</span> - </span> - <span - onClick={() => - onChange(AbsoluteTime.fromStampMs(setHours(date, 1).getTime())) - } - class="absolute rounded-[100%] w-[32px] h-[32px] text-center cursor-pointer text-[1.1rem] bg-transparent flex justify-center items-center font-light focus:outline-none selection:bg-transparent data-[selected=true]:text-white data-[selected=true]:bg-[#3b71ca] data-[selected=true]:font-normal" - style="left: 169px; bottom: 209.263px;" - > - <span>1</span> - </span> - <span - onClick={() => - onChange(AbsoluteTime.fromStampMs(setHours(date, 2).getTime())) - } - class="absolute rounded-[100%] w-[32px] h-[32px] text-center cursor-pointer text-[1.1rem] bg-transparent flex justify-center items-center font-light focus:outline-none selection:bg-transparent data-[selected=true]:text-white data-[selected=true]:bg-[#3b71ca] data-[selected=true]:font-normal" - data-selected={true} - style="left: 209.263px; bottom: 169px;" - > - <span>2</span> - </span> - <span - onClick={() => - onChange(AbsoluteTime.fromStampMs(setHours(date, 3).getTime())) - } - class="absolute rounded-[100%] w-[32px] h-[32px] text-center cursor-pointer text-[1.1rem] bg-transparent flex justify-center items-center font-light focus:outline-none selection:bg-transparent data-[selected=true]:text-white data-[selected=true]:bg-[#3b71ca] data-[selected=true]:font-normal" - style="left: 224px; bottom: 114px;" - > - <span>3</span> - </span> - <span - onClick={() => - onChange(AbsoluteTime.fromStampMs(setHours(date, 4).getTime())) - } - class="absolute rounded-[100%] w-[32px] h-[32px] text-center cursor-pointer text-[1.1rem] bg-transparent flex justify-center items-center font-light focus:outline-none selection:bg-transparent data-[selected=true]:text-white data-[selected=true]:bg-[#3b71ca] data-[selected=true]:font-normal" - style="left: 209.263px; bottom: 59px;" - > - <span>4</span> - </span> - <span - onClick={() => - onChange(AbsoluteTime.fromStampMs(setHours(date, 5).getTime())) - } - class="absolute rounded-[100%] w-[32px] h-[32px] text-center cursor-pointer text-[1.1rem] bg-transparent flex justify-center items-center font-light focus:outline-none selection:bg-transparent data-[selected=true]:text-white data-[selected=true]:bg-[#3b71ca] data-[selected=true]:font-normal" - style="left: 169px; bottom: 18.7372px;" - > - <span>5</span> - </span> - <span - onClick={() => - onChange(AbsoluteTime.fromStampMs(setHours(date, 6).getTime())) - } - class="absolute rounded-[100%] w-[32px] h-[32px] text-center cursor-pointer text-[1.1rem] bg-transparent flex justify-center items-center font-light focus:outline-none selection:bg-transparent data-[selected=true]:text-white data-[selected=true]:bg-[#3b71ca] data-[selected=true]:font-normal" - style="left: 114px; bottom: 4px;" - > - <span>6</span> - </span> - <span - onClick={() => - onChange(AbsoluteTime.fromStampMs(setHours(date, 7).getTime())) - } - class="absolute rounded-[100%] w-[32px] h-[32px] text-center cursor-pointer text-[1.1rem] bg-transparent flex justify-center items-center font-light focus:outline-none selection:bg-transparent data-[selected=true]:text-white data-[selected=true]:bg-[#3b71ca] data-[selected=true]:font-normal" - style="left: 59px; bottom: 18.7372px;" - > - <span>7</span> - </span> - <span - onClick={() => - onChange(AbsoluteTime.fromStampMs(setHours(date, 8).getTime())) - } - class="absolute rounded-[100%] w-[32px] h-[32px] text-center cursor-pointer text-[1.1rem] bg-transparent flex justify-center items-center font-light focus:outline-none selection:bg-transparent data-[selected=true]:text-white data-[selected=true]:bg-[#3b71ca] data-[selected=true]:font-normal" - style="left: 18.7372px; bottom: 59px;" - > - <span>8</span> - </span> - <span - onClick={() => - onChange(AbsoluteTime.fromStampMs(setHours(date, 9).getTime())) - } - class="absolute rounded-[100%] w-[32px] h-[32px] text-center cursor-pointer text-[1.1rem] bg-transparent flex justify-center items-center font-light focus:outline-none selection:bg-transparent data-[selected=true]:text-white data-[selected=true]:bg-[#3b71ca] data-[selected=true]:font-normal" - style="left: 4px; bottom: 114px;" - > - <span>9</span> - </span> - <span - onClick={() => - onChange(AbsoluteTime.fromStampMs(setHours(date, 10).getTime())) - } - class="absolute rounded-[100%] w-[32px] h-[32px] text-center cursor-pointer text-[1.1rem] bg-transparent flex justify-center items-center font-light focus:outline-none selection:bg-transparent data-[selected=true]:text-white data-[selected=true]:bg-[#3b71ca] data-[selected=true]:font-normal" - style="left: 18.7372px; bottom: 169px;" - > - <span>10</span> - </span> - <span - onClick={() => - onChange(AbsoluteTime.fromStampMs(setHours(date, 11).getTime())) - } - class="absolute rounded-[100%] w-[32px] h-[32px] text-center cursor-pointer text-[1.1rem] bg-transparent flex justify-center items-center font-light focus:outline-none selection:bg-transparent data-[selected=true]:text-white data-[selected=true]:bg-[#3b71ca] data-[selected=true]:font-normal" - style="left: 59px; bottom: 209.263px;" - > - <span>11</span> - </span> - </div> - </div> - </div> - <div - id="" - class="rounded-b-lg flex justify-between items-center w-full h-[56px] px-[12px] bg-white dark:bg-zinc-500" - > - <div class="w-full flex justify-end"> - <button - type="submit" - onClick={onConfirm} - class="rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600" - > - <i18n.Translate>Confirm</i18n.Translate> - </button> - </div> - </div> - </Fragment> - ); -} diff --git a/packages/web-util/src/forms/gana/gls_merchant_onboarding.stories.tsx b/packages/web-util/src/forms/gana/gls_merchant_onboarding.stories.tsx @@ -1,44 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ - -import { i18n, setupI18n } from "@gnu-taler/taler-util"; -import * as tests from "../../tests/hook.js"; -import { DefaultForm as TestedComponent } from "../forms-ui.js"; -import { gls_merchant_onboarding } from "./gls_merchant_onboarding.js"; - -export default { - title: "GLS_Onboarding", -}; - -export namespace Simplest { - export interface Form { - comment: string; - } -} - -setupI18n("en", {}); -type TargetObject = {}; -const initial: TargetObject = {}; - -export const SimpleUsage = tests.createExample(TestedComponent, { - initial, - design: gls_merchant_onboarding(i18n), -}); diff --git a/packages/web-util/src/forms/gana/gls_merchant_onboarding.ts b/packages/web-util/src/forms/gana/gls_merchant_onboarding.ts @@ -1,377 +0,0 @@ -import { TalerFormAttributes, TranslatedString } from "@gnu-taler/taler-util"; -import { intervalToDuration, isFuture, isValid, parse } from "date-fns"; -import { InternationalizationAPI } from "../../context/translation.js"; -import { DoubleColumnFormDesign, FormMetadata } from "../forms-types.js"; -import { - countryNameList, - countryNationalityList, - drilldownGlsIndustries, - germanBusinessTypes, -} from "../../utils/select-ui-lists.js"; - -export const form_gls_merchant_onboarding = ( - i18n: InternationalizationAPI, -): FormMetadata => ({ - config: gls_merchant_onboarding(i18n, {}), - id: "gls-merchant-onboarding", - label: "GLS Merchant Onboarding", - version: 1, -}); - -function validateDateOfBirth( - i18n: InternationalizationAPI, - text: string, - _form: any, -): TranslatedString | undefined { - // Date is stored as ISO timestamp - const time = parse(text, "yyyy-MM-dd", new Date()); - if (!isValid(time)) { - return i18n.str`invalid format`; - } - if (isFuture(time)) { - return i18n.str`it can't be in the future`; - } - const { years } = intervalToDuration({ - start: time, - end: new Date(), - }); - if (years && years > 120) { - return i18n.str`it can't be greater than 120 years`; - } - return undefined; -} - -function validateFoundingDate( - i18n: InternationalizationAPI, - text: string, - _form: any, -): TranslatedString | undefined { - // Date is stored as ISO timestamp - const time = parse(text, "yyyy-MM-dd", new Date()); - if (!isValid(time)) { - return i18n.str`invalid format`; - } - if (isFuture(time)) { - return i18n.str`it can't be in the future`; - } - const { years } = intervalToDuration({ - start: time, - end: new Date(), - }); - if (years && years > 120) { - return i18n.str`it can't be greater than 120 years`; - } - return undefined; -} - -function validateEmail( - i18n: InternationalizationAPI, - text: string, - _form: any, -): TranslatedString | undefined { - const re = /^\S+@\S+\.\S+$/; - if (re.test(text)) { - return undefined; - } - return i18n.str`Invalid email address`; -} - -function validatePhone( - i18n: InternationalizationAPI, - text: string, - _form: any, -): TranslatedString | undefined { - const re = /^[+]?([0-9]+[. ]*)+$/; - if (re.test(text)) { - return undefined; - } - return i18n.str`Invalid phone number`; -} - -export function gls_merchant_onboarding( - i18n: InternationalizationAPI, - context?: any, -): DoubleColumnFormDesign { - return { - type: "double-column", - title: "Merchant Onboarding Information", - sections: [ - { - title: i18n.str`Personal Details`, - description: i18n.str`Personal details of the authorised representative.`, - fields: [ - { - id: TalerFormAttributes.PERSON_FIRST_NAMES, - label: i18n.str`First name(s)`, - help: i18n.str`As on your ID document`, - type: "text", - required: true, - }, - { - id: TalerFormAttributes.PERSON_LAST_NAME, - label: i18n.str`Last name`, - type: "text", - required: true, - }, - { - id: TalerFormAttributes.DATE_OF_BIRTH, - label: i18n.str`Date of birth`, - type: "isoDateText", - placeholder: "dd.MM.yyyy", - pattern: "dd.MM.yyyy", - required: true, - validator: (text, form) => validateDateOfBirth(i18n, text, form), - }, - { - id: TalerFormAttributes.NATIONALITY, - label: i18n.str`Nationality`, - type: "selectOne", - choices: countryNationalityList(i18n), - required: true, - }, - { - id: TalerFormAttributes.CONTACT_PHONE, - label: i18n.str`Phone number`, - type: "text", - required: true, - validator: (text, form) => validatePhone(i18n, text, form), - }, - { - id: TalerFormAttributes.CONTACT_EMAIL, - label: i18n.str`E-Mail`, - type: "text", - required: true, - validator: (text, form) => validateEmail(i18n, text, form), - }, - ], - }, - { - title: i18n.str`Company information`, - fields: [ - { - id: TalerFormAttributes.BUSINESS_DISPLAY_NAME, - label: i18n.str`Name of the company`, - type: "text", - required: true, - }, - { - id: TalerFormAttributes.BUSINESS_TYPE, - label: i18n.str`Legal form`, - required: true, - type: "selectOne", - choices: germanBusinessTypes(i18n), - }, - { - id: TalerFormAttributes.BUSINESS_TYPE_OTHER, - label: i18n.str`Legal form (free-form entry for other)`, - hide(value, root) { - return root[TalerFormAttributes.BUSINESS_TYPE] !== "OTHER"; - }, - required: true, - type: "text", - }, - { - id: TalerFormAttributes.COMMERCIAL_REGISTER_NUMBER, - label: i18n.str`Commercial register number`, - type: "text", - required: true, - }, - { - id: TalerFormAttributes.REGISTER_COURT_LOCATION, - label: i18n.str`Location of the registration court`, - type: "text", - required: true, - }, - { - id: TalerFormAttributes.FOUNDING_DATE, - label: i18n.str`Founding date`, - type: "isoDateText", - placeholder: "dd.MM.yyyy", - pattern: "dd.MM.yyyy", - required: true, - validator: (text, form) => validateFoundingDate(i18n, text, form), - }, - { - id: TalerFormAttributes.BUSINESS_IS_NON_PROFIT, - label: i18n.str`Is the company a non-profit organization?`, - required: true, - type: "choiceHorizontal", - choices: [ - { - label: "Yes", - value: true, - }, - { - label: "No", - value: false, - }, - ], - }, - { - id: TalerFormAttributes.BUSINESS_INDUSTRY, - label: i18n.str`Industry`, - required: true, - type: "drilldown", - choices: drilldownGlsIndustries, - }, - ], - }, - { - title: i18n.str`Company address`, - fields: [ - { - id: TalerFormAttributes.DOMICILE_ADDRESS, - label: i18n.str`Address`, - type: "textArea", - required: true, - }, - { - id: TalerFormAttributes.ADDRESS_COUNTRY, - label: i18n.str`Country`, - type: "selectOne", - choices: countryNameList(i18n), - required: true, - }, - ], - }, - { - title: i18n.str`Tax information`, - fields: [ - { - id: TalerFormAttributes.DE_BUSINESS_OR_TAX_ID, - label: i18n.str`Business identification number or tax number`, - type: "text", - required: true, - }, - { - id: TalerFormAttributes.TAX_IS_USA_LAW, - label: i18n.str`Was the company incorporated in the USA or under US law?`, - required: true, - type: "choiceHorizontal", - choices: [ - { - label: "Yes", - value: true, - }, - { - label: "No", - value: false, - }, - ], - }, - { - id: TalerFormAttributes.TAX_IS_ACTIVE, - label: i18n.str`Economically active or inactive?`, - type: "choiceHorizontal", - choices: [ - { - label: "Active", - value: "ACTIVE", - }, - { - label: "Inactive", - value: "INACTIVE", - }, - ], - required: true, - }, - { - id: TalerFormAttributes.TAX_IS_DEDUCTED, - label: i18n.str`Eligible for input tax deduction`, - type: "choiceHorizontal", - choices: [ - { - label: "Yes", - value: true, - }, - { - label: "No", - value: false, - }, - ], - required: true, - }, - ], - }, - { - title: i18n.str`Persons`, - description: i18n.str`Please list all legal representatives, shareholders/partners, and authorized signatories.`, - fields: [ - { - id: TalerFormAttributes.BUSINESS_PERSONS, - label: i18n.str`Legal representatives / shareholders / partners / authorized signatories`, - type: "array", - labelFieldId: TalerFormAttributes.PERSON_LAST_NAME, - fields: [ - { - id: TalerFormAttributes.PERSON_FIRST_NAMES, - label: i18n.str`First name(s)`, - type: "text", - required: true, - }, - { - id: TalerFormAttributes.PERSON_LAST_NAME, - label: i18n.str`Last name`, - type: "text", - required: true, - }, - { - id: TalerFormAttributes.DATE_OF_BIRTH, - label: i18n.str`Date of birth`, - type: "isoDateText", - placeholder: "dd.MM.yyyy", - pattern: "dd.MM.yyyy", - required: true, - validator: (text, form) => - validateDateOfBirth(i18n, text, form), - }, - { - id: TalerFormAttributes.NATIONALITY, - label: i18n.str`Nationality`, - type: "selectOne", - choices: countryNationalityList(i18n), - required: true, - }, - { - id: TalerFormAttributes.REPRESENTATIVE_TYPE, - label: i18n.str`Type of representative`, - type: "choiceStacked", - choices: [ - { - label: "Shareholder (at least 25% of shares)", - value: "SHAREHOLDER_GT_25_PERCENT", - }, - { - label: "Legal representative", - value: "LEGAL_REPRESENTATIVE", - }, - { - label: "Authorized employee with account access", - value: "AUTHORIZED_EMPLOYEE", - }, - ], - }, - ], - required: true, - }, - ], - }, - { - title: i18n.str`New Customer Identification`, - fields: [ - { - type: "caption", - label: - "Please complete the customer registration and identification for the authorized representative and other persons listed in this form.", - }, - { - type: "external-link", - url: "https://kontoeroeffnung.gls.de/kundenanlage/gks-v", - id: "none", - label: "GLS Customer Registration", - }, - ], - }, - ], - }; -} diff --git a/packages/web-util/src/forms/gana/gls_wallet_confirmation.stories.tsx b/packages/web-util/src/forms/gana/gls_wallet_confirmation.stories.tsx @@ -1,44 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ - -import { i18n, setupI18n } from "@gnu-taler/taler-util"; -import * as tests from "../../tests/hook.js"; -import { DefaultForm as TestedComponent } from "../forms-ui.js"; -import { gls_wallet_confirmation } from "./gls_wallet_confirmation.js"; - -export default { - title: "gls_wallet_confirmation", -}; - -export namespace Simplest { - export interface Form { - comment: string; - } -} - -setupI18n("en", {}); -type TargetObject = {}; -const initial: TargetObject = {}; - -export const SimpleUsage = tests.createExample(TestedComponent, { - initial, - design: gls_wallet_confirmation(i18n), -}); diff --git a/packages/web-util/src/forms/gana/gls_wallet_confirmation.ts b/packages/web-util/src/forms/gana/gls_wallet_confirmation.ts @@ -1,46 +0,0 @@ -import { TalerFormAttributes } from "@gnu-taler/taler-util"; -import { InternationalizationAPI } from "../../context/translation.js"; -import { DoubleColumnFormDesign, FormMetadata } from "../forms-types.js"; - -export const form_gls_wallet_confirmation = ( - i18n: InternationalizationAPI, -): FormMetadata => ({ - config: gls_wallet_confirmation(i18n, {}), - id: "gls-wallet-confirmation", - label: "GLS Wallet Confirmation", - version: 1, -}); - -export function gls_wallet_confirmation( - i18n: InternationalizationAPI, - context?: any, -): DoubleColumnFormDesign { - return { - type: "double-column", - title: "GLS Wallet Confirmation", - sections: [ - { - title: i18n.str`Confirmation`, - description: i18n.str`Confirmation of private customer / wallet.`, - fields: [ - { - id: TalerFormAttributes.WALLET_USER_IS_PRIVATE_CUSTOMER, - label: i18n.str`Please confirm that you are a private customer that wants to redeem their wallet balance.`, - type: "choiceHorizontal", - required: true, - choices: [ - { - label: "Yes", - value: true, - }, - { - label: "No", - value: false, - }, - ], - }, - ], - }, - ], - }; -} diff --git a/packages/web-util/src/forms/gana/index.stories.ts b/packages/web-util/src/forms/gana/index.stories.ts @@ -1,9 +1,7 @@ export * as accept_tops_stories from "./accept-tos.stories.js"; export * as generic_note_stories from "./generic_note.stories.js"; export * as generic_upload_stories from "./generic_upload.stories.js"; - -export * as gls_onboarding_stories from "./gls_merchant_onboarding.stories.js"; -export * as gls_wallet_confirmation_stories from "./gls_wallet_confirmation.stories.js"; +export * as personal_info_stories from "./personal-info.stories.js"; export * as vqf_902_11_customer_stories from "./VQF_902_11_customer.stories.js"; export * as vqf_902_11_officer_stories from "./VQF_902_11_officer.stories.js"; diff --git a/packages/web-util/src/forms/gana/personal-info.stories.tsx b/packages/web-util/src/forms/gana/personal-info.stories.tsx @@ -0,0 +1,39 @@ +/* + This file is part of GNU Taler + (C) 2026 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +import { Amounts, i18n, setupI18n } from "@gnu-taler/taler-util"; +import * as tests from "../../tests/hook.js"; +import { DefaultForm } from "../forms-ui.js"; +import { personalInfo } from "./personal-info.js"; + +setupI18n("en", {}); + +const design = personalInfo(i18n); + +export const Empty = tests.createExample(DefaultForm, { + initial: {}, + design, +}); + +export const Prefilled = tests.createExample(DefaultForm, { + initial: { + trucker: "yes", + money: Amounts.parseOrThrow("YEIN:100"), + }, + design, +}); + +export default { title: "personal info" }; diff --git a/packages/web-util/src/forms/index.ts b/packages/web-util/src/forms/index.ts @@ -21,8 +21,6 @@ import { form_challenger_email } from "./gana/challenger_email.js"; import { form_challenger_postal } from "./gana/challenger_postal.js"; import { form_challenger_sms } from "./gana/challenger_sms.js"; import { form_generic_note } from "./gana/generic_note.js"; -import { form_gls_merchant_onboarding } from "./gana/gls_merchant_onboarding.js"; -import { form_gls_wallet_confirmation } from "./gana/gls_wallet_confirmation.js"; import { form_multi_upload } from "./gana/multi_upload.js"; import { nameAndDob } from "./gana/nameAndBirthdate.js"; import { simplest } from "./gana/simplest.js"; @@ -64,9 +62,6 @@ export * from "./gana/challenger_postal.js"; export * from "./gana/challenger_sms.js"; export * from "./gana/generic_note.js"; -export * from "./gana/gls_merchant_onboarding.js"; -export * from "./gana/gls_wallet_confirmation.js"; - export * from "./gana/VQF_902_11_customer.js"; export * from "./gana/VQF_902_11_officer.js"; export * from "./gana/VQF_902_14.js"; @@ -79,7 +74,6 @@ export * from "./gana/VQF_902_9_officer.js"; export * from "./Group.js"; export * from "./HtmlIframe.js"; -export * from "./TimePicker.js"; export const preloadedForms: ( i18n: InternationalizationAPI, @@ -116,6 +110,4 @@ export const preloadedForms: ( form_vqf_902_11_officer(i18n), form_vqf_902_14(i18n), form_generic_note(i18n), - form_gls_merchant_onboarding(i18n), - form_gls_wallet_confirmation(i18n), ]; diff --git a/packages/web-util/src/utils/select-ui-lists.ts b/packages/web-util/src/utils/select-ui-lists.ts @@ -1,6 +1,6 @@ /* This file is part of GNU Taler - (C) 2022-2024 Taler Systems S.A. + (C) 2022-2026 Taler Systems S.A. GNU Taler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -17,21 +17,10 @@ import { countryNamesByCode, countryNationalitiesByCode, - currencyNamesByCode, - langNamesByCode, } from "@gnu-taler/taler-util"; import { InternationalizationAPI } from "../context/translation.js"; import { SelectUiChoice } from "../forms/forms-types.js"; -export function currencyNameList( - i18n: InternationalizationAPI, -): SelectUiChoice[] { - return Object.entries(currencyNamesByCode).map(([value, translator]) => ({ - value, - label: translator(i18n), - })); -} - export function countryNameList( i18n: InternationalizationAPI, ): SelectUiChoice[] { @@ -51,523 +40,3 @@ export function countryNationalityList( }), ); } - -export function languageNameList( - i18n: InternationalizationAPI, -): SelectUiChoice[] { - return Object.entries(langNamesByCode).map(([value, translator]) => ({ - value, - label: translator(i18n), - })); -} - -export const germanBusinessTypesList = { - DE_GMBH: (i18n: InternationalizationAPI) => i18n.str`GmbH`, - DE_GMBH_IG: (i18n: InternationalizationAPI) => i18n.str`GmbH i.G.`, - DE_UG: (i18n: InternationalizationAPI) => i18n.str`UG`, - DE_UG_IG: (i18n: InternationalizationAPI) => i18n.str`UG i.G.`, - DE_OHG: (i18n: InternationalizationAPI) => i18n.str`UHG`, - DE_KG: (i18n: InternationalizationAPI) => i18n.str`KG`, - DE_EV: (i18n: InternationalizationAPI) => i18n.str`e.V.`, - DE_EV_IG: (i18n: InternationalizationAPI) => i18n.str`e.V. i.G.`, - DE_EG: (i18n: InternationalizationAPI) => i18n.str`eG`, - DE_EG_IG: (i18n: InternationalizationAPI) => i18n.str`eG i.G.`, - DE_PARTG: (i18n: InternationalizationAPI) => i18n.str`PartG`, - DE_EK: (i18n: InternationalizationAPI) => i18n.str`e.K.`, - DE_AG_UNLISTED: (i18n: InternationalizationAPI) => - i18n.str`AG (nicht börsennotiert)`, - DE_AG_LISTED: (i18n: InternationalizationAPI) => i18n.str`AG (börsennotiert)`, - DE_GBR: (i18n: InternationalizationAPI) => i18n.str`GbR`, - DE_NEV: (i18n: InternationalizationAPI) => i18n.str`n.e.V.`, - DE_PARTEI: (i18n: InternationalizationAPI) => i18n.str`Partei`, - DE_WEG: (i18n: InternationalizationAPI) => i18n.str`WEG`, - OTHER: (i18n: InternationalizationAPI) => i18n.str`Anderes`, -}; - -export function germanBusinessTypes( - i18n: InternationalizationAPI, -): SelectUiChoice[] { - return Object.entries(germanBusinessTypesList).map(([value, translator]) => ({ - value, - label: translator(i18n), - })); -} - -export const drilldownGlsIndustries = { - "Land- und Forstwirtschaft, Fischerei": { - "Landwirtschaft, Jagd": { - Pflanzenbau: "aaa", - Tierhaltung: "aab", - "Gemischte Landwirtschaft": "aac", - "Erbringung von landwirtschaftlichen und gärtnerischen Dienstleistungen": - "aad", - Jagd: "aae", - }, - "Forstwirtschaft, Fischerei, Fischzucht": { - "Erbringung von forstwirtschaftlichen Dienstleistungen": "aba", - Fischerei: "abb", - }, - }, - "Bergbau und Gewinnung von Steinen und Erden": { - "Kohlenbergbau, Torfgewinnung, Erdöl, Erdgas, Erzbergbau": { - "Steinkohlenbergbau und -brikettherstellung": "baa", - "Gewinnung von Erdöl und Erdgas": "bab", - Eisenerzbergbau: "bac", - }, - "Gewinnung von Steinen und Erden, sonstiger Bergbau": { - "Gewinnung von Natursteinen": "bba", - "Gewinnung von Kies, Sand, Ton und Kaolin": "bbb", - "Gewinnung von Mineralien für die Herstellung von chemischen Erzeugnissen": - "bbc", - "Gewinnung von Salz": "bbd", - "Gewinnung von Steinen und Erden, anderweitig nicht genannt, sonstiger Bergbau": - "bbe", - }, - }, - "Verarbeitendes Gewerbe": { - Ernährungsgewerbe: { - "Schlachten und Fleischverarbeitung": "caa", - Fischverarbeitung: "cab", - "Obst- und Gemüseverarbeitung": "cac", - "Herstellung von pflanzlichen und tierischen Ölen und Fetten": "cad", - "Milchverarbeitung, Herstellung von Speiseeis": "cae", - "Mahl- und Schälmühlen, Herstellung von Stärke und Stärkeerzeugnissen": - "caf", - "Herstellung von Futtermitteln": "cag", - "Sonstiges Ernährungsgewerbe (ohne Getränkeherstellung)": "cah", - "Herstellung von Getränken": "cai", - }, - "Textil-, Bekleidungs-, Ledergewerbe": { - "Spinnstoffaufbereitung und Spinnerei": "cba", - Weberei: "cbb", - Textilveredlung: "cbc", - "Herstellung von konfektionierten Textilwaren (ohne Bekleidung)": "cbd", - "Sonstiges Textilgewerbe (ohne Herstellung von Maschenware)": "cbe", - "Herstellung von gewirktem und gestricktem Stoff": "cbf", - "Herstellung von gewirkten und gestrickten Fertigerzeugnissen": "cbg", - "Herstellung von Lederbekleidung": "cbh", - "Herstellung von Bekleidung (ohne Lederbekleidung)": "cbi", - "Zurichtung und Färben von Fellen, Herstellung von Pelzwaren": "cbj", - "Herstellung von Leder und Lederfaserstoff": "cbk", - "Lederverarbeitung (ohne Herstellung von Lederbekleidung und Schuhen)": - "cbl", - "Herstellung von Schuhen": "cbm", - }, - "Holzgewerbe (ohne Herstellung von Möbeln)": { - "Säge-, Hobel- und Holzimprägnierwerke": "cca", - "Herstellung von Furnier-, Sperrholz-, Holzfaser- und Holzspanplatten": - "ccb", - "Herstellung von Konstruktionsteilen, Fertigbauteilen, Ausbauelementen und Fertigteilbauten aus Holz": - "ccc", - "Herstellung von Verpackungsmitteln, Lagerbehältern und Ladungsträgern aus Holz": - "ccd", - "Herstellung von Holzwaren, anderweitig nicht genannt, sowie von Kork-, Flecht- und Korbwaren (ohne Herstellung von Möbeln)": - "cce", - }, - "Papier-, Verlags-, Druckgewerbe": { - "Herstellung von Holz- und Zellstoff, Papier, Karton und Pappe": "cda", - "Herstellung von Waren aus Papier, Karton und Pappe": "cdb", - Verlagsgewerbe: "cdc", - Druckgewerbe: "cdd", - "Vervielfältigung von bespielten Ton-, Bild- und Datenträgern": "cde", - }, - "Kokerei, Mineralölverarbeitung": { - Kokerei: "cea", - Mineralölverarbeitung: "ceb", - }, - "Herstellung von chemischen und pharmazeutischen Erzeugnissen": { - "Herstellung von chemischen Grundstoffen": "cfa", - "Herstellung von Schädlingsbekämpfungs-, Pflanzenschutz- und Desinfektionsmitteln": - "cfb", - "Herstellung von Anstrichmitteln, Druckfarben und Kitten": "cfc", - "Herstellung von pharmazeutischen Erzeugnissen": "cfd", - "Herstellung von Seifen, Wasch-, Reinigungs- und Körperpflegemitteln sowie von Duftstoffen": - "cfe", - "Herstellung von sonstigen chemischen Erzeugnissen": "cff", - "Herstellung von Chemiefasern": "cfg", - }, - "Herstellung von Gummi- und Kunststoffwaren": { - "Herstellung von Gummiwaren": "cga", - "Herstellung von Kunststoffwaren": "cgb", - }, - "Herstellung von Glas und Glaswaren, Keramik, Verarbeitung von Steinen und Erden": - { - "Herstellung von Glas und Glaswaren": "cha", - "Herstellung von keramischen Erzeugnissen (ohne Herstellung von Ziegeln und Baukeramik)": - "chb", - "Herstellung von keramischen Wand- und Bodenfliesen und -platten": - "chc", - "Herstellung von Ziegeln und sonstiger Baukeramik": "chd", - "Herstellung von Zement, Kalk und gebranntem Gips": "che", - "Herstellung von Erzeugnissen aus Beton, Zement und Gips": "chf", - "Be- und Verarbeitung von Naturwerksteinen und Natursteinen, anderweitig nicht genannt": - "chg", - "Herstellung von sonstigen Erzeugnissen aus nicht metallischen Mineralien": - "chh", - }, - "Metallerzeugung und -bearbeitung": { - "Erzeugung von Roheisen, Stahl und Ferrolegierungen": "cia", - "Herstellung von Rohren": "cib", - "Sonstige erste Bearbeitung von Eisen und Stahl": "cic", - "Erzeugung und erste Bearbeitung von NE-Metallen": "cid", - Gießereien: "cie", - }, - "Herstellung von Metallerzeugnissen": { - "Stahl- und Leichtmetallbau": "cja", - "Herstellung von Metallbehältern mit einem Fassungsvermögen von mehr als 300 l, Herstellung von Heizkörpern und -kesseln für Zentralheizungen": - "cjb", - "Herstellung von Dampfkesseln (ohne Zentralheizungskessel)": "cjc", - "Herstellung von Schmiede-, Press-, Zieh- und Stanzteilen, gewalzten Ringen und pulvermetallurgischen Erzeugnissen": - "cjd", - "Oberflächenveredlung und Wärmebehandlung, Mechanik, anderweitig nicht genannt": - "cje", - "Herstellung von Schneidwaren, Werkzeugen, Schlössern und Beschlägen aus unedlen Metallen": - "cjf", - "Herstellung von sonstigen Metallwaren": "cjg", - }, - Maschinenbau: { - "Herstellung von Maschinen für die Erzeugung und Nutzung von mechanischer Energie (ohne Motoren für Luft- und Straßenfahrzeuge)": - "cka", - "Herstellung von sonstigen nicht wirtschaftszweigspezifischen Maschinen": - "ckb", - "Herstellung von land- und forstwirtschaftlichen Maschinen": "ckc", - "Herstellung von Werkzeugmaschinen": "ckd", - "Herstellung von Maschinen für sonstige bestimmte Wirtschaftszweige": - "cke", - "Herstellung von Haushaltsgeräten, anderweitig nicht genannt": "ckf", - "Reparatur von sonstigen Ausrüstungen": "ckg", - }, - "Herstellung von Büromaschinen, Datenverarbeitungsgeräten und -einrichtungen": - { - "Herstellung von Büromaschinen": "cla", - "Herstellung von Datenverarbeitungsgeräten und -einrichtungen": "clb", - "Reparatur von Datenverarbeitungs- und Telekommunikationsgeräten": - "clc", - }, - "Herstellung von Geräten der Elektrizitätserzeugung, -verteilung": { - "Herstellung von Elektromotoren, Generatoren und Transformatoren": "cma", - "Herstellung von Elektrizitätsverteilungs- und -schalteinrichtungen": - "cmb", - "Herstellung von isolierten Elektrokabeln, -leitungen und -drähten": - "cmc", - "Herstellung von Akkumulatoren und Batterien": "cmd", - "Herstellung von elektrischen Lampen und Leuchten": "cme", - "Herstellung von elektrischen Ausrüstungen, anderweitig nicht genannt": - "cmf", - }, - "Rundfunk- und Nachrichtentechnik": { - "Herstellung von elektronischen Bauelementen": "cna", - "Herstellung von Geräten und Einrichtungen der Telekommunikationstechnik": - "cnb", - "Herstellung von Rundfunkgeräten sowie phono- und videotechnischen Geräten": - "cnc", - }, - "Medizin-, Mess-, Steuer- und Regelungstechnik, Optik, Herstellung von Uhren": - { - "Herstellung von medizinischen Geräten und orthopädischen Erzeugnissen": - "coa", - "Herstellung von Mess-, Kontroll-, Navigations- u.ä. Instrumenten und Vorrichtungen": - "cob", - "Herstellung von industriellen Prozesssteuerungseinrichtungen": "coc", - "Herstellung von optischen und fotografischen Geräten": "cod", - "Herstellung von Uhren": "coe", - "Reparatur von Haushaltswaren und Ziergegenständen aus Glas, Ton, Steinzeug und Porzellan": - "cof", - }, - "Herstellung von Kraftwagen, Kraftwagenteilen": { - "Herstellung von Kraftwagen und Kraftwagenmotoren": "cpa", - "Herstellung von Karosserien, Aufbauten und Anhängern": "cpb", - "Herstellung von Teilen und Zubehör für Kraftwagen und Kraftwagenmotoren": - "cpc", - }, - "Sonstiger Fahrzeugbau": { - "Schiff- und Bootsbau": "cqa", - Bahnindustrie: "cqb", - "Luft- und Raumfahrzeugbau": "cqc", - "Herstellung von Krafträdern, Fahrrädern und Behindertenfahrzeugen": - "cqd", - "Fahrzeugbau, anderweitig nicht genannt": "cqe", - }, - "Herstellung von Möbeln, Schmuck, Musikinstrumenten, Sportgeräten, Spielwaren, sonstigen Erzeugnissen": - { - "Herstellung von Möbeln": "cra", - "Herstellung von Schmuck u.ä. Erzeugnissen": "crb", - "Herstellung von Musikinstrumenten": "crc", - "Herstellung von Sportgeräten": "crd", - "Herstellung von Spielwaren": "cre", - "Herstellung von sonstigen Erzeugnissen": "crf", - }, - Recycling: { - "Recycling von metallischen Altmaterialien und Reststoffen": "csa", - "Recycling von nicht metallischen Altmaterialien und Reststoffen": "csb", - }, - }, - "Energie- und Wasserversorgung, Baugewerbe": { - Energieversorgung: { - Elektrizitätsversorgung: "daa", - Gasversorgung: "dab", - Wärmeversorgung: "dac", - }, - Wasserversorgung: { - "Wassergewinnung mit Fremdbezug zur Verteilung": "dba", - "Wassergewinnung ohne Fremdbezug zur Verteilung": "dbb", - }, - Baugewerbe: { - "Vorbereitende Baustellenarbeiten": "dca", - "Hoch- und Tiefbau": "dcb", - Bauinstallation: "dcc", - "Sonstiges Ausbaugewerbe": "dcd", - "Vermietung von Baumaschinen und -geräten mit Bedienungspersonal": "dce", - }, - }, - "Handel, Instandhaltung und Reparatur von Kraftfahrzeugen, Tankstellen": { - "Kraftfahrzeughandel, Instandhaltung und Reparatur von Kraftfahrzeugen, Tankstellen": - { - "Handel mit Kraftwagen": "eaa", - "Instandhaltung und Reparatur von Kraftwagen": "eab", - "Handel mit Kraftwagenteilen und -zubehör": "eac", - "Handel mit Krafträdern, Kraftradteilen und -zubehör, Instandhaltung und Reparatur von Krafträdern": - "ead", - Tankstellen: "eae", - }, - "Handelsvermittlung, Großhandel": { - Handelsvermittlung: "eba", - "Großhandel mit landwirtschaftlichen Grundstoffen und lebenden Tieren": - "ebb", - "Großhandel mit Nahrungsmitteln, Getränken und Tabakwaren": "ebc", - "Großhandel mit Gebrauchs- und Verbrauchsgütern": "ebd", - "Großhandel mit nicht landwirtschaftlichen Halbwaren, Altmaterialien und Reststoffen": - "ebe", - "Großhandel mit Maschinen, Ausrüstungen und Zubehör": "ebf", - "Sonstiger Großhandel": "ebg", - }, - Einzelhandel: { - "Einzelhandel mit Waren verschiedener Art (in Verkaufsräumen)": "eca", - "Facheinzelhandel mit Nahrungsmitteln, Getränken und Tabakwaren (in Verkaufsräumen)": - "ecb", - "Apotheken, Facheinzelhandel mit medizinischen, orthopädischen und kosmetischen Artikeln (in Verkaufsräumen)": - "ecc", - "Sonstiger Facheinzelhandel (in Verkaufsräumen)": "ecd", - "Einzelhandel mit Antiquitäten und Gebrauchtwaren (in Verkaufsräumen)": - "ece", - "Einzelhandel (nicht in Verkaufsräumen)": "ecf", - "Reparatur von Gebrauchsgütern": "ecg", - }, - }, - Gastgewerbe: { - Beherbergung: { - Hotellerie: "faa", - "Sonstiges Beherbergungsgewerbe": "fab", - }, - Gastronomie: { - "Speisengeprägte Gastronomie": "fba", - "Getränkegeprägte Gastronomie": "fbb", - "Kantinen und Caterer": "fbc", - }, - }, - "Verkehr und Lagerei": { - "Landverkehr, Transport in Rohrfernleitungen": { - Eisenbahnverkehr: "gaa", - "Sonstiger Landverkehr": "gab", - "Transport in Rohrfernleitungen": "gac", - "Deutsche Bahn AG": "gad", - }, - "Schifffahrt, Luftfahrt": { - "See- und Küstenschifffahrt": "gba", - Binnenschifffahrt: "gbb", - Linienflugverkehr: "gbc", - }, - "Lagerei sowie Erbringung von sonstigen Dienstleistungen für den Verkehr": { - "Frachtumschlag und Lagerei": "gca", - "Sonstige Hilfs- und Nebentätigkeiten für den Verkehr": "gcb", - "Reisebüros und Reiseveranstalter": "gcc", - "Spedition, sonstige Verkehrsvermittlung": "gcd", - }, - "Post-, Kurier- und Expressdienste": { - "Postverwaltung und private Post- und Kurierdienste": "gda", - Fernmeldedienste: "gdb", - "Telekom AG": "gdc", - "Deutsche Post AG": "gdd", - }, - }, - "Erbringung von Finanz- und Versicherungsdienstleistungen": { - "Kreditgewerbe, Versicherungsgewerbe": { - Wertpapierfirma: "haa", - "Sonstige Finanzierungsinstitutionen": "hab", - "Fonds von Kapitalgesellschaften": "hac", - "Ausländ. Finanzges. Als Kreditinst. Gem. §1Abs.1KWG": "had", - Geldmarktfonds: "hae", - "Sonstiges Versicherungsgewerbe": "hag", - }, - "Mit Finanz- und Versicherungsdienstleistungen verbundene Tätigkeiten": { - "Mit dem Kreditgewerbe verbundene Tätigkeiten": "hba", - "Mit dem Versicherungsgewerbe verbundene Tätigkeiten": "hbb", - "Börseneinrichtungen mit tägl. Einschüssen": "hbc", - Postgiroämter: "hae", - "Zuständige genossenschaftliche Zentralbank": "hbg", - "Andere Genossenschaftliche Zentralbanken": "hbh", - "Angeschlossene Kreditgenoss.(nur für genoss. Zentralbanken)": "hbi", - "Sonstige mindestreservepflichtige Kreditinstitute": "hbj", - "Ausländische Kreditinstitute gem. § 53 KWG": "hbk", - "Internationale Organisationen im Bereich KI": "hbl", - "Multilaterale Entwicklungsbanken nicht mindestreservefrei und ohne Nullgewichtung": - "hbm", - "LbNRW/InvB Berlin/Hessen/WK/LaBo/BremAB": "hbo", - "Multilaterale Entwicklungsbanken nicht mindestreservefrei mit Nullgewichtung": - "hbp", - "Sonstige mindestreservefreie Kreditinstitute": "hbq", - "Internat. Organisationen im Bereich KI (AMR-frei)": "hbr", - "Europäische Investitionsbank": "hbs", - "Multilaterale Entwicklungsbanken (AMR-frei)": "hbt", - "Multilaterale Entwicklungsbanken mindestreservefrei und mit Nullgewichtung": - "hbu", - }, - }, - "Grundstücks- und Wohnungswesen, Vermietung (inkl. Bewegl. Sachen)": { - "Grundstücks- und Wohnungswesen, Vermietung n. bewegl. Sachen": { - "Erschließung, Kauf und Verkauf von Grundstücken, Gebäuden und Wohnungen": - "iaa", - "Vermietung und Verpachtung von eigenen Grundstücken, Gebäuden und Wohnungen": - "iab", - "Vermittlung und Verwaltung von fremden Grundstücken, Gebäuden und Wohnungen": - "iac", - "Vermietung und Verpachtung von eigenen Grundstücken und Nichtwohngebäuden und Bauträger für Nichtwohngebäude": - "iad", - }, - "Vermietung beweglicher Sachen": { - "Vermietung von Kraftwagen bis 3,5 t Gesamtgewicht": "iba", - "Vermietung von Maschinen und Geräten": "ibb", - "Vermietung von Gebrauchsgütern, anderweitig nicht genannt": "ibc", - "Leasing von nichtfinanziellen immatriellen Vermögensgegenständen (ohne Copyrights)": - "ibd", - }, - }, - "Informations- und Datenverarbeitung, Forschung und Entwicklung": { - Informationsdienstleistungen: { - Hardwareberatung: "jaa", - Softwarehäuser: "jab", - }, - Datenverarbeitung: { - Datenverarbeitungsdienste: "jba", - Datenbanken: "jbb", - "Instandhaltung und Reparatur von Büromaschinen, Datenverarbeitungsgeräten und -einrichtungen": - "jbc", - "Sonstige mit der Datenverarbeitung verbundene Tätigkeiten und Rundfunkveranstalter": - "jbd", - }, - "Forschung und Entwicklung": { - "Forschung und Entwicklung im Bereich Natur-, Ingenieur-, Agrarwissenschaften und Medizin": - "jca", - "Forschung und Entwicklung im Bereich Rechts-, Wirtschafts- und Sozialwissenschaften sowie im Bereich Sprach-, Kultur- und Kunstwissenschaften": - "jcb", - }, - }, - "Erbringung von freiberuflichen, wirtschaftlichen und technischen Dienstleistungen": - { - "Freiberufliche Dienstleistungen": { - "Rechts-, Steuer- und Unternehmensberatung, Wirtschaftsprüfung, Buchführung, Markt- und Meinungsforschung, Managementtätigkeiten von Holdinggesellschaften": - "kaa", - "Architektur- und Ingenieurbüros": "kab", - Werbung: "kac", - "Personal- und Stellenvermittlung, Überlassung von Arbeitskräften": - "kad", - "Wach- und Sicherheitsdienste sowie Detekteien": "kae", - }, - "Technische Dienstleistungen": { - "Technische, physikalische und chemische Untersuchung": "kba", - "Reinigung von Gebäuden, Inventar und Verkehrsmitteln": "kbb", - }, - "Wirtschaftliche Dienstleistungen": { - "Erbringung von sonstigen wirtschaftlichen Dienstleistungen, anderweitig nicht genannt": - "kca", - }, - }, - "Öffentliche Verwaltung, Verteidigung, Sozialversicherung": { - "Verwaltung, Verteidigung, Sozialversicherung": { - "Öffentliche Verwaltung": "laa", - "Auswärtige Angelegenheiten, Verteidigung, Rechtspflege, öffentliche Sicherheit und Ordnung": - "lab", - "Sozialversicherung und Arbeitsförderung": "lac", - }, - Bund: { - "Fonds Deutsche Einheit / Erblastentilgungsfonds": "lba", - "ERP-Sondervermögen": "lbb", - Bundeseisenbahnvermögen: "lbc", - }, - Länder: { - Gemeinden: "lcb", - "Kommunale Zweckverbände": "lcc", - "Sonstige ausländische Gebietskörperschaften": "lcd", - }, - }, - "Gesundheits-, Veterinär- und Sozialwesen, Erziehung und Unterricht": { - "Erziehung und Unterricht": { - "Kindergärten, Vor- und Grundschulen": "maa", - "Weiterführende Schulen": "mab", - "Hochschulen und andere Bildungseinrichtungen des Tertiärsbereichs": - "mac", - "Erwachsenenbildung und sonstiger Unterricht": "mad", - }, - "Gesundheits-, Veterinär- und Sozialwesen": { - Gesundheitswesen: "mba", - Veterinärwesen: "mbb", - Sozialwesen: "mbc", - }, - }, - "Abwasser- und Abfallentsorgung, Private Haushalte": { - Abwasserentsorgung: { - Abwasserbeseitigung: "naa", - }, - Abfallbeseitigung: { - Abfallbeseitigung: "nba", - }, - "Private Haushalte": { - "Private Haushalte mit sonstigem Hauspersonal": "nca", - }, - }, - "Interessenvertretungen sowie kirchliche und sonstige Vereinigungen, Organisationen": - { - Interessenvertretungen: { - "Wirtschafts- und Arbeitgeberverbände": "oaa", - Gewerkschaften: "oab", - Berufsorganisationen: "oac", - }, - "Kirchliche und sonstige Vereinigungen": { - "Kirchliche und sonstige religiöse Vereinigungen": "oba", - "Politische Parteien und Vereinigungen": "obb", - "Interessenvertretungen und Vereinigungen, anderweitig nicht genannt": - "obc", - }, - Organisationen: { - "Organisationen der freien Wohlfahrts-/Jugendpflege": "oca", - "Organisationen der Bildung/Wissenschaft/Forsch./Kultur": "ocb", - "Organisationen des Sports und Gesundheitswesens": "occ", - "Kommunale Spitzen- und Regionalverbände": "ocd", - "Sonstige Organisationen ohne Erwerbszweck": "oce", - }, - }, - "Kunst, Unterhaltung und Erholung, Erbringung von sonstigen Dienstleistungen": - { - "Kunst, Unterhaltung und Erholung": { - "Film- und Videofilmherstellung, -verleih und -vertrieb, Kinos": "paa", - "Rundfunkveranstalter, Herstellung von Hörfunk- und Fernsehprogrammen": - "pab", - "Erbringung von sonstigen kulturellen und unterhaltenden Leistungen": - "pac", - "Korrespondenz- und Nachrichtenbüros, selbstständige Journalistinnen und Journalisten": - "pad", - "Bibliotheken, Archive, Museen, botanische und zoologische Gärten": - "pae", - Sport: "paf", - "Erbringung von sonstigen Dienstleistungen für Unterhaltung, Erholung und Freizeit": - "pag", - }, - "Erbringung von sonstigen Dienstleistungen": { - "Wäscherei und chemische Reinigung": "pba", - "Frisör- und Kosmetiksalons": "pbb", - Bestattungswesen: "pbc", - "Saunas, Solarien, Fitnesszentren u.ä.": "pbd", - "Erbringung von Dienstleistungen, anderweitig nicht genannt": "pbe", - }, - }, -};