diff --git a/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-cemetery/financial-statement-cemetery.service.ts b/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-cemetery/financial-statement-cemetery.service.ts index dbfbf5c9f752..c68c95358b12 100644 --- a/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-cemetery/financial-statement-cemetery.service.ts +++ b/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-cemetery/financial-statement-cemetery.service.ts @@ -7,41 +7,45 @@ import { CemeteryFinancialStatementValues, FinancialStatementsInaoClientService, ClientRoles, - Contact, - ContactType, - DigitalSignee, } from '@island.is/clients/financial-statements-inao' import { ApplicationTypes, ApplicationWithAttachments as Application, - PerformActionResult, } from '@island.is/application/types' import { getValueViaPath } from '@island.is/application/core' import AmazonS3URI from 'amazon-s3-uri' import { TemplateApiModuleActionProps } from '../../../types' import * as kennitala from 'kennitala' -import { - DataResponse, - getCurrentUserType, -} from '../financial-statements-inao/financial-statements-inao.service' -import { - BoardMember, - FSIUSERTYPE, -} from '@island.is/application/templates/financial-statements-inao/types' import { mapValuesToCemeterytype, getNeededCemeteryValues, mapContactsAnswersToContacts, mapDigitalSignee, } from '../financial-statement-cemetery/mappers/mapValuesToUserType' -import { TemplateApiError } from '@island.is/nest/problem' -import { ApplicationApiAction } from '../../template-api.service' export type AttachmentData = { key: string name: string } +export interface DataResponse { + success: boolean + message?: string +} + +export const getCurrentUserType = ( + answers: Application['answers'], + externalData: Application['externalData'], +) => { + const fakeUserType: any = getValueViaPath(answers, 'fakeData.options') + + const currentUserType: any = getValueViaPath( + externalData, + 'getUserType.data.value', + ) + return fakeUserType ?? currentUserType +} + export class FinancialStatementCemeteryTemplateService extends BaseTemplateApiService { s3: S3 constructor( diff --git a/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-cemetery/mappers/mapValuesToUserType.ts b/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-cemetery/mappers/mapValuesToUserType.ts index a5d02e9acadb..a9bdb4dcbc07 100644 --- a/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-cemetery/mappers/mapValuesToUserType.ts +++ b/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-cemetery/mappers/mapValuesToUserType.ts @@ -1,5 +1,4 @@ import { getValueViaPath } from '@island.is/application/core' -import { BoardMember } from '@island.is/application/templates/financial-statements-inao/types' import { FormValue } from '@island.is/application/types' import { Contact, @@ -8,6 +7,12 @@ import { DigitalSignee, } from '@island.is/clients/financial-statements-inao' +type BoardMember = { + nationalId: string + name: string + role: string +} + export const mapValuesToCemeterytype = (answers: FormValue) => { return { careIncome: Number(getValueViaPath(answers, 'cemetryIncome.careIncome')), diff --git a/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-political-party/financial-statement-political-party.modules.ts b/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-political-party/financial-statement-political-party.modules.ts new file mode 100644 index 000000000000..f49a6489afca --- /dev/null +++ b/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-political-party/financial-statement-political-party.modules.ts @@ -0,0 +1,21 @@ +import { Module } from '@nestjs/common' +import { SharedTemplateAPIModule } from '../../shared' +import { ConfigModule } from '@nestjs/config' +import { + FinancialStatementsInaoClientConfig, + FinancialStatementsInaoClientModule, +} from '@island.is/clients/financial-statements-inao' +import { FinancialStatementPoliticalPartyTemplateService } from './financial-statement-political-party.service' + +@Module({ + imports: [ + SharedTemplateAPIModule, + ConfigModule.forRoot({ + load: [FinancialStatementsInaoClientConfig], + }), + FinancialStatementsInaoClientModule, + ], + providers: [FinancialStatementPoliticalPartyTemplateService], + exports: [FinancialStatementPoliticalPartyTemplateService], +}) +export class FinancialStatementPoliticalPartyTemplateModule {} diff --git a/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-political-party/financial-statement-political-party.service.ts b/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-political-party/financial-statement-political-party.service.ts new file mode 100644 index 000000000000..087713a9ed41 --- /dev/null +++ b/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-political-party/financial-statement-political-party.service.ts @@ -0,0 +1,209 @@ +import { Inject, Injectable } from '@nestjs/common' +import { BaseTemplateApiService } from '../../base-template-api.service' +import { S3 } from 'aws-sdk' +import { LOGGER_PROVIDER } from '@island.is/logging' +import type { Logger } from '@island.is/logging' +import { + ApplicationTypes, + ApplicationWithAttachments as Application, +} from '@island.is/application/types' +import { + Contact, + ContactType, + DigitalSignee, + FinancialStatementsInaoClientService, + PoliticalPartyFinancialStatementValues, +} from '@island.is/clients/financial-statements-inao' +import { getValueViaPath } from '@island.is/application/core' +import AmazonS3Uri from 'amazon-s3-uri' +import { TemplateApiModuleActionProps } from '../../../types' +import * as kennitala from 'kennitala' +import { mapValuesToPartyTypes } from './mappers/mapValuesToPartyTypes' + +export interface AttachmentData { + key: string + name: string +} + +export interface DataResponse { + success: boolean + message?: string +} + +export const getCurrentUserType = ( + answers: Application['answers'], + externalData: Application['externalData'], +) => { + const fakeUserType = getValueViaPath(answers, 'fakeData.options') as + | number + | undefined + + const currentUserType = getValueViaPath( + externalData, + 'getUserType.data.value', + ) as number | undefined + + return fakeUserType ?? currentUserType +} + +const PARTY_USER_TYPE = 150000001 + +@Injectable() +export class FinancialStatementPoliticalPartyTemplateService extends BaseTemplateApiService { + s3: S3 + constructor( + @Inject(LOGGER_PROVIDER) private logger: Logger, + private financialStatementClientService: FinancialStatementsInaoClientService, + ) { + super(ApplicationTypes.FINANCIAL_STATEMENT_POLITICAL_PARTY) + this.s3 = new S3() + } + + private async getAttachment(application: Application): Promise { + const attachments = getValueViaPath( + application.answers, + 'attachments.files', + ) as Array + + if (!attachments || attachments.length === 0) { + throw new Error('No attachments found in application') + } + + const attachmentKey = attachments[0].key + + const fileName = ( + application.attachments as { + [key: string]: string + } + )[attachmentKey] + + if (!fileName) { + throw new Error('Attachment file name not found') + } + + const { bucket, key } = AmazonS3Uri(fileName) + + const uploadBucket = bucket + try { + const file = await this.s3 + .getObject({ Bucket: uploadBucket, Key: key }) + .promise() + const fileContent = file.Body as Buffer + return fileContent?.toString('base64') || '' + } catch (error) { + this.logger.error('Error retrieving attachment from S3', error) + throw new Error('Failed to retrieve attachment from S3') + } + } + + async getUserType({ auth }: TemplateApiModuleActionProps) { + const { nationalId } = auth + if (kennitala.isPerson(nationalId)) { + return this.financialStatementClientService.getClientType('Einstaklingur') + } else { + return this.financialStatementClientService.getUserClientType(nationalId) + } + } + + async submitApplication({ application, auth }: TemplateApiModuleActionProps) { + const { nationalId, actor } = auth + + if (!actor) { + throw new Error('Enginn umboðsmaður fannst') + } + + this.validateUserType(application) + + const values = this.prepareValues(application) + const year = this.getOperatingYear(application) + const fileName = await this.getAttachment(application) + const client = { nationalId } + const contacts = this.prepareContacts(application, actor) + const digitalSignee = this.prepareDigitalSignee(application) + + try { + const result = + await this.financialStatementClientService.postFinancialStatementForPoliticalParty( + client, + contacts, + digitalSignee, + year, + '', + values, + fileName, + ) + + if (!result) { + throw new Error('Application submission failed') + } + + return { success: true } + } catch (error) { + this.logger.error('Error submitting application', error) + return { + success: false, + message: error.message, + } + // throw new Error('Application submission failed') + } + } + + private prepareValues( + application: Application, + ): PoliticalPartyFinancialStatementValues { + return mapValuesToPartyTypes(application.answers) + } + + private getOperatingYear(application: Application) { + const year = getValueViaPath( + application.answers, + 'conditionalAbout.operatingYear', + ) + if (typeof year !== 'string') { + throw new Error('Operating year not found or invalid') + } + return year + } + + private validateUserType(application: Application) { + const currentUserType = getCurrentUserType( + application.answers, + application.externalData, + ) + if (currentUserType !== PARTY_USER_TYPE) { + throw new Error('Invalid user type for application submission') + } + } + + private prepareContacts( + application: Application, + actor: { nationalId: string }, + ): Array { + const actorsName = getValueViaPath( + application.answers, + 'about.powerOfAttorneyName', + ) as string + return [ + { + nationalId: actor.nationalId, + name: actorsName, + contactType: ContactType.Actor, + }, + ] + } + + private prepareDigitalSignee(application: Application): DigitalSignee { + const clientPhone = getValueViaPath( + application.answers, + 'about.phoneNumber', + ) as string + const clientEmail = getValueViaPath( + application.answers, + 'about.email', + ) as string + return { + email: clientEmail, + phone: clientPhone, + } + } +} diff --git a/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-political-party/mappers/mapValuesToPartyTypes.ts b/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-political-party/mappers/mapValuesToPartyTypes.ts new file mode 100644 index 000000000000..bcd5b4a2a2b4 --- /dev/null +++ b/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-political-party/mappers/mapValuesToPartyTypes.ts @@ -0,0 +1,49 @@ +import { getValueViaPath } from '@island.is/application/core' +import { FormValue } from '@island.is/application/types' + +export const mapValuesToPartyTypes = (answers: FormValue) => { + return { + contributionsFromTheTreasury: Number( + getValueViaPath(answers, 'partyIncome.contributionsFromTheTreasury'), + ), + parliamentaryPartySupport: Number( + getValueViaPath(answers, 'partyIncome.parliamentaryPartySupport'), + ), + municipalContributions: Number( + getValueViaPath(answers, 'partyIncome.municipalContributions'), + ), + contributionsFromLegalEntities: Number( + getValueViaPath(answers, 'partyIncome.contributionsFromLegalEntities'), + ), + contributionsFromIndividuals: Number( + getValueViaPath(answers, 'partyIncome.contributionsFromIndividuals'), + ), + generalMembershipFees: Number( + getValueViaPath(answers, 'partyIncome.generalMembershipFees'), + ), + otherIncome: Number(getValueViaPath(answers, 'partyIncome.otherIncome')), + capitalIncome: Number( + getValueViaPath(answers, 'capitalNumbers.capitalIncome'), + ), + officeOperations: Number( + getValueViaPath(answers, 'partyExpense.electionOffice'), + ), + otherOperatingExpenses: Number( + getValueViaPath(answers, 'partyExpense.otherCost'), + ), + financialExpenses: Number( + getValueViaPath(answers, 'capitalNumbers.capitalCost'), + ), + fixedAssetsTotal: Number( + getValueViaPath(answers, 'asset.fixedAssetsTotal'), + ), + currentAssets: Number(getValueViaPath(answers, 'asset.currentAssets')), + longTermLiabilitiesTotal: Number( + getValueViaPath(answers, 'liability.longTerm'), + ), + shortTermLiabilitiesTotal: Number( + getValueViaPath(answers, 'liability.shortTerm'), + ), + equityTotal: Number(getValueViaPath(answers, 'equity.totalEquity')), + } +} diff --git a/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-political-party/types/index.ts b/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-political-party/types/index.ts new file mode 100644 index 000000000000..eff3baa03dc9 --- /dev/null +++ b/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-political-party/types/index.ts @@ -0,0 +1,4 @@ +export type KeyValue = { + key: number + value: number +} diff --git a/libs/application/template-api-modules/src/lib/modules/templates/index.ts b/libs/application/template-api-modules/src/lib/modules/templates/index.ts index fcc5c66b42d8..b407059faf1f 100644 --- a/libs/application/template-api-modules/src/lib/modules/templates/index.ts +++ b/libs/application/template-api-modules/src/lib/modules/templates/index.ts @@ -30,6 +30,8 @@ import { FinancialStatementsInaoTemplateModule } from './financial-statements-in import { FinancialStatementsInaoTemplateService } from './financial-statements-inao/financial-statements-inao.service' import { FinancialStatementIndividualElectionModule } from './financial-statement-individual-election/financial-statement-individual-election.module' import { FinancialStatementIndividualElectionService } from './financial-statement-individual-election/financial-statement-individual-election.service' +import { FinancialStatementPoliticalPartyTemplateModule } from './financial-statement-political-party/financial-statement-political-party.modules' +import { FinancialStatementPoliticalPartyTemplateService } from './financial-statement-political-party/financial-statement-political-party.service' import { FundingGovernmentProjectsModule } from './funding-government-projects/funding-government-projects.module' import { FundingGovernmentProjectsService } from './funding-government-projects/funding-government-projects.service' import { GeneralFishingLicenseModule } from './general-fishing-license/general-fishing-license.module' @@ -64,7 +66,6 @@ import { PublicDebtPaymentPlanTemplateModule } from './public-debt-payment-plan/ import { PublicDebtPaymentPlanTemplateService } from './public-debt-payment-plan/public-debt-payment-plan.service' import { ReferenceTemplateModule } from './reference-template/reference-template.module' import { ReferenceTemplateService } from './reference-template/reference-template.service' - import { CitizenshipModule } from './directorate-of-immigration/citizenship/citizenship.module' import { CitizenshipService } from './directorate-of-immigration/citizenship/citizenship.service' import { DrivingLearnersPermitModule } from './driving-learners-permit/driving-learners-permit.module' @@ -99,12 +100,10 @@ import { OrderVehicleRegistrationCertificateModule } from './transport-authority import { OrderVehicleRegistrationCertificateService } from './transport-authority/order-vehicle-registration-certificate/order-vehicle-registration-certificate.service' import { TransferOfVehicleOwnershipModule } from './transport-authority/transfer-of-vehicle-ownership/transfer-of-vehicle-ownership.module' import { TransferOfVehicleOwnershipService } from './transport-authority/transfer-of-vehicle-ownership/transfer-of-vehicle-ownership.service' - import { EnergyFundsModule } from './energy-funds/energy-funds.module' import { EnergyFundsService } from './energy-funds/energy-funds.service' import { UniversityModule } from './university/university.module' import { UniversityService } from './university/university.service' - import { TransferOfMachineOwnershipTemplateModule } from './aosh/transfer-of-machine-ownership/transfer-of-machine-ownership.module' import { TransferOfMachineOwnershipTemplateService } from './aosh/transfer-of-machine-ownership/transfer-of-machine-ownership.service' import { CarRecyclingModule } from './car-recycling/car-recycling.module' @@ -137,7 +136,6 @@ import { HealthInsuranceDeclarationModule } from './health-insurance-declaration import { HealthInsuranceDeclarationService } from './health-insurance-declaration/health-insurance-declaration.service' import { NewPrimarySchoolModule } from './new-primary-school/new-primary-school.module' import { NewPrimarySchoolService } from './new-primary-school/new-primary-school.service' - import { IdCardModule } from './id-card/id-card.module' import { IdCardService } from './id-card/id-card.service' import { ParliamentaryListCreationModule } from './signature-collection/parliamentary-list-creation/parliamentary-list-creation.module' @@ -174,6 +172,7 @@ export const modules = [ FinancialStatementCemeteryTemplateModule, FinancialStatementsInaoTemplateModule, FinancialStatementIndividualElectionModule, + FinancialStatementPoliticalPartyTemplateModule, NoDebtCertificateModule, InheritanceReportModule, EstateTemplateModule, @@ -248,6 +247,7 @@ export const services = [ FinancialStatementCemeteryTemplateService, FinancialStatementsInaoTemplateService, FinancialStatementIndividualElectionService, + FinancialStatementPoliticalPartyTemplateService, MarriageConditionsSubmissionService, NoDebtCertificateService, InheritanceReportService, diff --git a/libs/application/template-loader/src/lib/templateLoaders.ts b/libs/application/template-loader/src/lib/templateLoaders.ts index d1ea92123509..5bf5164f814c 100644 --- a/libs/application/template-loader/src/lib/templateLoaders.ts +++ b/libs/application/template-loader/src/lib/templateLoaders.ts @@ -71,6 +71,10 @@ const templates: Record Promise> = { import( '@island.is/application/templates/financial-statement-individual-election' ), + [ApplicationTypes.FINANCIAL_STATEMENT_POLITICAL_PARTY]: () => + import( + '@island.is/application/templates/financial-statement-political-party' + ), [ApplicationTypes.OPERATING_LICENSE]: () => import('@island.is/application/templates/operating-license'), [ApplicationTypes.MARRIAGE_CONDITIONS]: () => diff --git a/libs/application/templates/inao/README.md b/libs/application/templates/inao/README.md index 1305db159fef..f4452034b030 100644 --- a/libs/application/templates/inao/README.md +++ b/libs/application/templates/inao/README.md @@ -1 +1,14 @@ # Applications for the Icelandic National Audit Office, Ríkisendurskoðun + +## Financial-statement-cemetery + +Annual financial statement for cemeteries, should be handed in before the 1. of June each year. + +## Financial-statement-individual-election + +Financial statements that should he handed in with in three months of an election that individuals take part in. +This is for example elections for president, parlament, local goverments or primaries for political parties. + +## Financial-statements-political-party + +Annual financial statements for political parties, should be handed in before 31. of October each year. diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/clientInfoSection/index.ts b/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/clientInfoSection/index.ts index 9846bfef640e..f763eeb88a19 100644 --- a/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/clientInfoSection/index.ts +++ b/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/clientInfoSection/index.ts @@ -5,12 +5,10 @@ import { buildSection, buildTextField, } from '@island.is/application/core' -import { getCurrentUserType } from '../../../utils/helpers' import { Application, UserProfile } from '@island.is/application/types' import { m } from '../../../lib/messages' import { ABOUTIDS } from '../../../utils/constants' import { Identity } from '@island.is/api/schema' -import { FSIUSERTYPE } from '../../../types/types' export const clientInfoSection = buildSection({ id: 'info', @@ -19,14 +17,7 @@ export const clientInfoSection = buildSection({ buildMultiField({ id: 'about', title: m.info, - description: (application: Application) => { - const answers = application.answers - const externalData = application.externalData - const userType = getCurrentUserType(answers, externalData) - return userType === FSIUSERTYPE.INDIVIDUAL - ? m.reviewInfo - : m.reviewContact - }, + description: m.reviewContact, children: [ buildDescriptionField({ id: ABOUTIDS.operatingYear, diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/lib/financialStatementCemeteryTemplate.ts b/libs/application/templates/inao/financial-statement-cemetery/src/lib/financialStatementCemeteryTemplate.ts index ebd0fc224d5f..127341d014f5 100644 --- a/libs/application/templates/inao/financial-statement-cemetery/src/lib/financialStatementCemeteryTemplate.ts +++ b/libs/application/templates/inao/financial-statement-cemetery/src/lib/financialStatementCemeteryTemplate.ts @@ -28,7 +28,7 @@ import { ApiActions, Events, Roles, States } from '../types/types' import { Features } from '@island.is/feature-flags' const configuration = - ApplicationConfigurations[ApplicationTypes.FINANCIAL_STATEMENTS_INAO] + ApplicationConfigurations[ApplicationTypes.FINANCIAL_STATEMENT_CEMETERY] const FinancialStatementCemeteryTemplate: ApplicationTemplate< ApplicationContext, diff --git a/libs/application/templates/inao/financial-statement-political-party/.babelrc b/libs/application/templates/inao/financial-statement-political-party/.babelrc new file mode 100644 index 000000000000..1ea870ead410 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + [ + "@nx/react/babel", + { + "runtime": "automatic", + "useBuiltIns": "usage" + } + ] + ], + "plugins": [] +} diff --git a/libs/application/templates/inao/financial-statement-political-party/.eslintrc.json b/libs/application/templates/inao/financial-statement-political-party/.eslintrc.json new file mode 100644 index 000000000000..1ac7686355e0 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["plugin:@nx/react", "../../../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/libs/application/templates/inao/financial-statement-political-party/README.md b/libs/application/templates/inao/financial-statement-political-party/README.md new file mode 100644 index 000000000000..3961bb865298 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/README.md @@ -0,0 +1,7 @@ +# application-templates-inao-financial-statement-political-party + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test application-templates-inao-financial-statement-political-party` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/application/templates/inao/financial-statement-political-party/jest.config.ts b/libs/application/templates/inao/financial-statement-political-party/jest.config.ts new file mode 100644 index 000000000000..e661205e0d0d --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/jest.config.ts @@ -0,0 +1,12 @@ +/* eslint-disable */ +export default { + displayName: 'application-templates-inao-financial-statement-political-party', + preset: '../../../../../jest.preset.js', + transform: { + '^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nx/react/plugins/jest', + '^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nx/react/babel'] }], + }, + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], + coverageDirectory: + '../../../../../coverage/libs/application/templates/inao/financial-statement-political-party', +} diff --git a/libs/application/templates/inao/financial-statement-political-party/project.json b/libs/application/templates/inao/financial-statement-political-party/project.json new file mode 100644 index 000000000000..842ea13d45aa --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/project.json @@ -0,0 +1,25 @@ +{ + "name": "application-templates-inao-financial-statement-political-party", + "$schema": "../../../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/application/templates/inao/financial-statement-political-party/src", + "projectType": "library", + "tags": ["scope:application-system", "lib:application-system"], + "targets": { + "lint": { + "executor": "@nx/eslint:lint" + }, + "extract-strings": { + "executor": "nx:run-commands", + "options": { + "command": "yarn ts-node -P libs/localization/tsconfig.lib.json libs/localization/scripts/extract libs/application/templates/inao/financial-statement-political-party/src/lib/messages.ts" + } + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "libs/application/templates/inao/financial-statement-political-party/jest.config.ts" + } + } + } +} diff --git a/libs/application/templates/inao/financial-statement-political-party/src/components/AboutOverview.tsx b/libs/application/templates/inao/financial-statement-political-party/src/components/AboutOverview.tsx new file mode 100644 index 000000000000..095657490203 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/components/AboutOverview.tsx @@ -0,0 +1,62 @@ +import { GridColumn, GridRow } from '@island.is/island-ui/core' +import { formatPhoneNumber } from '@island.is/application/ui-components' +import { format as formatNationalId } from 'kennitala' +import { ValueLine } from './ValueLine' +import { m } from '../lib/messages' +import { FinancialStatementPoliticalParty } from '../lib/dataSchema' +import { sectionColumn } from './css/overviewStyles.css' + +type Props = { + answers: FinancialStatementPoliticalParty +} + +export const AboutOverview = ({ answers }: Props) => { + return ( + <> + + + + + + + + + + {answers.about.powerOfAttorneyName ? ( + + + + ) : null} + {answers.about.powerOfAttorneyNationalId ? ( + + + + ) : null} + + + + + + + + + + + ) +} diff --git a/libs/application/templates/inao/financial-statement-political-party/src/components/AssetDebtEquityOverview.tsx b/libs/application/templates/inao/financial-statement-political-party/src/components/AssetDebtEquityOverview.tsx new file mode 100644 index 000000000000..2f4c1335863a --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/components/AssetDebtEquityOverview.tsx @@ -0,0 +1,72 @@ +import { Box, GridColumn, GridRow, Text } from '@island.is/island-ui/core' +import { ValueLine } from './ValueLine' +import { useLocale } from '@island.is/localization' +import { formatCurrency } from '../utils/helpers' +import { m } from '../lib/messages' +import { FinancialStatementPoliticalParty } from '../lib/dataSchema' +import { sectionColumn } from './css/overviewStyles.css' + +type Props = { + answers: FinancialStatementPoliticalParty +} + +export const AssetDebtEquityOverview = ({ answers }: Props) => { + const { formatMessage } = useLocale() + + return ( + + + + + {formatMessage(m.properties)} + + + + + + + + + + + {formatMessage(m.debtsAndEquity)} + + + + + + + + + + + + ) +} diff --git a/libs/application/templates/inao/financial-statement-political-party/src/components/BottomBar.tsx b/libs/application/templates/inao/financial-statement-political-party/src/components/BottomBar.tsx new file mode 100644 index 000000000000..d9a2d938168f --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/components/BottomBar.tsx @@ -0,0 +1,37 @@ +import { Box, Button, Divider } from '@island.is/island-ui/core' +import { useLocale } from '@island.is/localization' +import { m } from '../lib/messages' + +type Props = { + onBackButtonClick: () => void + onSendButtonClick: () => void + loading?: boolean + sendText?: string +} + +const BottomBar = ({ + onBackButtonClick, + onSendButtonClick, + loading = false, + sendText, +}: Props) => { + const { formatMessage } = useLocale() + + return ( + <> + + + + + + + + + ) +} + +export default BottomBar diff --git a/libs/application/templates/inao/financial-statement-political-party/src/components/CapitalNumberOverview.tsx b/libs/application/templates/inao/financial-statement-political-party/src/components/CapitalNumberOverview.tsx new file mode 100644 index 000000000000..aa74007ef7e4 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/components/CapitalNumberOverview.tsx @@ -0,0 +1,49 @@ +import { Box, GridColumn, GridRow, Text } from '@island.is/island-ui/core' +import { ValueLine } from './ValueLine' +import { useLocale } from '@island.is/localization' +import { FinancialStatementPoliticalParty } from '../lib/dataSchema' +import { formatCurrency } from '../utils/helpers' +import { m } from '../lib/messages' +import { sectionColumn, starterColumnStyle } from './css/overviewStyles.css' + +type Props = { + answers: FinancialStatementPoliticalParty +} + +export const CapitalNumberOverview = ({ answers }: Props) => { + const { formatMessage } = useLocale() + return ( + <> + + + {formatMessage(m.capitalNumbers)} + + + + + + + {answers.capitalNumbers?.capitalCost ? ( + + + + ) : null} + + + + + + + + ) +} diff --git a/libs/application/templates/inao/financial-statement-political-party/src/components/FileValueLine.tsx b/libs/application/templates/inao/financial-statement-political-party/src/components/FileValueLine.tsx new file mode 100644 index 000000000000..3a7dcea5bacf --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/components/FileValueLine.tsx @@ -0,0 +1,30 @@ +import { ActionCard, Box, Text } from '@island.is/island-ui/core' +import { useLocale } from '@island.is/localization' +import { m } from '../lib/messages' + +type Props = { + label?: string +} + +export const FileValueLine = ({ label = '' }: Props) => { + const { formatMessage } = useLocale() + + return ( + + {formatMessage(m.files)} + + + + + ) +} diff --git a/libs/application/templates/inao/financial-statement-political-party/src/components/Logo.tsx b/libs/application/templates/inao/financial-statement-political-party/src/components/Logo.tsx new file mode 100644 index 000000000000..a3fc5fc686a4 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/components/Logo.tsx @@ -0,0 +1,20 @@ +import { useLocale } from '@island.is/localization' +import { Box, Text } from '@island.is/island-ui/core' +import { m } from '../lib/messages' + +const Logo = () => { + const { formatMessage } = useLocale() + + return ( + + + {formatMessage(m.serviceProvider)} + + + {formatMessage(m.inao).toUpperCase()} + + + ) +} + +export default Logo diff --git a/libs/application/templates/inao/financial-statement-political-party/src/components/Total.tsx b/libs/application/templates/inao/financial-statement-political-party/src/components/Total.tsx new file mode 100644 index 000000000000..f0cd9b51798f --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/components/Total.tsx @@ -0,0 +1,39 @@ +import { useEffect } from 'react' +import { Box, Text } from '@island.is/island-ui/core' +import { InputController } from '@island.is/shared/form-fields' +import { useFormContext } from 'react-hook-form' + +type Props = { + name: string + total: number + label: string + title?: string +} + +export const Total = ({ name, total, label, title }: Props) => { + const { setValue } = useFormContext() + + useEffect(() => { + setValue(name, total.toString()) + }, [total]) + + return ( + + {title ? ( + + {title} + + ) : null} + + + + ) +} diff --git a/libs/application/templates/inao/financial-statement-political-party/src/components/ValueLine.tsx b/libs/application/templates/inao/financial-statement-political-party/src/components/ValueLine.tsx new file mode 100644 index 000000000000..e52d48763b63 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/components/ValueLine.tsx @@ -0,0 +1,29 @@ +import { Box, Text } from '@island.is/island-ui/core' +import { useLocale } from '@island.is/localization' +import { MessageDescriptor } from 'react-intl' + +type Props = { + label: string | MessageDescriptor + value?: string | MessageDescriptor + isTotal?: boolean +} + +export const ValueLine = ({ label, value = '-', isTotal = false }: Props) => { + const { formatMessage } = useLocale() + + return ( + + + {formatMessage(label)} + + + + {formatMessage(value)} + + + ) +} diff --git a/libs/application/templates/inao/financial-statement-political-party/src/components/css/overviewStyles.css.ts b/libs/application/templates/inao/financial-statement-political-party/src/components/css/overviewStyles.css.ts new file mode 100644 index 000000000000..02636c43d839 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/components/css/overviewStyles.css.ts @@ -0,0 +1,26 @@ +import { style } from '@vanilla-extract/css' + +export const columnStyle = style({ + paddingTop: '0px', + paddingBottom: '0px', + '@media': { + 'screen and (min-width: 576px)': { + paddingTop: '0.5rem', + paddingBottom: '0.5rem', + }, + }, +}) + +export const starterColumnStyle = style({ + paddingTop: '1.5rem', + paddingBottom: '1rem', +}) + +export const sectionColumn = style({ + '@media': { + print: { + flexBasis: '50%', + maxWidth: '50%', + }, + }, +}) diff --git a/libs/application/templates/inao/financial-statement-political-party/src/dataProviders/index.ts b/libs/application/templates/inao/financial-statement-political-party/src/dataProviders/index.ts new file mode 100644 index 000000000000..36303255e230 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/dataProviders/index.ts @@ -0,0 +1,16 @@ +import { defineTemplateApi } from '@island.is/application/types' +import { UserProfileApi } from '@island.is/application/types' + +export { + NationalRegistryUserApi, + IdentityApi as IndentityApiProvider, +} from '@island.is/application/types' +export const CurrentUserTypeProvider = defineTemplateApi({ + action: 'getUserType', + externalDataId: 'currentUserType', +}) +export const UserInfoApi = UserProfileApi.configure({ + params: { + catchMock: true, + }, +}) diff --git a/libs/application/templates/inao/financial-statement-political-party/src/fields/DelegationCheck/DelegationCheck.tsx b/libs/application/templates/inao/financial-statement-political-party/src/fields/DelegationCheck/DelegationCheck.tsx new file mode 100644 index 000000000000..79510986f3c2 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/fields/DelegationCheck/DelegationCheck.tsx @@ -0,0 +1,43 @@ +import { FieldBaseProps } from '@island.is/application/types' +import { AlertBanner, Box } from '@island.is/island-ui/core' +import { useLocale } from '@island.is/localization' +import { useFormContext } from 'react-hook-form' +import { VALIDATOR } from '../../utils/constants' +import { m } from '../../lib/messages' +import { FinancialStatementPoliticalParty } from '../../lib/dataSchema' + +export const DelegationCheck = ({ + application, + setBeforeSubmitCallback, +}: FieldBaseProps) => { + const { formatMessage } = useLocale() + const { + formState: { errors }, + setError, + } = useFormContext() + setBeforeSubmitCallback && + setBeforeSubmitCallback(async () => { + const userType = application.externalData.getUserType?.data + const hasUserType = !!userType + + if (hasUserType) { + setError(VALIDATOR, { + type: 'custom', + message: formatMessage(m.wrongDelegation), + }) + return [false, formatMessage(m.wrongDelegation)] + } else { + return [true, null] + } + }) + + return errors && errors.validator ? ( + + + + ) : null +} diff --git a/libs/application/templates/inao/financial-statement-political-party/src/fields/ElectionEquities/ElectionEquities.tsx b/libs/application/templates/inao/financial-statement-political-party/src/fields/ElectionEquities/ElectionEquities.tsx new file mode 100644 index 000000000000..cedb1027a555 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/fields/ElectionEquities/ElectionEquities.tsx @@ -0,0 +1,213 @@ +import { useState, useEffect } from 'react' +import debounce from 'lodash/debounce' +import { useFormContext } from 'react-hook-form' +import { FieldBaseProps } from '@island.is/application/types' +import { + AlertBanner, + Box, + GridColumn, + GridContainer, + GridRow, + Text, +} from '@island.is/island-ui/core' +import { useLocale } from '@island.is/localization' +import { InputController } from '@island.is/shared/form-fields' +import { getErrorViaPath } from '@island.is/application/core' +import { m } from '../../lib/messages' +import { useTotals } from '../../hooks/useTotals' +import { + EQUITIESANDLIABILITIESIDS, + INPUTCHANGEINTERVAL, + VALIDATOR, +} from '../../utils/constants' +import { getTotal } from '../../utils/helpers' +import { Total } from '../../components/Total' + +export const ElectionEquities = ({ + setBeforeSubmitCallback, +}: FieldBaseProps) => { + const { formatMessage } = useLocale() + + const { + formState: { errors }, + clearErrors, + getValues, + setError, + } = useFormContext() + + const [getTotalEquity, totalEquity] = useTotals( + EQUITIESANDLIABILITIESIDS.equityPrefix, + ) + const [getTotalAssets, totalAssets] = useTotals( + EQUITIESANDLIABILITIESIDS.assetPrefix, + ) + const [getTotalLiabilities, totalLiabilities] = useTotals( + EQUITIESANDLIABILITIESIDS.liabilityPrefix, + ) + + const [equityAndDebts, setEquityAndDebts] = useState(0) + + useEffect(() => { + const total = totalEquity + totalLiabilities + setEquityAndDebts(total) + }, [totalEquity, totalLiabilities]) + + useEffect(() => { + clearErrors(VALIDATOR) + }, [totalEquity, totalLiabilities, totalAssets, clearErrors]) + + setBeforeSubmitCallback && + setBeforeSubmitCallback(async () => { + const values = getValues() + const assets = getTotal(values, 'asset') + const liabilties = getTotal(values, 'liability') + const equities = getTotal(values, 'equity') + + // assets should equal liabilties + equities + const isValid = liabilties + equities === assets + if (!isValid) { + setError(VALIDATOR, { + type: 'custom', + message: formatMessage(m.equityDebtsAssetsValidatorError), + }) + return [false, formatMessage(m.equityDebtsAssetsValidatorError)] + } + return [true, null] + }) + + return ( + + + + + {formatMessage(m.properties)} + + + { + getTotalAssets() + clearErrors(EQUITIESANDLIABILITIESIDS.fixedAssetsTotal) + }, INPUTCHANGEINTERVAL)} + backgroundColor="blue" + currency + /> + + + { + getTotalAssets() + clearErrors(EQUITIESANDLIABILITIESIDS.currentAssets) + }, INPUTCHANGEINTERVAL)} + label={formatMessage(m.currentAssets)} + backgroundColor="blue" + currency + /> + + + + + + {formatMessage(m.debtsAndEquity)} + + + { + getTotalLiabilities() + clearErrors(EQUITIESANDLIABILITIESIDS.longTerm) + }, INPUTCHANGEINTERVAL)} + error={ + errors && + getErrorViaPath(errors, EQUITIESANDLIABILITIESIDS.longTerm) + } + label={formatMessage(m.longTerm)} + backgroundColor="blue" + currency + /> + + + { + getTotalLiabilities() + clearErrors(EQUITIESANDLIABILITIESIDS.shortTerm) + }, INPUTCHANGEINTERVAL)} + error={ + errors && + getErrorViaPath(errors, EQUITIESANDLIABILITIESIDS.shortTerm) + } + label={formatMessage(m.shortTerm)} + backgroundColor="blue" + currency + /> + + + + { + getTotalEquity() + clearErrors(EQUITIESANDLIABILITIESIDS.totalEquity) + }, INPUTCHANGEINTERVAL)} + error={ + errors && + getErrorViaPath(errors, EQUITIESANDLIABILITIESIDS.totalEquity) + } + label={formatMessage(m.equity)} + backgroundColor="blue" + currency + /> + + + + + + + {errors && errors.validator ? ( + + + + ) : null} + + ) +} diff --git a/libs/application/templates/inao/financial-statement-political-party/src/fields/ElectionStatement/ElectionStatement.tsx b/libs/application/templates/inao/financial-statement-political-party/src/fields/ElectionStatement/ElectionStatement.tsx new file mode 100644 index 000000000000..89b4df521eaa --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/fields/ElectionStatement/ElectionStatement.tsx @@ -0,0 +1,84 @@ +import { getErrorViaPath, getValueViaPath } from '@island.is/application/core' +import { AlertBanner, Box, InputError, Text } from '@island.is/island-ui/core' +import { m } from '../../lib/messages' +import { useLocale } from '@island.is/localization' +import { DefaultEvents, FieldBaseProps } from '@island.is/application/types' +import { format as formatNationalId } from 'kennitala' +import { useSubmitApplication } from '../../hooks/useSubmitApplication' +import BottomBar from '../../components/BottomBar' +import { useFormContext } from 'react-hook-form' +import { FinancialStatementPoliticalParty } from '../../lib/dataSchema' +import { ELECTIONLIMIT, GREATER } from '../../utils/constants' +import { formatNumber } from '../../utils/helpers' + +export const ElectionStatement = ({ + application, + goToScreen, + refetch, +}: FieldBaseProps) => { + const { formatMessage } = useLocale() + const { + formState: { errors }, + } = useFormContext() + const answers = application.answers as FinancialStatementPoliticalParty + const email = getValueViaPath(answers, 'about.email') + const [submitApplication, { loading }] = useSubmitApplication({ + application, + refetch, + event: DefaultEvents.SUBMIT, + }) + + const onBackButtonClick = () => { + const incomeLimit = getValueViaPath(answers, 'election.incomeLimit') + + if (incomeLimit === GREATER) { + goToScreen?.('attachments.file') + } else { + goToScreen?.('election') + } + } + + const onSendButtonClick = () => { + submitApplication() + } + + return ( + + + + {`${answers.about.fullName}, + ${formatMessage(m.nationalId)}: ${formatNationalId( + answers.about.nationalId, + )}, ${formatMessage(m.participated)} + ${answers.election.genitiveName}`} + + + + {`${formatMessage(m.electionDeclare)} ${formatNumber( + ELECTIONLIMIT, + )}`} + + + {formatMessage(m.electionStatementLaw)} + + + + + {errors && getErrorViaPath(errors, 'applicationApprove') ? ( + + ) : null} + + + ) +} diff --git a/libs/application/templates/inao/financial-statement-political-party/src/fields/KeyNumbersCapital/KeyNumbersCapital.tsx b/libs/application/templates/inao/financial-statement-political-party/src/fields/KeyNumbersCapital/KeyNumbersCapital.tsx new file mode 100644 index 000000000000..17329d216f88 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/fields/KeyNumbersCapital/KeyNumbersCapital.tsx @@ -0,0 +1,93 @@ +import { useState, useEffect } from 'react' +import { + Box, + GridColumn, + GridContainer, + GridRow, +} from '@island.is/island-ui/core' +import { getValueViaPath } from '@island.is/application/core' +import debounce from 'lodash/debounce' +import { useFormContext } from 'react-hook-form' +import { useLocale } from '@island.is/localization' +import { InputController } from '@island.is/shared/form-fields' +import { m } from '../../lib/messages' +import { getErrorViaPath } from '@island.is/application/core' +import { CAPITALNUMBERS, INPUTCHANGEINTERVAL } from '../../utils/constants' +import { Total } from '../../components/Total' + +export const KeyNumbersCapital = () => { + const { formatMessage } = useLocale() + const [totalCapital, setTotalCapital] = useState(0) + const { + clearErrors, + formState: { errors }, + getValues, + } = useFormContext() + + const getTotalCapital = () => { + const values = getValues() + + const income = getValueViaPath(values, CAPITALNUMBERS.capitalIncome) || '0' + const expense = getValueViaPath(values, CAPITALNUMBERS.capitalCost) || '0' + const total = Number(income) - Number(expense) + setTotalCapital(total) + } + + useEffect(() => { + getTotalCapital() + }, [getTotalCapital]) + + return ( + + + + + { + getTotalCapital() + clearErrors(CAPITALNUMBERS.capitalIncome) + }, INPUTCHANGEINTERVAL)} + label={formatMessage(m.capitalIncome)} + backgroundColor="blue" + rightAlign + currency + /> + + + + + { + getTotalCapital() + clearErrors(CAPITALNUMBERS.capitalCost) + }, INPUTCHANGEINTERVAL)} + label={formatMessage(m.capitalCost)} + error={ + errors && getErrorViaPath(errors, CAPITALNUMBERS.capitalCost) + } + backgroundColor="blue" + rightAlign + currency + /> + + + + + + + + + + ) +} diff --git a/libs/application/templates/inao/financial-statement-political-party/src/fields/OperatingYear/OperatingYear.tsx b/libs/application/templates/inao/financial-statement-political-party/src/fields/OperatingYear/OperatingYear.tsx new file mode 100644 index 000000000000..9824ba8b7492 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/fields/OperatingYear/OperatingYear.tsx @@ -0,0 +1,82 @@ +import { + AlertMessage, + Box, + ContentBlock, + SkeletonLoader, +} from '@island.is/island-ui/core' +import { useLocale } from '@island.is/localization' +import { + ABOUTIDS, + PartiesBackwardLimit, + PartiesYearAllowed, +} from '../../utils/constants' +import * as styles from './styles.css' +import { useFormContext } from 'react-hook-form' +import { getErrorViaPath } from '@island.is/application/core' +import { SelectController } from '@island.is/shared/form-fields' +import { useQuery } from '@apollo/client' +import { + getConfigInfoForKey, + possibleOperatingYears, +} from '../../utils/helpers' +import { auditConfigQuery } from '../../graphql' +import { m } from '../../lib/messages' + +export const OperatingYear = () => { + const { data, loading, error } = useQuery(auditConfigQuery) + const { formatMessage } = useLocale() + const { + formState: { errors }, + } = useFormContext() + + if (loading) { + return ( + + + + ) + } + + if (error || data?.financialStatementsInaoConfig?.length <= 0) { + return ( + + + + ) + } + + const { financialStatementsInaoConfig } = data + + const backwardsYearLimit = getConfigInfoForKey( + financialStatementsInaoConfig, + PartiesBackwardLimit, + ) + + const countYearBackwardsFrom = getConfigInfoForKey( + financialStatementsInaoConfig, + PartiesYearAllowed, + ) + + const operatingYear = possibleOperatingYears( + backwardsYearLimit, + countYearBackwardsFrom, + ) + + return ( + + + + ) +} diff --git a/libs/application/templates/inao/financial-statement-political-party/src/fields/OperatingYear/styles.css.ts b/libs/application/templates/inao/financial-statement-political-party/src/fields/OperatingYear/styles.css.ts new file mode 100644 index 000000000000..c5dd8724f088 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/fields/OperatingYear/styles.css.ts @@ -0,0 +1,5 @@ +import { style } from '@vanilla-extract/css' + +export const selectSpace = style({ + paddingRight: '10px', +}) diff --git a/libs/application/templates/inao/financial-statement-political-party/src/fields/Overview/Overview.tsx b/libs/application/templates/inao/financial-statement-political-party/src/fields/Overview/Overview.tsx new file mode 100644 index 000000000000..fef843b8e6da --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/fields/Overview/Overview.tsx @@ -0,0 +1,170 @@ +import { useState } from 'react' +import { DefaultEvents, FieldBaseProps } from '@island.is/application/types' + +import { + AlertBanner, + Box, + Checkbox, + Divider, + GridColumn, + GridRow, + InputError, + Text, +} from '@island.is/island-ui/core' +import { Controller, useFormContext } from 'react-hook-form' +import { getErrorViaPath, getValueViaPath } from '@island.is/application/core' +import { useLocale } from '@island.is/localization' +import { m } from '../../lib/messages' +import { useSubmitApplication } from '../../hooks/useSubmitApplication' +import BottomBar from '../../components/BottomBar' +import { FinancialStatementPoliticalParty } from '../../lib/dataSchema' +import { AboutOverview } from '../../components/AboutOverview' +import { GREATER } from '../../utils/constants' +import { + sectionColumn, + starterColumnStyle, +} from '../../components/css/overviewStyles.css' +import { CapitalNumberOverview } from '../../components/CapitalNumberOverview' +import { AssetDebtEquityOverview } from '../../components/AssetDebtEquityOverview' +import { FileValueLine } from '../../components/FileValueLine' + +export const Overview = ({ + application, + goToScreen, + refetch, +}: FieldBaseProps) => { + const { formatMessage } = useLocale() + const { + formState: { errors }, + setError, + setValue, + } = useFormContext() + + const [approveOverview, setApproveOverview] = useState(false) + + const answers = application.answers as FinancialStatementPoliticalParty + const fileName = answers.attachments?.file?.[0]?.name + + const [submitApplication, { error: submitError, loading }] = + useSubmitApplication({ + application, + refetch, + event: DefaultEvents.SUBMIT, + }) + + const onBackButtonClick = () => { + const incomeLimit = getValueViaPath(answers, 'election.incomeLimit') + + if (incomeLimit === GREATER) { + goToScreen?.('attachments.file') + } else { + goToScreen?.('election') + } + } + + const onSendButtonClick = () => { + if (approveOverview) { + submitApplication() + } else { + setError('applicationApprove', { + type: 'error', + }) + } + } + + return ( + + + + + + + + + + {formatMessage(m.expensesIncome)} + + + + + + + {formatMessage(m.expenses)} + + + + + + + + + + + + + + {formatMessage(m.propertiesAndDebts)} + + + + + + + + {fileName ? ( + <> + + + + ) : null} + + + + + {formatMessage(m.overview)} + + + + { + return ( + { + onChange(e.target.checked) + setApproveOverview(e.target.checked) + setValue('applicationApprove' as string, e.target.checked) + }} + checked={value} + name="applicationApprove" + id="applicationApprove" + label={formatMessage(m.overviewCorrect)} + large + /> + ) + }} + /> + + {errors && getErrorViaPath(errors, 'applicationApprove') ? ( + + ) : null} + {submitError ? ( + + + + ) : null} + + + ) +} diff --git a/libs/application/templates/inao/financial-statement-political-party/src/fields/PartyOperatingIncome/PartyExpenses.tsx b/libs/application/templates/inao/financial-statement-political-party/src/fields/PartyOperatingIncome/PartyExpenses.tsx new file mode 100644 index 000000000000..5a3eadacb74b --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/fields/PartyOperatingIncome/PartyExpenses.tsx @@ -0,0 +1,56 @@ +import React, { Fragment } from 'react' +import debounce from 'lodash/debounce' +import { RecordObject } from '@island.is/application/types' +import { InputController } from '@island.is/shared/form-fields' +import { Box } from '@island.is/island-ui/core' +import { useFormContext } from 'react-hook-form' +import { useLocale } from '@island.is/localization' +import { getErrorViaPath } from '@island.is/application/core' +import { m } from '../../lib/messages' +import { INPUTCHANGEINTERVAL, PARTYOPERATIONIDS } from '../../utils/constants' + +interface PropTypes { + getSum: () => void + errors: RecordObject | undefined +} + +export const PartyExpenses = ({ errors, getSum }: PropTypes): JSX.Element => { + const { formatMessage } = useLocale() + const { clearErrors } = useFormContext() + + const onInputChange = debounce((fieldId: string) => { + getSum() + clearErrors(fieldId) + }, INPUTCHANGEINTERVAL) + + return ( + + + onInputChange(PARTYOPERATIONIDS.electionOffice)} + error={ + errors && getErrorViaPath(errors, PARTYOPERATIONIDS.electionOffice) + } + rightAlign + backgroundColor="blue" + currency + /> + + + onInputChange(PARTYOPERATIONIDS.otherCost)} + error={errors && getErrorViaPath(errors, PARTYOPERATIONIDS.otherCost)} + rightAlign + backgroundColor="blue" + currency + /> + + + ) +} diff --git a/libs/application/templates/inao/financial-statement-political-party/src/fields/PartyOperatingIncome/PartyIncome.tsx b/libs/application/templates/inao/financial-statement-political-party/src/fields/PartyOperatingIncome/PartyIncome.tsx new file mode 100644 index 000000000000..26c702129598 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/fields/PartyOperatingIncome/PartyIncome.tsx @@ -0,0 +1,206 @@ +import React, { Fragment, useEffect } from 'react' +import debounce from 'lodash/debounce' +import { RecordObject } from '@island.is/application/types' +import { Box } from '@island.is/island-ui/core' +import { InputController } from '@island.is/shared/form-fields' +import { useFormContext } from 'react-hook-form' +import { useLocale } from '@island.is/localization' +import { getErrorViaPath, getValueViaPath } from '@island.is/application/core' +import { m } from '../../lib/messages' +import { FinancialStatementsInaoTaxInfo } from '@island.is/api/schema' +import { INPUTCHANGEINTERVAL, PARTYOPERATIONIDS } from '../../utils/constants' + +interface PropTypes { + data?: { + financialStatementsInaoTaxInfo: FinancialStatementsInaoTaxInfo[] + } | null + loading: boolean + getSum: () => void + errors: RecordObject | undefined +} + +export const PartyIncome = ({ + data, + loading, + errors, + getSum, +}: PropTypes): JSX.Element => { + const { formatMessage } = useLocale() + const { clearErrors, getValues, setValue } = useFormContext() + useEffect(() => { + const values = getValues() + + const contributionsFromTheTreasury = getValueViaPath( + values, + PARTYOPERATIONIDS.contributionsFromTheTreasury, + ) + const parliamentaryPartySupport = getValueViaPath( + values, + PARTYOPERATIONIDS.parliamentaryPartySupport, + ) + const municipalContributions = getValueViaPath( + values, + PARTYOPERATIONIDS.municipalContributions, + ) + + if (data?.financialStatementsInaoTaxInfo) { + if (!contributionsFromTheTreasury) { + setValue( + PARTYOPERATIONIDS.contributionsFromTheTreasury, + data.financialStatementsInaoTaxInfo?.[0]?.value?.toString() ?? '', + ) + } + if (!parliamentaryPartySupport) { + setValue( + PARTYOPERATIONIDS.parliamentaryPartySupport, + data.financialStatementsInaoTaxInfo?.[1]?.value?.toString() ?? '', + ) + } + if (!municipalContributions) { + setValue( + PARTYOPERATIONIDS.municipalContributions, + data.financialStatementsInaoTaxInfo?.[2]?.value?.toString() ?? '', + ) + } + } + getSum() + }, [data, getSum, setValue]) + + const onInputChange = debounce((fieldId: string) => { + getSum() + clearErrors(fieldId) + }, INPUTCHANGEINTERVAL) + + return ( + + + + onInputChange(PARTYOPERATIONIDS.contributionsFromTheTreasury) + } + rightAlign + backgroundColor="blue" + loading={loading} + currency + error={ + errors && + getErrorViaPath( + errors, + PARTYOPERATIONIDS.contributionsFromTheTreasury, + ) + } + /> + + + + onInputChange(PARTYOPERATIONIDS.parliamentaryPartySupport) + } + loading={loading} + backgroundColor="blue" + rightAlign + currency + error={ + errors && + getErrorViaPath(errors, PARTYOPERATIONIDS.parliamentaryPartySupport) + } + /> + + + + onInputChange(PARTYOPERATIONIDS.municipalContributions) + } + loading={loading} + backgroundColor="blue" + rightAlign + currency + error={ + errors && + getErrorViaPath(errors, PARTYOPERATIONIDS.municipalContributions) + } + /> + + + + onInputChange(PARTYOPERATIONIDS.contributionsFromLegalEntities) + } + backgroundColor="blue" + currency + error={ + errors && + getErrorViaPath( + errors, + PARTYOPERATIONIDS.contributionsFromLegalEntities, + ) + } + /> + + + + onInputChange(PARTYOPERATIONIDS.contributionsFromIndividuals) + } + backgroundColor="blue" + currency + error={ + errors && + getErrorViaPath( + errors, + PARTYOPERATIONIDS.contributionsFromIndividuals, + ) + } + /> + + + + onInputChange(PARTYOPERATIONIDS.generalMembershipFees) + } + rightAlign + backgroundColor="blue" + currency + error={ + errors && + getErrorViaPath(errors, PARTYOPERATIONIDS.generalMembershipFees) + } + /> + + + onInputChange(PARTYOPERATIONIDS.otherIncome)} + rightAlign + backgroundColor="blue" + currency + error={ + errors && getErrorViaPath(errors, PARTYOPERATIONIDS.otherIncome) + } + /> + + + ) +} diff --git a/libs/application/templates/inao/financial-statement-political-party/src/fields/PartyOperatingIncome/PartyOperatingIncome.tsx b/libs/application/templates/inao/financial-statement-political-party/src/fields/PartyOperatingIncome/PartyOperatingIncome.tsx new file mode 100644 index 000000000000..14c43d56e667 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/fields/PartyOperatingIncome/PartyOperatingIncome.tsx @@ -0,0 +1,89 @@ +import React from 'react' +import { useFormContext } from 'react-hook-form' +import { useQuery } from '@apollo/client' +import { + GridColumn, + GridContainer, + GridRow, + Text, +} from '@island.is/island-ui/core' +import { useLocale } from '@island.is/localization' + +import { m } from '../../lib/messages' +import { PartyIncome } from './PartyIncome' +import { PartyExpenses } from './PartyExpenses' + +import { TaxInfoQuery } from '../../graphql' +import { getValueViaPath } from '@island.is/application/core' +import { FieldBaseProps } from '@island.is/application/types' +import { Total } from '../../components/Total' +import { useTotals } from '../../hooks/useTotals' +import { OPERATINGCOST, PARTYOPERATIONIDS } from '../../utils/constants' + +export const PartyOperatingIncome = ({ application }: FieldBaseProps) => { + const { answers } = application + const operatingYear = getValueViaPath( + answers, + 'conditionalAbout.operatingYear', + ) + + const { data, loading } = useQuery(TaxInfoQuery, { + variables: { year: operatingYear }, + }) + + const { + formState: { errors }, + } = useFormContext() + + const [getTotalIncome, totalIncome] = useTotals( + PARTYOPERATIONIDS.incomePrefix, + ) + const [getTotalExpense, totalExpense] = useTotals( + PARTYOPERATIONIDS.expensePrefix, + ) + const { formatMessage } = useLocale() + + return ( + + + + + {formatMessage(m.income)} + + + + + + + {formatMessage(m.expenses)} + + + + + + + + + + + + ) +} diff --git a/libs/application/templates/inao/financial-statement-political-party/src/fields/PartyOverview/PartyOverview.tsx b/libs/application/templates/inao/financial-statement-political-party/src/fields/PartyOverview/PartyOverview.tsx new file mode 100644 index 000000000000..363492b42d03 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/fields/PartyOverview/PartyOverview.tsx @@ -0,0 +1,222 @@ +import { useState } from 'react' +import { DefaultEvents, FieldBaseProps } from '@island.is/application/types' +import { + AlertBanner, + Box, + Checkbox, + Divider, + GridColumn, + GridRow, + InputError, + Text, +} from '@island.is/island-ui/core' +import { getErrorViaPath } from '@island.is/application/core' +import { Controller, useFormContext } from 'react-hook-form' +import { useLocale } from '@island.is/localization' +import { m } from '../../lib/messages' +import { useSubmitApplication } from '../../hooks/useSubmitApplication' +import { FinancialStatementPoliticalParty } from '../../lib/dataSchema' +import { formatCurrency } from '../../utils/helpers' +import { ValueLine } from '../../components/ValueLine' +import { FileValueLine } from '../../components/FileValueLine' +import { AssetDebtEquityOverview } from '../../components/AssetDebtEquityOverview' +import { AboutOverview } from '../../components/AboutOverview' +import BottomBar from '../../components/BottomBar' +import { + sectionColumn, + starterColumnStyle, +} from '../../components/css/overviewStyles.css' +import { CapitalNumberOverview } from '../../components/CapitalNumberOverview' + +export const PartyOverview = ({ + application, + goToScreen, + refetch, +}: FieldBaseProps) => { + const { formatMessage } = useLocale() + const [approveOverview, setApproveOverview] = useState(false) + const { + setError, + setValue, + formState: { errors }, + } = useFormContext() + const answers = application.answers as FinancialStatementPoliticalParty + const fileName = answers.attachments?.file?.[0]?.name + const [submitApplication, { error: submitError, loading }] = + useSubmitApplication({ + application, + refetch, + event: DefaultEvents.SUBMIT, + }) + + const onBackButtonClick = () => { + goToScreen?.('attachments.file') + } + + const onSendButtonClick = () => { + if (approveOverview) { + submitApplication() + } else { + setError('applicationApprove', { + type: 'error', + }) + } + } + + return ( + + + + + + + + + + {formatMessage(m.expensesIncome)} + + + + + + + {formatMessage(m.income)} + + + + + + + + + + + + + + + + {formatMessage(m.expenses)} + + + + + + + + + + + + + + + + + {formatMessage(m.propertiesAndDebts)} + + + + + + + {fileName ? ( + <> + + + + ) : null} + + + {formatMessage(m.overview)} + + + + { + return ( + { + onChange(e.target.checked) + setApproveOverview(e.target.checked) + setValue('applicationApprove' as string, e.target.checked) + }} + checked={value} + name="applicationApprove" + id="applicationApprove" + label={formatMessage(m.overviewCorrect)} + large + /> + ) + }} + /> + + {errors && getErrorViaPath(errors, 'applicationApprove') ? ( + + ) : null} + {submitError ? ( + + + + ) : null} + + + ) +} diff --git a/libs/application/templates/inao/financial-statement-political-party/src/fields/PowerOfAttorneyFields/PowerOfAttorneyFields.tsx b/libs/application/templates/inao/financial-statement-political-party/src/fields/PowerOfAttorneyFields/PowerOfAttorneyFields.tsx new file mode 100644 index 000000000000..07b7fb4a95bd --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/fields/PowerOfAttorneyFields/PowerOfAttorneyFields.tsx @@ -0,0 +1,97 @@ +import React, { useEffect } from 'react' +import { useFormContext } from 'react-hook-form' +import { useLazyQuery } from '@apollo/client' +import { + Box, + GridColumn, + GridContainer, + GridRow, + InputError, +} from '@island.is/island-ui/core' +import { InputController } from '@island.is/shared/form-fields' +import { useLocale } from '@island.is/localization' +import { IdentityInput, Query } from '@island.is/api/schema' + +import { m } from '../../lib/messages' +import { ABOUTIDS } from '../../utils/constants' +import { FieldBaseProps } from '@island.is/application/types' +import { getErrorViaPath } from '@island.is/application/core' +import { IdentityQuery } from '../../graphql' + +export const PowerOfAttorneyFields = ({ application }: FieldBaseProps) => { + const { formatMessage } = useLocale() + const { + formState: { errors }, + setValue, + } = useFormContext() + + const currentActor = + application.applicantActors[application.applicantActors.length - 1] + + const [getIdentity, { loading, error: queryError }] = useLazyQuery< + Query, + { input: IdentityInput } + >(IdentityQuery, { + onCompleted: (data) => { + setValue(ABOUTIDS.powerOfAttorneyName, data.identity?.name ?? '') + }, + }) + + useEffect(() => { + if (currentActor) { + getIdentity({ + variables: { + input: { + nationalId: currentActor, + }, + }, + }) + } + }, []) + + if (application.applicantActors.length === 0) { + return null + } + + return ( + + + + + + + + + + + {queryError ? ( + + ) : null} + + + + + ) +} diff --git a/libs/application/templates/inao/financial-statement-political-party/src/fields/Success/Success.tsx b/libs/application/templates/inao/financial-statement-political-party/src/fields/Success/Success.tsx new file mode 100644 index 000000000000..1603815ae9d1 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/fields/Success/Success.tsx @@ -0,0 +1,54 @@ +import { + Box, + ContentBlock, + ActionCard, + AlertMessage, +} from '@island.is/island-ui/core' +import { useLocale } from '@island.is/localization' +import { CustomField, FieldBaseProps } from '@island.is/application/types' +import format from 'date-fns/format' +import { m } from '../../lib/messages' +import { FinancialStatementPoliticalParty } from '../../lib/dataSchema' + +interface PropTypes extends FieldBaseProps { + field: CustomField +} + +export const Success = ({ application }: PropTypes) => { + const applicationAnswers = + application.answers as FinancialStatementPoliticalParty + const { formatMessage } = useLocale() + + const getDescriptionText = () => { + const currentDate = format(new Date(), "dd.MM.yyyy 'kl.' kk:mm") + return `${formatMessage(m.operatingYearMsgFirst)} ${ + applicationAnswers.conditionalAbout.operatingYear + } + ${formatMessage(m.individualReceivedMsgSecond)} ${currentDate}` + } + + return ( + + + + + + + window.open('/minarsidur/postholf', '_blank'), + }} + backgroundColor="blue" + /> + + + + ) +} diff --git a/libs/application/templates/inao/financial-statement-political-party/src/fields/index.ts b/libs/application/templates/inao/financial-statement-political-party/src/fields/index.ts new file mode 100644 index 000000000000..45ccedc9d599 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/fields/index.ts @@ -0,0 +1,10 @@ +export { OperatingYear } from './OperatingYear/OperatingYear' +export { PowerOfAttorneyFields } from './PowerOfAttorneyFields/PowerOfAttorneyFields' +export { DelegationCheck } from './DelegationCheck/DelegationCheck' +export { PartyOperatingIncome } from './PartyOperatingIncome/PartyOperatingIncome' +export { KeyNumbersCapital } from './KeyNumbersCapital/KeyNumbersCapital' +export { ElectionEquities } from './ElectionEquities/ElectionEquities' +export { PartyOverview } from './PartyOverview/PartyOverview' +export { Overview } from './Overview/Overview' +export { ElectionStatement } from './ElectionStatement/ElectionStatement' +export { Success } from './Success/Success' diff --git a/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/clientInfoSection/index.ts b/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/clientInfoSection/index.ts new file mode 100644 index 000000000000..6343af9dfa42 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/clientInfoSection/index.ts @@ -0,0 +1,94 @@ +import { + buildCustomField, + buildDescriptionField, + buildMultiField, + buildSection, + buildTextField, +} from '@island.is/application/core' +import { m } from '../../../lib/messages' +import { ABOUTIDS } from '../../../utils/constants' +import { Application, UserProfile } from '@island.is/application/types' +import { Identity } from '@island.is/clients/identity' + +export const clientInfoSection = buildSection({ + id: 'info', + title: m.info, + children: [ + buildMultiField({ + id: 'about', + title: m.info, + description: m.reviewContact, + children: [ + buildDescriptionField({ + id: ABOUTIDS.operatingYear, + title: '', + }), + buildCustomField({ + id: 'OperatingYear', + childInputIds: [ABOUTIDS.operatingYear], + title: '', + component: 'OperatingYear', + }), + buildTextField({ + id: 'about.nationalId', + title: m.clientNationalId, + width: 'half', + readOnly: true, + format: '######-####', + defaultValue: (application: Application) => application.applicant, + }), + buildTextField({ + id: 'about.fullName', + title: m.clientName, + width: 'half', + readOnly: true, + defaultValue: (application: Application) => { + const nationalRegistry = application.externalData.identity + .data as Identity + return nationalRegistry.name + }, + }), + buildDescriptionField({ + id: ABOUTIDS.powerOfAttorneyName, + title: '', + }), + buildCustomField({ + id: 'powerOfAttorney', + title: '', + component: 'PowerOfAttorneyFields', + childInputIds: [ + ABOUTIDS.powerOfAttorneyNationalId, + ABOUTIDS.powerOfAttorneyName, + ], + }), + buildTextField({ + id: 'about.email', + title: m.email, + width: 'half', + variant: 'email', + defaultValue: (application: Application) => { + const userProfile = application.externalData.userProfile + .data as UserProfile + return userProfile.email + }, + }), + buildTextField({ + id: 'about.phoneNumber', + title: m.phoneNumber, + width: 'half', + variant: 'tel', + defaultValue: (application: Application) => { + const userProfile = application.externalData.userProfile + .data as UserProfile + return userProfile.mobilePhoneNumber + }, + }), + buildCustomField({ + id: 'delegationCheck', + title: '', + component: 'DelegationCheck', + }), + ], + }), + ], +}) diff --git a/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/index.ts b/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/index.ts new file mode 100644 index 000000000000..bca7ac51bc34 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/index.ts @@ -0,0 +1,22 @@ +import { buildForm } from '@island.is/application/core' +import { m } from '../../lib/messages' +import { Form, FormModes } from '@island.is/application/types' +import Logo from '../../components/Logo' +import { clientInfoSection } from './clientInfoSection' +import { keyNumbersSection } from './keyNumbersSection' +import { financialStatementSection } from './keyNumbersSection/financialStatementSection' +import { overviewSection } from './keyNumbersSection/overviewSection' + +export const FinancialStatementPoliticalPartyForm: Form = buildForm({ + id: 'FinancialStatementPoliticalPartyForm', + title: m.applicationTitle, + mode: FormModes.DRAFT, + renderLastScreenButton: false, + logo: Logo, + children: [ + clientInfoSection, + keyNumbersSection, + financialStatementSection, + overviewSection, + ], +}) diff --git a/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/keyNumbersSection/capitalNumbersSubsection/index.ts b/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/keyNumbersSection/capitalNumbersSubsection/index.ts new file mode 100644 index 000000000000..42e21bf1259e --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/keyNumbersSection/capitalNumbersSubsection/index.ts @@ -0,0 +1,28 @@ +import { + buildCustomField, + buildMultiField, + buildSubSection, +} from '@island.is/application/core' +import { m } from '../../../../lib/messages' +import { CAPITALNUMBERS } from '../../../../utils/constants' + +export const capitalNumbersSubsection = buildSubSection({ + id: 'keynumbers.capitalNumbers', + title: m.capitalNumbers, + children: [ + buildMultiField({ + id: 'capitalNumber', + title: m.capitalNumbersSectionTitle, + description: m.fillOutAppopriate, + children: [ + buildCustomField({ + id: 'capitalNumberField', + title: '', + description: '', + component: 'KeyNumbersCapital', + childInputIds: Object.values(CAPITALNUMBERS), + }), + ], + }), + ], +}) diff --git a/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/keyNumbersSection/equitiesAndLiabilitiesSubsection/index.ts b/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/keyNumbersSection/equitiesAndLiabilitiesSubsection/index.ts new file mode 100644 index 000000000000..6920f444dac6 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/keyNumbersSection/equitiesAndLiabilitiesSubsection/index.ts @@ -0,0 +1,17 @@ +import { buildCustomField, buildSubSection } from '@island.is/application/core' +import { m } from '../../../../lib/messages' +import { EQUITIESANDLIABILITIESIDS } from '../../../../utils/constants' + +export const equitiesAndLiabilitiesSubsection = buildSubSection({ + id: 'keyNumbers.equitiesAndLiabilities', + title: m.propertiesAndDebts, + children: [ + buildCustomField({ + id: 'equitiesAndLiabilities', + title: m.keyNumbersDebt, + description: m.fillOutAppopriate, + component: 'ElectionEquities', + childInputIds: Object.values(EQUITIESANDLIABILITIESIDS), + }), + ], +}) diff --git a/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/keyNumbersSection/financialStatementSection/index.ts b/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/keyNumbersSection/financialStatementSection/index.ts new file mode 100644 index 000000000000..6f40b92fc14d --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/keyNumbersSection/financialStatementSection/index.ts @@ -0,0 +1,30 @@ +import { + buildFileUploadField, + buildSection, + getValueViaPath, +} from '@island.is/application/core' +import { m } from '../../../../lib/messages' +import { LESS } from '../../../../utils/constants' + +export const financialStatementSection = buildSection({ + id: 'documents', + title: m.financialStatement, + condition: (answers, _externalData) => { + const incomeLimit = getValueViaPath(answers, 'election.incomeLimit') + return incomeLimit !== LESS + }, + children: [ + buildFileUploadField({ + id: 'attachments.file', + title: m.upload, + introduction: m.uploadIntro, + description: m.uploadDescription, + uploadHeader: m.uploadHeader, + uploadAccept: '.pdf', + uploadDescription: m.uploadAccept, + uploadButtonLabel: m.uploadButtonLabel, + uploadMultiple: false, + forImageUpload: false, + }), + ], +}) diff --git a/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/keyNumbersSection/index.ts b/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/keyNumbersSection/index.ts new file mode 100644 index 000000000000..dee0b831047e --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/keyNumbersSection/index.ts @@ -0,0 +1,15 @@ +import { buildSection } from '@island.is/application/core' +import { m } from '../../../lib/messages' +import { operatingCostSubsection } from './operatingCostSubsection' +import { capitalNumbersSubsection } from './capitalNumbersSubsection' +import { equitiesAndLiabilitiesSubsection } from './equitiesAndLiabilitiesSubsection' + +export const keyNumbersSection = buildSection({ + id: 'keyNumbers', + title: m.keyNumbers, + children: [ + operatingCostSubsection, + capitalNumbersSubsection, + equitiesAndLiabilitiesSubsection, + ], +}) diff --git a/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/keyNumbersSection/operatingCostSubsection/index.ts b/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/keyNumbersSection/operatingCostSubsection/index.ts new file mode 100644 index 000000000000..fbc76af55a1b --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/keyNumbersSection/operatingCostSubsection/index.ts @@ -0,0 +1,17 @@ +import { buildCustomField, buildSubSection } from '@island.is/application/core' +import { m } from '../../../../lib/messages' +import { PARTYOPERATIONIDS } from '../../../../utils/constants' + +export const operatingCostSubsection = buildSubSection({ + id: 'operatingCost', + title: m.expensesIncome, + children: [ + buildCustomField({ + id: 'partyOperations', + title: m.keyNumbersIncomeAndExpenses, + description: m.fillOutAppopriate, + component: 'PartyOperatingIncome', + childInputIds: Object.values(PARTYOPERATIONIDS), + }), + ], +}) diff --git a/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/keyNumbersSection/overviewSection/index.ts b/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/keyNumbersSection/overviewSection/index.ts new file mode 100644 index 000000000000..543a96b5fa01 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/keyNumbersSection/overviewSection/index.ts @@ -0,0 +1,9 @@ +import { buildSection } from '@island.is/application/core' +import { overviewMultiField } from './overviewMultiField' +import { m } from '../../../../lib/messages' + +export const overviewSection = buildSection({ + id: 'overviewSection', + title: m.overviewSectionTitle, + children: [overviewMultiField], +}) diff --git a/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/keyNumbersSection/overviewSection/overviewMultiField.ts b/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/keyNumbersSection/overviewSection/overviewMultiField.ts new file mode 100644 index 000000000000..d466187af16c --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/forms/applicationForm/keyNumbersSection/overviewSection/overviewMultiField.ts @@ -0,0 +1,37 @@ +import { + buildCustomField, + buildMultiField, + getValueViaPath, +} from '@island.is/application/core' +import { m } from '../../../../lib/messages' +import { GREATER, LESS } from '../../../../utils/constants' + +export const overviewMultiField = buildMultiField({ + id: 'overview', + title: m.yearlyOverview, + description: m.review, + children: [ + buildCustomField({ + id: 'overviewPartyField', + title: '', + doesNotRequireAnswer: true, + component: 'PartyOverview', + }), + buildCustomField({ + id: 'overviewField', + title: '', + condition: (answers) => + getValueViaPath(answers, 'election.incomeLimit') === GREATER, + doesNotRequireAnswer: true, + component: 'Overview', + }), + buildCustomField({ + id: 'overviewStatementField', + title: '', + condition: (answers) => + getValueViaPath(answers, 'election.incomeLimit') === LESS, + doesNotRequireAnswer: true, + component: 'ElectionStatement', + }), + ], +}) diff --git a/libs/application/templates/inao/financial-statement-political-party/src/forms/done/conclusionSection/index.ts b/libs/application/templates/inao/financial-statement-political-party/src/forms/done/conclusionSection/index.ts new file mode 100644 index 000000000000..d6b9add9c2e4 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/forms/done/conclusionSection/index.ts @@ -0,0 +1,24 @@ +import { + buildCustomField, + buildMultiField, + buildSection, +} from '@island.is/application/core' +import { m } from '../../../lib/messages' + +export const conclusionSection = buildSection({ + id: 'conclusionSection', + title: '', + children: [ + buildMultiField({ + id: 'conclusion', + title: m.received, + children: [ + buildCustomField({ + id: 'overview', + component: 'Success', + title: m.applicationAccept, + }), + ], + }), + ], +}) diff --git a/libs/application/templates/inao/financial-statement-political-party/src/forms/done/index.ts b/libs/application/templates/inao/financial-statement-political-party/src/forms/done/index.ts new file mode 100644 index 000000000000..bfb95dec1cee --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/forms/done/index.ts @@ -0,0 +1,10 @@ +import { buildForm } from '@island.is/application/core' +import { Form, FormModes } from '@island.is/application/types' +import { conclusionSection } from './conclusionSection' + +export const done: Form = buildForm({ + id: 'done', + title: 'Umsókn móttekin', + mode: FormModes.COMPLETED, + children: [conclusionSection], +}) diff --git a/libs/application/templates/inao/financial-statement-political-party/src/forms/prerequsites/index.ts b/libs/application/templates/inao/financial-statement-political-party/src/forms/prerequsites/index.ts new file mode 100644 index 000000000000..e8f8d9631b70 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/forms/prerequsites/index.ts @@ -0,0 +1,13 @@ +import { buildForm } from '@island.is/application/core' +import { Form, FormModes } from '@island.is/application/types' +import Logo from '../../components/Logo' +import { prerequisitesSection } from './prerequsitesSection' + +export const PrerequisitesForm: Form = buildForm({ + id: 'PrerequisitesForm', + title: '', + mode: FormModes.NOT_STARTED, + renderLastScreenButton: true, + logo: Logo, + children: [prerequisitesSection], +}) diff --git a/libs/application/templates/inao/financial-statement-political-party/src/forms/prerequsites/prerequsitesSection.ts b/libs/application/templates/inao/financial-statement-political-party/src/forms/prerequsites/prerequsitesSection.ts new file mode 100644 index 000000000000..40dca0ccb508 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/forms/prerequsites/prerequsitesSection.ts @@ -0,0 +1,56 @@ +import { + buildDataProviderItem, + buildExternalDataProvider, + buildSection, + buildSubmitField, + coreMessages, +} from '@island.is/application/core' +import { m } from '../../lib/messages' +import { + CurrentUserTypeProvider, + IndentityApiProvider, + UserInfoApi, +} from '../../dataProviders' +import { DefaultEvents } from '@island.is/application/types' + +export const prerequisitesSection = buildSection({ + id: 'ExternalDataSection', + title: '', + children: [ + buildExternalDataProvider({ + id: 'approveExternalData', + title: m.dataCollectionTitleUserParty, + checkboxLabel: m.dataCollectionCheckboxLabel, + dataProviders: [ + buildDataProviderItem({ + provider: IndentityApiProvider, + title: m.dataCollectionNationalRegistryTitle, + subTitle: m.dataCollectionNationalRegistrySubtitle, + }), + buildDataProviderItem({ + provider: UserInfoApi, + title: m.dataCollectionUserProfileTitle, + subTitle: m.dataCollectionUserProfileSubtitle, + }), + buildDataProviderItem({ + provider: CurrentUserTypeProvider, + title: m.dataCollectionUserFinancialInfoTitle, + subTitle: m.dataCollectionUserFinancialInfo, + }), + ], + submitField: buildSubmitField({ + id: 'submit', + placement: 'footer', + title: '', + refetchApplicationAfterSubmit: true, + actions: [ + { + event: DefaultEvents.SUBMIT, + name: coreMessages.buttonNext, + type: 'primary', + }, + ], + }), + }), + ], +}) diff --git a/libs/application/templates/inao/financial-statement-political-party/src/graphql/index.ts b/libs/application/templates/inao/financial-statement-political-party/src/graphql/index.ts new file mode 100644 index 000000000000..75f10290eeca --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/graphql/index.ts @@ -0,0 +1,28 @@ +import { gql } from '@apollo/client' + +export const auditConfigQuery = gql` + query FinancialStatementsInaoConfig { + financialStatementsInaoConfig { + value + key + } + } +` + +export const IdentityQuery = gql` + query IdentityQuery($input: IdentityInput!) { + identity(input: $input) { + name + nationalId + } + } +` + +export const TaxInfoQuery = gql` + query TaxInfoQuery($year: String!) { + financialStatementsInaoTaxInfo(year: $year) { + key + value + } + } +` diff --git a/libs/application/templates/inao/financial-statement-political-party/src/hooks/useSubmitApplication.tsx b/libs/application/templates/inao/financial-statement-political-party/src/hooks/useSubmitApplication.tsx new file mode 100644 index 000000000000..de5e2838cb93 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/hooks/useSubmitApplication.tsx @@ -0,0 +1,43 @@ +import { MutationTuple, useMutation } from '@apollo/client' +import { DefaultEvents, Application } from '@island.is/application/types' +import { SUBMIT_APPLICATION } from '@island.is/application/graphql' + +export interface UseSubmitApplication { + (params: { + application: Application + refetch: (() => void) | undefined + event: DefaultEvents + }): MutationTuple< + void, + { + input: { + id: Application['id'] + event: DefaultEvents + answers: Application['answers'] + } + } + > +} + +export const useSubmitApplication: UseSubmitApplication = ({ + application, + refetch, + event, +}) => { + return useMutation(SUBMIT_APPLICATION, { + onError: (e) => { + console.error(e.message) + return + }, + onCompleted: () => { + refetch?.() + }, + variables: { + input: { + id: application.id, + event, + answers: application.answers, + }, + }, + }) +} diff --git a/libs/application/templates/inao/financial-statement-political-party/src/hooks/useTotals.tsx b/libs/application/templates/inao/financial-statement-political-party/src/hooks/useTotals.tsx new file mode 100644 index 000000000000..6d6ebfde264c --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/hooks/useTotals.tsx @@ -0,0 +1,19 @@ +import { useCallback, useEffect, useState } from 'react' +import { useFormContext } from 'react-hook-form' +import { getTotal } from '../utils/helpers' + +export const useTotals = (key: string): [() => void, number] => { + const [total, setTotal] = useState(0) + const { getValues } = useFormContext() + const getSum = useCallback(() => { + const values = getValues() + const sum = getTotal(values, key) + setTotal(sum) + }, [key, getValues, setTotal]) + + useEffect(() => { + getSum() + }, [getSum]) + + return [getSum, total] +} diff --git a/libs/application/templates/inao/financial-statement-political-party/src/index.ts b/libs/application/templates/inao/financial-statement-political-party/src/index.ts new file mode 100644 index 000000000000..2f1b1f310335 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/index.ts @@ -0,0 +1,6 @@ +import FinancialStatementPoliticalPartyTemplate from './lib/financialStatementPoliticalPartyTemplate' + +export const getDataProviders = () => import('./dataProviders') +export const getFields = () => import('./fields') + +export default FinancialStatementPoliticalPartyTemplate diff --git a/libs/application/templates/inao/financial-statement-political-party/src/lib/dataSchema.ts b/libs/application/templates/inao/financial-statement-political-party/src/lib/dataSchema.ts new file mode 100644 index 000000000000..33f3ea983270 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/lib/dataSchema.ts @@ -0,0 +1,113 @@ +import { z } from 'zod' +import { m } from './messages' +import * as kennitala from 'kennitala' +import { parsePhoneNumberFromString } from 'libphonenumber-js/min' +import { checkIfNegative } from '../utils/helpers' + +const requiredNonNegativeString = z + .string() + .refine((x) => !!x, { params: m.required }) + .refine((x) => checkIfNegative(x), { params: m.negativeNumberError }) + +const requiredString = z.string().refine((x) => !!x, { params: m.required }) + +const FileSchema = z.object({ + name: z.string(), + key: z.string(), + url: z.string().optional(), +}) +const conditionalAbout = z.object({ + operatingYear: requiredString, +}) +const about = z.object({ + nationalId: z + .string() + .refine((val) => (val ? kennitala.isValid(val) : false), { + params: m.nationalIdError, + }), + fullName: requiredString, + powerOfAttorneyNationalId: z.string().optional(), + powerOfAttorneyName: z.string().optional(), + phoneNumber: z.string().refine( + (p) => { + const phoneNumber = parsePhoneNumberFromString(p, 'IS') + return phoneNumber?.isValid() + }, + { params: m.dataSchemePhoneNumber }, + ), + email: z.string().email(), +}) + +const election = z.object({ + selectElection: z.string().optional(), + electionName: z.string().optional(), + genitiveName: z.string().optional(), + incomeLimit: requiredString, +}) + +const operatingCost = z.object({ + total: requiredString, +}) + +const partyIncome = z.object({ + contributionsFromTheTreasury: requiredNonNegativeString, + parliamentaryPartySupport: requiredNonNegativeString, + municipalContributions: requiredNonNegativeString, + contributionsFromLegalEntities: requiredNonNegativeString, + contributionsFromIndividuals: requiredNonNegativeString, + generalMembershipFees: requiredNonNegativeString, + otherIncome: requiredNonNegativeString, + total: z.string(), +}) + +const partyExpense = z.object({ + electionOffice: requiredNonNegativeString, + otherCost: requiredNonNegativeString, + total: z.string(), +}) + +const capitalNumbers = z.object({ + capitalIncome: requiredNonNegativeString, + capitalCost: requiredNonNegativeString, + total: z.string(), +}) + +const equityAndLiabilities = z.object({ + total: z.string(), +}) + +const asset = z.object({ + currentAssets: requiredNonNegativeString, + fixedAssetsTotal: requiredNonNegativeString, + total: requiredString, +}) + +const equity = z.object({ + totalEquity: requiredString, +}) + +const liability = z.object({ + longTerm: requiredNonNegativeString, + shortTerm: requiredNonNegativeString, + total: requiredNonNegativeString, +}) + +export const dataSchema = z.object({ + approveExternalData: z.literal(true), + conditionalAbout, + about, + election, // Needed?? + operatingCost, + partyIncome, + partyExpense, + capitalNumbers, + equityAndLiabilities, + asset, + equity, + liability, + attachments: z.object({ + file: z.array(FileSchema).nonempty(), + }), +}) + +export type FinancialStatementPoliticalParty = z.TypeOf diff --git a/libs/application/templates/inao/financial-statement-political-party/src/lib/financialStatementPoliticalPartyTemplate.ts b/libs/application/templates/inao/financial-statement-political-party/src/lib/financialStatementPoliticalPartyTemplate.ts new file mode 100644 index 000000000000..8324c1ec8af1 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/lib/financialStatementPoliticalPartyTemplate.ts @@ -0,0 +1,155 @@ +import { + ApplicationTemplate, + ApplicationTypes, + ApplicationContext, + ApplicationStateSchema, + ApplicationConfigurations, + Application, + ApplicationRole, + DefaultEvents, + defineTemplateApi, +} from '@island.is/application/types' +import { ApiActions, Events, Roles, States } from '../types/types' +import { m } from './messages' +import { dataSchema } from './dataSchema' +import { + DefaultStateLifeCycle, + pruneAfterDays, +} from '@island.is/application/core' +import { + CurrentUserTypeProvider, + IndentityApiProvider, + NationalRegistryUserApi, + UserInfoApi, +} from '../dataProviders' +import { AuthDelegationType } from '@island.is/shared/types' +import { Features } from '@island.is/feature-flags' + +const configuration = + ApplicationConfigurations[ + ApplicationTypes.FINANCIAL_STATEMENT_POLITICAL_PARTY + ] + +const FinancialStatementPoliticalPartyTemplate: ApplicationTemplate< + ApplicationContext, + ApplicationStateSchema, + Events +> = { + type: ApplicationTypes.FINANCIAL_STATEMENT_POLITICAL_PARTY, + name: m.applicationTitle, + institution: m.institutionName, + translationNamespaces: [configuration.translation], + dataSchema, + featureFlag: Features.FinancialStatementPoliticalPartyEnabled, + allowedDelegations: [{ type: AuthDelegationType.ProcurationHolder }], + stateMachineConfig: { + initial: States.PREREQUISITES, + states: { + [States.PREREQUISITES]: { + meta: { + name: States.PREREQUISITES, + progress: 0, + status: 'draft', + actionCard: { + pendingAction: { + title: '', + displayStatus: 'success', + }, + }, + lifecycle: pruneAfterDays(60), + roles: [ + { + id: Roles.APPLICANT, + formLoader: () => + import('../forms/prerequsites').then((val) => + Promise.resolve(val.PrerequisitesForm), + ), + + actions: [ + { + event: DefaultEvents.SUBMIT, + name: 'Submit', + type: 'primary', + }, + ], + write: 'all', + delete: true, + api: [ + CurrentUserTypeProvider, + IndentityApiProvider, + NationalRegistryUserApi, + UserInfoApi, + ], + }, + ], + }, + on: { + [DefaultEvents.SUBMIT]: [{ target: States.DRAFT }], + }, + }, + [States.DRAFT]: { + meta: { + name: States.DRAFT, + actionCard: { + title: m.applicationTitle, + }, + status: States.DRAFT, + lifecycle: pruneAfterDays(60), + roles: [ + { + id: Roles.APPLICANT, + formLoader: () => + import('../forms/applicationForm').then((val) => + Promise.resolve(val.FinancialStatementPoliticalPartyForm), + ), + actions: [ + { event: 'SUBMIT', name: 'Staðfesta', type: 'primary' }, + ], + write: 'all', + delete: true, + api: [ + CurrentUserTypeProvider, + IndentityApiProvider, + NationalRegistryUserApi, + UserInfoApi, + ], + }, + ], + }, + on: { + [DefaultEvents.SUBMIT]: { target: States.DONE }, + }, + }, + [States.DONE]: { + meta: { + name: States.DONE, + status: 'completed', + progress: 1, + lifecycle: DefaultStateLifeCycle, + onEntry: defineTemplateApi({ + action: ApiActions.submitApplication, + throwOnError: true, + }), + roles: [ + { + id: Roles.APPLICANT, + formLoader: () => import('../forms/done').then((val) => val.done), + read: 'all', + }, + ], + }, + }, + }, + }, + mapUserToRole( + nationalId: string, + application: Application, + ): ApplicationRole | undefined { + if (application.applicant === nationalId) { + return Roles.APPLICANT + } + return undefined + }, +} + +export default FinancialStatementPoliticalPartyTemplate diff --git a/libs/application/templates/inao/financial-statement-political-party/src/lib/messages.ts b/libs/application/templates/inao/financial-statement-political-party/src/lib/messages.ts new file mode 100644 index 000000000000..e82dddf8af80 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/lib/messages.ts @@ -0,0 +1,561 @@ +import { defineMessages } from 'react-intl' + +export const m = defineMessages({ + applicationTitle: { + id: 'fspp.application:title', + defaultMessage: 'Skil ársreikninga fyrir stjórnmálaflokka', + description: 'Application title', + }, + institutionName: { + id: 'fspp.application:institution', + defaultMessage: 'Ríkisendurskoðun', + description: `Institution's name`, + }, + inao: { + id: 'fspp.application:inao', + defaultMessage: 'Ríkisendurskoðun', + description: 'icelandic national audit', + }, + serviceProvider: { + id: 'fspp.application:serviceProvider', + defaultMessage: 'Þjónustuaðili', + description: 'service provider', + }, + dataCollectionTitleUserParty: { + id: 'fspp.application:applicationDataCollectionTitleUserParty', + defaultMessage: 'Gagnaöflun vegna skila ársreiknings stjórnmálaflokks', + description: 'Title for data collection section', + }, + dataCollectionCheckboxLabel: { + id: 'fspp.application:dataCollectionCheckboxLabel', + defaultMessage: + 'Ég skil að ofangreindra gagna verður aflað við vinnslu innsendingarinnar', + description: 'Checkbox label for data collection section', + }, + dataCollectionNationalRegistryTitle: { + id: 'fspp.application:dataCollectionNationalRegistryTitle', + defaultMessage: 'Persónuupplýsingar', + description: 'National registry title', + }, + dataCollectionNationalRegistrySubtitle: { + id: 'fspp.application:dataCollectionNationalRegistrySubtitle', + defaultMessage: 'Fullt nafn, kennitala, heimilisfang.', + description: 'National registry subtitle', + }, + dataCollectionUserProfileTitle: { + id: 'fspp.application:dataCollectionUserProfileTitle', + defaultMessage: 'Mínar síður á Ísland.is/stillingar', + description: 'Your user profile information', + }, + dataCollectionUserProfileSubtitle: { + id: 'fspp.application:dataCollectionUserProfileSubtitle', + defaultMessage: + 'Ef þú ert með skráðar upplýsingar um síma og netfang inni á Mínar síður á Ísland.is þá verða þær sjálfkrafa settar inn í umsóknina.', + description: + 'In order to apply for this application we need your email and phone number', + }, + dataCollectionUserFinancialInfoTitle: { + id: 'fspp.application:dataCollectionUserFinancialInfoTitle', + defaultMessage: 'Fjárhagsupplýsingar', + description: 'Financial info', + }, + dataCollectionUserFinancialInfo: { + id: 'fspp.application:dataCollectionUserFinancialInfo', + defaultMessage: + 'Til þess að auðvelda fyrir sækjum við fjárhagsupplýsingar til Ríkisendurskoðunar, sem embættið aflar frá viðeigandi aðilum á grundvelli aðgangs- og skoðunarheimilda sem það hefur, og forskráum þær.', + description: 'Financial info', + }, + info: { + id: 'fspp.application:info', + defaultMessage: 'Upplýsingar', + description: 'info', + }, + reviewContact: { + id: 'fspp.application:reviewContact', + defaultMessage: 'Vinsamlega yfirfarið upplýsingar um tengilið hér að neðan', + description: 'Review contact info', + }, + operatingYear: { + id: 'fspp.application:keyNumbers.operatingYear', + defaultMessage: 'Rekstrarár', + description: 'Operating year', + }, + selectOperatingYear: { + id: 'fspp.application:keyNumbers.selectOperatingYear', + defaultMessage: 'Veldu rekstrarár', + description: 'Select operating year', + }, + fetchErrorTitle: { + id: 'fspp.application:fetchErrorMsg', + defaultMessage: 'Eitthvað fór úrskeiðiðs', + description: 'Error msg title when fetching data fails', + }, + fetchErrorMsg: { + id: 'fspp.application:fetchError', + defaultMessage: 'Ekki tókst að sækja gögn, reyndur aftur seinna', + description: 'Error msg when fetching data fails', + }, + clientNationalId: { + id: 'fspp.application:clientNationalId', + defaultMessage: 'Kennitala viðskiptavinar', + description: 'client national id', + }, + clientName: { + id: 'fspp.application:clientName', + defaultMessage: 'Nafn viðskiptavinar', + description: 'client name', + }, + email: { + id: 'fspp.application:person.email', + defaultMessage: 'Netfang', + description: 'email', + }, + phoneNumber: { + id: 'fspp.application:about.phoneNumber', + defaultMessage: 'Símanúmer', + description: 'phone number', + }, + keyNumbers: { + id: 'fspp.application:keyNumbers', + defaultMessage: 'Lykiltölur', + description: 'Statement key numbers', + }, + powerOfAttorneyNationalId: { + id: 'fspp.application:powerOfAttorneyNationalId', + defaultMessage: 'Kennitala umboðsmanns', + description: `national id for power of attorney`, + }, + powerOfAttorneyName: { + id: 'fspp.application:powerOfAttorneyName', + defaultMessage: 'Nafn umboðsmanns', + description: `name for power of attorney`, + }, + errorFetchingName: { + id: 'fspp.application:error.errorFetchingName', + defaultMessage: 'Tókst ekki að sækja nafn umboðsmanns', + description: 'Could not fetch powerofattorney name', + }, + wrongDelegation: { + id: 'fspp.application:wrongDelegation', + defaultMessage: 'Eingöngu er hægt að skila fyrir hönd Stjórnmálasamtaka', + description: 'Logged in user with incorrect delegation type', + }, + genericError: { + id: 'fspp.application:error.genericError', + defaultMessage: 'Eitthvað fór úrskeiðis', + description: 'Generic error message', + }, + expensesIncome: { + id: 'fspp.application:keyNumbers.expensesIncome', + defaultMessage: 'Tekjur og gjöld', + description: 'Expenses and income', + }, + keyNumbersIncomeAndExpenses: { + id: 'fspp.application:keyNumbersIncomeAndExpenses', + defaultMessage: 'Lykiltölur - Tekjur og gjöld', + description: 'income and expenses of keynumbers', + }, + fillOutAppopriate: { + id: 'fspp.application:fillOutAppopriate', + defaultMessage: 'Vinsamlegast fylltu út þá reiti sem eiga við', + description: 'Fill out fields', + }, + contributionsFromTheTreasury: { + id: 'fspp.application:income.contributionsFromTheTreasury', + defaultMessage: 'Framlög úr ríkissjóði', + description: 'public donations', + }, + parliamentaryPartySupport: { + id: 'fspp.application:income.parliamentaryPartySupport', + defaultMessage: 'Þingflokksstyrkur', + description: 'Party donations', + }, + municipalContributions: { + id: 'fspp.application:income.municipalContributions', + defaultMessage: 'Framlög sveitarfélaga', + description: 'Municipality Donations', + }, + contributionsFromLegalEntities: { + id: 'fspp.application:income.contributionsFromLegalEntities', + defaultMessage: 'Framlög lögaðila', + description: 'Contributions From Legal Entities', + }, + contributionsFromIndividuals: { + id: 'fspp.application:income.contributionsFromIndividuals', + defaultMessage: 'Framlög einstaklinga', + description: 'Contributions From Individuals', + }, + generalMembershipFees: { + id: 'fspp.application:income.generalMembershipFees', + defaultMessage: 'Almenn félagsgjöld', + description: 'General membership fees', + }, + otherIncome: { + id: 'fspp.application:income.other', + defaultMessage: 'Aðrar tekjur', + description: 'Other income', + }, + electionOffice: { + id: 'fspp.application:income.electionOffice', + defaultMessage: 'Kosningaskrifstofa', + description: 'electionOffice', + }, + otherOperationalCost: { + id: 'fspp.application:income.otherOperationalCost', + defaultMessage: 'Annar rekstrarkostnaður', + description: 'Other costs', + }, + income: { + id: 'fspp.application:income', + defaultMessage: 'Tekjur', + description: 'Applicants income', + }, + totalIncome: { + id: 'fspp.application:income.totalIncome', + defaultMessage: 'Tekjur samtals:', + description: 'Total income', + }, + totalExpenses: { + id: 'fspp.application:income.totalExpenses', + defaultMessage: 'Gjöld samtals:', + description: 'Total expenses', + }, + expenses: { + id: 'fspp.application:keyNumbers.expenses', + defaultMessage: 'Gjöld', + description: 'expenses', + }, + operatingCost: { + id: 'fspp.application:keyNumbers.operatingCost', + defaultMessage: 'Rekstrarniðurstaða alls', + description: 'Operating Cost', + }, + operatingCostBefore: { + id: 'fspp.application:keyNumbers.operatingCostBeforeCapital', + defaultMessage: 'Rekstrarniðurstaða fyrir fjármagnsliði', + description: 'Operating Cost Capital', + }, + capitalNumbers: { + id: 'fspp.application:income.capitalNumbers', + defaultMessage: 'Fjármagnsliðir', + description: 'capital numbers', + }, + capitalNumbersSectionTitle: { + id: 'fspp.application:income.capitalNumbersSectionTitle', + defaultMessage: 'Lykiltölur Fjármagnsliðir', + description: 'capital numbers', + }, + capitalIncome: { + id: 'fspp.application:income.capital', + defaultMessage: 'Fjármagnstekjur', + description: 'capital income', + }, + capitalCost: { + id: 'fspp.application:income.capitalCost', + defaultMessage: 'Fjármagnsgjöld', + description: 'capital costs', + }, + totalCapital: { + id: 'fspp.application:totalCapital', + defaultMessage: 'Fjármagnsliðir samtals', + description: 'Total capital', + }, + propertiesAndDebts: { + id: 'fspp.application:keyNumbers.properties', + defaultMessage: 'Eignir, skuldir og eigið fé', + description: 'Statement property numbers', + }, + keyNumbersDebt: { + id: 'fspp.application:keyNumbers.debt', + defaultMessage: 'Lykiltölur - Eignir, Skuldir og eigið fé', + description: 'Statement debts', + }, + equityDebtsAssetsValidatorError: { + id: 'fspp.application:equityValidatorError', + defaultMessage: 'Skuldir og eigið fé þarf að vera jafnt og eignir samtals', + description: 'Equity + debts shout equal assets', + }, + properties: { + id: 'fspp.application:properties', + defaultMessage: 'Eignir', + description: 'List of applicants properties', + }, + fixedAssetsTotal: { + id: 'fspp.application:keyNumbers.fixedAssetsTotal', + defaultMessage: 'Fastafjármunir samtals', + description: 'Fixed assets', + }, + currentAssets: { + id: 'fspp.application:keyNumbers.currentAssets', + defaultMessage: 'Veltufjármunir samtals', + description: 'Current assets', + }, + longTerm: { + id: 'fspp.application:keyNumbers.longTermdebt', + defaultMessage: 'Langtímaskuldir samtals', + description: 'Long term debt', + }, + shortTerm: { + id: 'fspp.application:keyNumbers.shortTermDebt', + defaultMessage: 'Skammtímaskuldir samtals', + description: 'Short term debt', + }, + totalAssets: { + id: 'fspp.application:totalAssets', + defaultMessage: 'Eignir samtals', + description: 'Total assets', + }, + debtsAndEquity: { + id: 'fspp.application:keyNumbers.debtsAndEquity', + defaultMessage: 'Skuldir og eigið fé', + description: 'debts and equity', + }, + totalDebts: { + id: 'fspp.application:income.totalDebts', + defaultMessage: 'Skuldir samtals:', + description: 'Total debts', + }, + equity: { + id: 'fspp.application:keyNumbers.equity', + defaultMessage: 'Eigið fé', + description: 'total equity', + }, + debtsAndCash: { + id: 'fspp.application:keyNumbers.debtsAndCash', + defaultMessage: 'Skuldir og eigið fé samtals', + description: 'Debts and cash', + }, + equityErrorTitle: { + id: 'fspp.application:equityErrorTitle', + defaultMessage: 'Ósamræmi í tölum', + description: 'Error msg title when E = S+E.fé is incorrect', + }, + financialStatement: { + id: 'fspp.application:financial.statment', + defaultMessage: 'Ársreikningur', + description: 'financial statements', + }, + upload: { + id: 'fspp.application:upload', + defaultMessage: 'Hlaða upp ársreikningi', + description: 'Upload financial statements', + }, + uploadHeader: { + id: 'fspp.application:uploadHeader', + defaultMessage: 'Dragðu skjöl hingað til að hlaða upp', + description: 'Upload here', + }, + uploadIntro: { + id: 'fspp.application:upload.intro', + defaultMessage: 'Vinsamlegast hlaðið upp ársreikning hér að neðan.', + description: 'Upload financial statements intro', + }, + uploadDescription: { + id: 'fspp.application:upload.description', + defaultMessage: 'Vinsamlegast hlaðið upp ársreikning hér að neðan.', + description: 'Upload financial statements intro', + }, + uploadAccept: { + id: 'fspp.application:upload.accept', + defaultMessage: 'Eingöngu er tekið við skjölum á PDF formi', + description: 'Upload financial statements intro', + }, + uploadButtonLabel: { + id: 'fspp.application:upload.buttonlabel', + defaultMessage: 'Velja skjöl til að hlaða upp', + description: 'Upload button label', + }, + overviewSectionTitle: { + id: 'fspp.application:overview.general.sectionTitle', + defaultMessage: 'Yfirlit', + description: 'Overview section title', + }, + yearlyOverview: { + id: 'fspp.application:overview.general.yearly', + defaultMessage: 'Yfirlit ársreiknings', + description: 'Yearly overview', + }, + review: { + id: 'fspp.application:review', + defaultMessage: + 'Endilega lestu yfir til að vera viss um að allar upplýsingar hafi verið gefnar', + description: 'financial statements', + }, + submitErrorMessage: { + id: 'fspp.application:submitErrorMessage', + defaultMessage: + 'Eitthvað fór úrskeiðis við að senda inn ársreikning. Reyndu aftur síðar.', + description: + 'Text that shows up when an error occurs while submitting the application', + }, + submitErrorTitle: { + id: 'fspp.application:submitErrorTitle', + defaultMessage: 'Móttaka ársreiknings tókst ekki', + description: + 'Title that shows up when an error occurs while submitting the application', + }, + errorApproval: { + id: 'fspp.application:error.errorApproval', + defaultMessage: 'Samþykkja þarf yfirlit', + description: 'Approval missing', + }, + overviewCorrect: { + id: 'fspp.application:overview.overViewCorrect', + defaultMessage: 'Ég samþykki að ofangreindar upplýsingar séu réttar', + description: 'Overview correct', + }, + overview: { + id: 'fspp.application:overview.general.overview', + defaultMessage: 'Yfirferð', + description: 'Overview section title', + }, + otherCost: { + id: 'fspp.application:income.otherCost', + defaultMessage: 'Annar kostnaður', + description: 'Other costs', + }, + files: { + id: 'fspp.application:files', + defaultMessage: 'Skjöl', + description: 'files', + }, + totalLiabilities: { + id: 'fspp.application:keyNumbers.totalLiabilities', + defaultMessage: 'Skuldir samtals', + description: 'total liabilities', + }, + nationalId: { + id: 'fspp.application:nationalId', + defaultMessage: 'Kennitala', + description: 'National id', + }, + fullName: { + id: 'fspp.application:fullName', + defaultMessage: 'Fullt nafn', + description: 'Full name', + }, + goBack: { + id: 'fspp.application:overview.goBack', + defaultMessage: 'Til Baka', + description: 'Go back btn text', + }, + send: { + id: 'fspp.application:send', + defaultMessage: 'Senda umsókn', + description: 'Send application', + }, + travelCost: { + id: 'fspp.application:income.travelCost', + defaultMessage: 'Fundir ferðakostnaður', + description: 'Meeting and travel cost', + }, + advertisements: { + id: 'fspp.application:income.advertisements', + defaultMessage: 'Auglýsingar og kynningar', + description: 'Advertisements costs', + }, + candidatesOwnContributions: { + id: 'fspp.application:income.candidatesOwnContributions', + defaultMessage: 'Eigin framlög frambjóðenda', + description: 'Candiates own donation', + }, + participated: { + id: 'fspp.application:overview.participated', + defaultMessage: 'tók þátt í kjöri til', + description: 'Participated in election', + }, + electionDeclare: { + id: 'fspp.application:electionStatementDeclare', + defaultMessage: + 'Ég lýsi því hér með yfir að viðlögðum drengskap að hvorki heildartekjur né heildarkostnaður vegna framboðs míns í kjörinu voru hærri en kr.', + description: 'statement', + }, + electionStatementLaw: { + id: 'fspp.application:electionStatementLaw', + defaultMessage: + 'Það staðfestist hér með að heildartekjur eða -kostnaður vegna framboðsins voru ekki umfram þau fjárhæðarmörk sem tilgreind eru í 3. mgr. 10. gr. laga nr. 162/2006, um starfsemi stjórnmálasamtaka, og er framboðið því undanþegið uppgjörsskyldu.', + description: 'statement', + }, + signatureTitle: { + id: 'fspp.application:SignatureTitle', + defaultMessage: 'Rafræn undirritun', + description: 'Signature alert title', + }, + signatureMessage: { + id: 'fspp.application:SignatureMessage', + defaultMessage: + 'Eftir að þú hefur sent inn umsókn mun rafræn undirritun verða send á netfangið', + description: 'Signature message', + }, + signaturePossible: { + id: 'fspp.application:SignaturePossible', + defaultMessage: 'svo hægt sé að undirrita hana með rafrænum skilríkjum.', + description: 'Signature possible message', + }, + sendStatement: { + id: 'fspp.application:sendStatement', + defaultMessage: 'Senda yfirlýsingu', + description: 'Send statement', + }, + received: { + id: 'fspp.application:received', + defaultMessage: 'Ársreikningur mótekinn', + description: 'financial statement received', + }, + applicationAccept: { + id: 'fspp.application:applicationAccept', + defaultMessage: 'Umsókn móttekin', + description: 'application accept', + }, + operatingYearMsgFirst: { + id: 'fspp.application:operatingYearMsgFirst', + defaultMessage: 'Ársreikningi fyrir rekstrarárið', + description: 'First part of audit received message', + }, + auditReceivedMsgSecond: { + id: 'fspp.application:individualReceivedMsgSecond', + defaultMessage: 'hefur verið skilað þann', + description: 'Second part of audit received message', + }, + individualReceivedMsgSecond: { + id: 'fspp.application:individualReceivedMsgSecond', + defaultMessage: 'hefur verið skilað þann', + description: 'Second part of audit received message', + }, + returned: { + id: 'fspp.application:returned', + defaultMessage: 'Skilað', + description: 'Returned', + }, + myPagesLinkText: { + id: 'fspp.application:myPagesLinkText', + defaultMessage: + 'Á Mínum síðum Ísland.is hefur þú aðgang að marvíslegum upplýsingum s.s stafrænt pósthólf, þínar upplýsingar, fjármál, umsóknir, menntun, fasteignir, ökutæki, skírteini, starfsleyfi ofl. ', + description: 'island.is my pages info', + }, + continue: { + id: 'fspp.application:continue', + defaultMessage: 'Áfram', + description: 'continue', + }, + required: { + id: 'fspp.application:error.required', + defaultMessage: 'Reitur má ekki vera tómur', + description: 'Error message when a required field has not been filled', + }, + nationalIdError: { + id: 'fspp.application:error.nationalIdError', + defaultMessage: 'Kennitala er ekki á réttu formi', + description: 'Error message when nationalid is wrong', + }, + dataSchemePhoneNumber: { + id: 'fspp.application:dataSchema.phoneNumber', + defaultMessage: 'Símanúmerið þarf að vera gilt.', + description: 'Error message when phone number is invalid.', + }, + negativeNumberError: { + id: 'fspp.application:error.negativeNumberError', + defaultMessage: 'Ekki er leyfilegt að setja inn neikvæðar tölur', + description: 'Error message when a required field has not been filled', + }, +}) diff --git a/libs/application/templates/inao/financial-statement-political-party/src/types/types.ts b/libs/application/templates/inao/financial-statement-political-party/src/types/types.ts new file mode 100644 index 000000000000..d4e6d3e5aea0 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/types/types.ts @@ -0,0 +1,20 @@ +import { DefaultEvents } from '@island.is/application/types' + +export type Events = { type: DefaultEvents.SUBMIT } + +export enum States { + PREREQUISITES = 'prerequisites', + DRAFT = 'draft', + DONE = 'done', +} + +export enum Roles { + APPLICANT = 'applicant', +} + +export type Config = { key: string; value: string } + +export enum ApiActions { + getUserType = 'getUserType', + submitApplication = 'submitApplication', +} diff --git a/libs/application/templates/inao/financial-statement-political-party/src/utils/constants.ts b/libs/application/templates/inao/financial-statement-political-party/src/utils/constants.ts new file mode 100644 index 000000000000..0efc55f7997e --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/utils/constants.ts @@ -0,0 +1,67 @@ +export const PartiesYearAllowed = 'PartiesYearAllowed' +export const PartiesBackwardLimit = 'PartiesBackwardLimit' +export const INPUTCHANGEINTERVAL = 300 +export const TOTAL = 'total' +export const LESS = 'less' +export const GREATER = 'greater' +export const ELECTIONLIMIT = 550000 + +export const ABOUTIDS = { + operatingYear: 'conditionalAbout.operatingYear', + applicationType: 'conditionalAbout.applicationType', + selectElection: 'election.selectElection', + electionName: 'election.electionName', + genitiveName: 'election.genitiveName', + incomeLimit: 'election.incomeLimit', + powerOfAttorneyNationalId: 'about.powerOfAttorneyNationalId', + powerOfAttorneyName: 'about.powerOfAttorneyName', +} + +export const PARTYOPERATIONIDS = { + incomePrefix: 'partyIncome', + expensePrefix: 'partyExpense', + contributionsFromTheTreasury: 'partyIncome.contributionsFromTheTreasury', + parliamentaryPartySupport: 'partyIncome.parliamentaryPartySupport', + municipalContributions: 'partyIncome.municipalContributions', + contributionsFromLegalEntities: 'partyIncome.contributionsFromLegalEntities', + contributionsFromIndividuals: 'partyIncome.contributionsFromIndividuals', + generalMembershipFees: 'partyIncome.generalMembershipFees', + capitalIncome: 'partyIncome.capitalIncome', + otherIncome: 'partyIncome.otherIncome', + totalIncome: 'partyIncome.total', + electionOffice: 'partyExpense.electionOffice', + otherCost: 'partyExpense.otherCost', + capitalCost: 'partyExpense.capitalCost', + totalExpense: 'partyExpense.total', +} + +export const OPERATINGCOST = { + total: 'operatingCost.total', +} + +export const CAPITALNUMBERS = { + capitalPrefix: 'capitalNumbers', + capitalIncome: 'capitalNumbers.capitalIncome', + capitalCost: 'capitalNumbers.capitalCost', + total: 'capitalNumbers.total', +} + +export const EQUITIESANDLIABILITIESIDS = { + assetPrefix: 'asset', + currentAssets: 'asset.currentAssets', + fixedAssetsTotal: 'asset.fixedAssetsTotal', + assetTotal: 'asset.total', + liabilityPrefix: 'liability', + longTerm: 'liability.longTerm', + shortTerm: 'liability.shortTerm', + asset: 'liability.asset', + totalLiability: 'liability.total', + operationResult: 'equity.operationResult', + equityPrefix: 'equity', + totalEquity: 'equity.totalEquity', + totalCash: 'equity.total', + totalEquityAndLiabilities: 'equityAndLiabilities.total', +} + +// Error helpers +export const VALIDATOR = 'validator' diff --git a/libs/application/templates/inao/financial-statement-political-party/src/utils/helpers.ts b/libs/application/templates/inao/financial-statement-political-party/src/utils/helpers.ts new file mode 100644 index 000000000000..82ac09edeb37 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/src/utils/helpers.ts @@ -0,0 +1,44 @@ +import { Config } from '../types/types' +import subYears from 'date-fns/subYears' +import getYear from 'date-fns/getYear' +import { TOTAL } from './constants' + +export const getConfigInfoForKey = (config: Config[], configKey: string) => { + return config?.filter((config: Config) => config.key === configKey)[0].value +} + +export const possibleOperatingYears = ( + yearLimit: string, + countYearBackwardsFrom: string, +) => { + const countFromYear = new Date(countYearBackwardsFrom) + const backwardsYearLimit = Number(yearLimit) + const operationYears = Array(backwardsYearLimit) + .fill('') + .map((_, index) => { + const dateDiff = subYears(countFromYear, index) + const yearsFromNow = getYear(dateDiff).toString() + return { label: yearsFromNow, value: yearsFromNow } + }) + return operationYears +} + +export const getTotal = (values: Record, key: string) => { + if (!values[key]) { + return 0 + } + const total = Object.entries(values[key]) + .filter(([k, v]) => k !== TOTAL && !isNaN(Number(v))) + .map(([_k, v]) => Number(v)) + .reduce((prev, current) => { + return (prev += current) + }, 0) + return total +} + +export const formatCurrency = (answer: string) => + answer.replace(/\B(?=(\d{3})+(?!\d))/g, '.') + ' kr.' + +export const formatNumber = (num: number) => num.toLocaleString('de-DE') + +export const checkIfNegative = (inputNumber: string) => Number(inputNumber) >= 0 diff --git a/libs/application/templates/inao/financial-statement-political-party/tsconfig.json b/libs/application/templates/inao/financial-statement-political-party/tsconfig.json new file mode 100644 index 000000000000..04538292f729 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "allowJs": false, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "strict": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "extends": "../../../../../tsconfig.base.json" +} diff --git a/libs/application/templates/inao/financial-statement-political-party/tsconfig.lib.json b/libs/application/templates/inao/financial-statement-political-party/tsconfig.lib.json new file mode 100644 index 000000000000..d17804e8805a --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/tsconfig.lib.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../../../dist/out-tsc", + "types": ["node"] + }, + "files": [ + "../../../../../node_modules/@nx/react/typings/cssmodule.d.ts", + "../../../../../node_modules/@nx/react/typings/image.d.ts" + ], + "exclude": ["/**/*.spec.ts", "/**/*.spec.tsx"], + "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] +} diff --git a/libs/application/templates/inao/financial-statement-political-party/tsconfig.spec.json b/libs/application/templates/inao/financial-statement-political-party/tsconfig.spec.json new file mode 100644 index 000000000000..915013b6a6d4 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-political-party/tsconfig.spec.json @@ -0,0 +1,20 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts" + ] +} diff --git a/libs/application/types/src/lib/ApplicationTypes.ts b/libs/application/types/src/lib/ApplicationTypes.ts index 3b154b43b4d0..8ab99d72143a 100644 --- a/libs/application/types/src/lib/ApplicationTypes.ts +++ b/libs/application/types/src/lib/ApplicationTypes.ts @@ -33,6 +33,7 @@ export enum ApplicationTypes { FINANCIAL_STATEMENT_CEMETERY = 'FinancialStatementCemetery', FINANCIAL_STATEMENTS_INAO = 'FinancialStatementsInao', FINANCIAL_STATEMENT_INDIVIDUAL_ELECTION = 'FinancialStatementIndividualElection', + FINANCIAL_STATEMENT_POLITICAL_PARTY = 'FinancialStatementPoliticalParty', OPERATING_LICENSE = 'OperatingLicense', ESTATE = 'Estate', DRIVING_LICENSE_DUPLICATE = 'DrivingLicenseDuplicate', @@ -219,6 +220,10 @@ export const ApplicationConfigurations = { slug: 'skil-arsreikninga-einstaklingsframbod', translation: 'fsie.application', }, + [ApplicationTypes.FINANCIAL_STATEMENT_POLITICAL_PARTY]: { + slug: 'skil-arsreikninga-stjornmalaflokkar', + translation: 'fspp.application', + }, [ApplicationTypes.OPERATING_LICENSE]: { slug: 'rekstrarleyfi', translation: 'ol.application', diff --git a/libs/application/types/src/lib/InstitutionMapper.ts b/libs/application/types/src/lib/InstitutionMapper.ts index 1c062d970143..5038a0c05db1 100644 --- a/libs/application/types/src/lib/InstitutionMapper.ts +++ b/libs/application/types/src/lib/InstitutionMapper.ts @@ -169,6 +169,11 @@ export const institutionMapper = { slug: InstitutionTypes.RIKISENDURSKODUN, contentfulId: InstitutionContentfulIds.RIKISENDURSKODUN, }, + [ApplicationTypes.FINANCIAL_STATEMENT_POLITICAL_PARTY]: { + nationalId: InstitutionNationalIds.RIKISENDURSKODUN, + slug: InstitutionTypes.RIKISENDURSKODUN, + contentfulId: InstitutionContentfulIds.RIKISENDURSKODUN, + }, [ApplicationTypes.ANNOUNCEMENT_OF_DEATH]: { nationalId: InstitutionNationalIds.SYSLUMENN, slug: InstitutionTypes.SYSLUMENN, diff --git a/libs/feature-flags/src/lib/features.ts b/libs/feature-flags/src/lib/features.ts index c3b1d9d48cb2..2ad15a30d9fd 100644 --- a/libs/feature-flags/src/lib/features.ts +++ b/libs/feature-flags/src/lib/features.ts @@ -38,6 +38,7 @@ export enum Features { FinancialStatementCemetery = 'isFinancialStatementCemeteryEnabled', ParliamentaryElectionApplication = 'isParliamentaryElectionApplicationEnabled', FinancialStatementIndividualElectionEnabled = 'isFinancialStatementIndividualElectionEnabled', + FinancialStatementPoliticalPartyEnabled = 'isFinancialStatementPoliticalPartyEnabled', IncomePlanEnabled = 'isIncomePlanEnabled', // Application System Delegations active diff --git a/tsconfig.base.json b/tsconfig.base.json index 8b5da3e7139f..79b510cb730e 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -387,6 +387,9 @@ "@island.is/application/templates/financial-statement-individual-election/types": [ "libs/application/templates/inao/financial-statement-individual-election/src/types/types.ts" ], + "@island.is/application/templates/financial-statement-political-party": [ + "libs/application/templates/inao/financial-statement-political-party/src/index.ts" + ], "@island.is/application/templates/financial-statements-inao": [ "libs/application/templates/financial-statements-inao/src/index.ts" ], @@ -1122,6 +1125,9 @@ "api/domains/financial-statement-cemetery": [ "libs/api/domains/financial-statement-cemetery/src/index.ts" ], + "application/templates/inao/financial-statement-political-party": [ + "libs/application/templates/inao/financial-statement-political-party/src/index.ts" + ], "delegation-admin": ["libs/portals/admin/delegation-admin/src/index.ts"] } }