-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(financial-statement-political-party): political party as a new a…
…pplication (#16076) * feat: political party as a new application * fix: add tags * fix: failed test and coderabbit * fix: more coderabbit suggestions * fix: remove old dev condition * fix: just change my dataschema * fix: add missing line to zod * fix: more codeRabbit comments * fix: pr comments * chore: module instead of dynamic module --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
- Loading branch information
1 parent
3e13aff
commit 83b076f
Showing
70 changed files
with
3,706 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
...plates/financial-statement-political-party/financial-statement-political-party.modules.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 {} |
209 changes: 209 additions & 0 deletions
209
...plates/financial-statement-political-party/financial-statement-political-party.service.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<string> { | ||
const attachments = getValueViaPath( | ||
application.answers, | ||
'attachments.files', | ||
) as Array<AttachmentData> | ||
|
||
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<Contact> { | ||
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, | ||
} | ||
} | ||
} |
49 changes: 49 additions & 0 deletions
49
...ib/modules/templates/financial-statement-political-party/mappers/mapValuesToPartyTypes.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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')), | ||
} | ||
} |
4 changes: 4 additions & 0 deletions
4
...-api-modules/src/lib/modules/templates/financial-statement-political-party/types/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export type KeyValue = { | ||
key: number | ||
value: number | ||
} |
Oops, something went wrong.