Skip to content

Commit

Permalink
feat(income-plan): new income plan "application" (#15807)
Browse files Browse the repository at this point in the history
* set up payment plan template

* change application name to income plan

* add instructions page

* implement conclusion screen

* Change some texts after review

* feat(tr): income plan table (#15340)

* fix:add scopes

* fix: use type

* chore: add to codeowners

* fix: codewners

* WIP table

* feat: update client

* fix: handle 404

* fix: write applciation

* Seeder file for adding scopes to @island.is/clients/api

* chore: nx format:write update dirty files

* use application and active field for options in table repeater, populate categories and types in income plan with info from TR, add readonly for fields in table repeater

* get currencies from TR and populate dropdown, format input fields that display something regarding income, call withholding tax api from TR and implement some rules when adding income to the income plan

* WIP call withholdind income plan api from TR

* validation when adding income, wip tooltip on fields in table repeater, format number showed in income table

* mock withholding tax and populate table, add readonly to table fields, change tooltip for checkbox and format

* add review screen

---------

Co-authored-by: Þorkell Máni Þorkelsson <mani@hugsmidjan.is>
Co-authored-by: Þorkell Máni Þorkelsson <wowthorkell@gmail.com>
Co-authored-by: ori.jonab <Jon.Arnar.Briem@origo.is>
Co-authored-by: andes-it <builders@andes.is>

* remove fake form steppers and call latest income plan

* foreign income + populate table with latest income plan

* format

* add history logs and corresponding messages

* feat(income-plan): text changes (#15636)

* text changes

* format

* eligible and update after withholding tax and latest income plan outputs was changed

* [TS-839] Calculate income per year (#15682)

* update read me and add flow chart (#15669)

* feat(income-plan): make more application card texts editable  (#15754)

* text changes

* format

* make open application button texts editable

* format

* chore: nx format:write update dirty files

---------

Co-authored-by: andes-it <builders@andes.is>

* [TS-848] Jafnar tekjur á mánuði (#15733)

* [TS-849] uneven income (#15701)

* feat(income-plan): send income plan (#15777)

* WIP send income plan to TR

* send income plan

* remove

* update eligible

* default IKR

* ts-853 change bottom button link

* clean up

* feat(income-plan): Add unit tests (#15778)

* add unit tests for state transitions

* add unit tests for utils

* format

* chore: nx format:write update dirty files

---------

Co-authored-by: andes-it <builders@andes.is>

* [TS-847] start application at the first page when table has been filled (#15793)

* add review and complete state to income plan + feature flag

* validation was triggered

* remove mock data

* clean

* feat(income-plan): Temporary calculation table (#15642)

* set up temporary calculation page and data

* add print screen custom component and messages

* fix input and add to temporary calculation screen

* [TS-823] temporary calculation plan page

* Add validation to incomePlanTable - nonempty

* Fixed query input

* Added AlertMessage when no payments

* Update temporary calculation query input

* chore: nx format:write update dirty files

---------

Co-authored-by: ylfahfa <yhafsteinsdottir@deloitte.is>
Co-authored-by: karenbjorg <khalldorsdottir@deloitte.is>
Co-authored-by: andes-it <builders@andes.is>

* [TS-889] fix validation for currency (#15803)

* if selected employment income and register uneven income, changing to other type of income then months still showed

* foreign income per year where not validated

* chore: nx format:write update dirty files

* Update libs/application/templates/social-insurance-administration/income-plan/README.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update libs/application/templates/social-insurance-administration/income-plan/README.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update libs/application/templates/social-insurance-administration/income-plan/README.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update libs/application/templates/social-insurance-administration/income-plan/README.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Fixed typo in dataProviders externalDataId

* Memoize the rows array to improve performance

* Improve useEffect dependency array for better performance.

* Update libs/application/templates/social-insurance-administration/income-plan/README.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update libs/application/templates/social-insurance-administration/income-plan/README.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update libs/application/templates/social-insurance-administration/income-plan/README.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update libs/application/templates/social-insurance-administration/income-plan/README.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update libs/application/templates/social-insurance-administration/income-plan/README.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update libs/application/templates/social-insurance-administration/income-plan/README.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update libs/application/templates/social-insurance-administration/income-plan/README.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* use Int instead of Number for number decorator

* remove commented out code and nullable (#15812)

* feat(income-plan): income plan conditions (#15820)

* call income plan conditions api

* Add incomePlanConditions to getApplicationExternalData

* Add AlertMessage when no available prerequisites for temporary calculation

* change income year

* Update dataSchema

* Update sendApplication and temporary calculation query input

* Update unsetIncomePlan template action and added unit test

---------

Co-authored-by: karenbjorg <khalldorsdottir@deloitte.is>

* fix(table-repeater): move Item component and remove FC (#15830)

* move Item component and remove FC

* remove

* move Item component

* add variables to useEffect dependency array

* add contentful id for income plan

---------

Co-authored-by: ylfahfa <yhafsteinsdottir@deloitte.is>
Co-authored-by: Þorkell Máni Þorkelsson <mani@hugsmidjan.is>
Co-authored-by: Þorkell Máni Þorkelsson <wowthorkell@gmail.com>
Co-authored-by: ori.jonab <Jon.Arnar.Briem@origo.is>
Co-authored-by: andes-it <builders@andes.is>
Co-authored-by: Ylfa <55542991+ylfahfa@users.noreply.github.com>
Co-authored-by: veronikasif <54938148+veronikasif@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Veronika Sif <veronikasif@hotmail.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
11 people authored Sep 2, 2024
1 parent 34e8bfd commit ed805ae
Show file tree
Hide file tree
Showing 55 changed files with 4,437 additions and 302 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { InputType, Field, Int } from '@nestjs/graphql'

@InputType('SocialInsuranceIncomeType')
class IncomeType {
@Field(() => Int, { nullable: true })
incomeTypeNumber?: number

@Field(() => String, { nullable: true })
incomeTypeCode?: string

@Field(() => String, { nullable: true })
incomeTypeName?: string

@Field(() => String, { nullable: true })
currencyCode?: string

@Field(() => Int, { nullable: true })
incomeCategoryNumber?: number

@Field(() => String, { nullable: true })
incomeCategoryCode?: string

@Field(() => String, { nullable: true })
incomeCategoryName?: string

@Field(() => Int, { nullable: true })
amountJan?: number

@Field(() => Int, { nullable: true })
amountFeb?: number

@Field(() => Int, { nullable: true })
amountMar?: number

@Field(() => Int, { nullable: true })
amountApr?: number

@Field(() => Int, { nullable: true })
amountMay?: number

@Field(() => Int, { nullable: true })
amountJun?: number

@Field(() => Int, { nullable: true })
amountJul?: number

@Field(() => Int, { nullable: true })
amountAug?: number

@Field(() => Int, { nullable: true })
amountSep?: number

@Field(() => Int, { nullable: true })
amountOct?: number

@Field(() => Int, { nullable: true })
amountNov?: number

@Field(() => Int, { nullable: true })
amountDec?: number
}

@InputType('SocialInsuranceTemporaryCalculationInput')
export class TemporaryCalculationInput {
@Field(() => Int)
incomeYear!: number

@Field(() => [IncomeType], { nullable: true })
incomeTypes?: Array<IncomeType>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Field, Int, ObjectType } from '@nestjs/graphql'

@ObjectType('SocialInsuranceTemporaryCalculationRow')
class TemporaryCalculationRow {
@Field(() => String, { nullable: true })
name?: string

@Field(() => Int, { nullable: true })
total?: number

@Field(() => [TemporaryCalculationMonth], { nullable: true })
months?: Array<TemporaryCalculationMonth>
}

@ObjectType('SocialInsuranceTemporaryCalculationMonth')
class TemporaryCalculationMonth {
@Field(() => Int)
month!: number

@Field(() => Int, { nullable: true })
amount?: number
}

@ObjectType('SocialInsuranceTemporaryCalculationGroup')
class TemporaryCalculationGroup {
@Field(() => String, { nullable: true })
group?: string

@Field(() => Int, { nullable: true })
groupId?: number

@Field(() => Int, { nullable: true })
total?: number

@Field(() => [TemporaryCalculationMonth], { nullable: true })
monthTotals?: Array<TemporaryCalculationMonth>

@Field(() => [TemporaryCalculationRow], { nullable: true })
rows?: Array<TemporaryCalculationRow>
}

@ObjectType('SocialInsuranceTemporaryCalculation')
export class TemporaryCalculation {
@Field(() => Int, { nullable: true })
totalPayment?: number

@Field(() => Int, { nullable: true })
subtracted?: number

@Field(() => Int, { nullable: true })
paidOut?: number

@Field(() => [TemporaryCalculationGroup], { nullable: true })
groups?: Array<TemporaryCalculationGroup>
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Audit } from '@island.is/nest/audit'
import { ApiScope } from '@island.is/auth/scopes'
import { Query, Resolver } from '@nestjs/graphql'
import { Args, Query, Resolver } from '@nestjs/graphql'
import {
IdsUserGuard,
ScopesGuard,
Expand All @@ -17,6 +17,8 @@ import {
Features,
} from '@island.is/nest/feature-flags'
import { Payments } from '../models/payments/payments.model'
import { TemporaryCalculation } from '../models/temporaryCalculation.model'
import { TemporaryCalculationInput } from '../dtos/temporaryCalculation.input'

@Resolver()
@UseGuards(IdsUserGuard, ScopesGuard, FeatureFlagGuard)
Expand Down Expand Up @@ -45,4 +47,12 @@ export class PaymentPlanResolver {
async(@CurrentUser() user: User): Promise<Payments | undefined> {
return this.service.getPayments(user)
}

@Query(() => TemporaryCalculation)
async getTemporaryCalculations(
@Args('input') input: TemporaryCalculationInput,
@CurrentUser() user: User,
) {
return this.service.getTemporaryCalculations(user, input)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { User } from '@island.is/auth-nest-tools'
import { handle404 } from '@island.is/clients/middlewares'
import {
SocialInsuranceAdministrationClientService,
TrWebCommonsExternalPortalsApiModelsPaymentPlanPaymentPlanDto,
IncomePlanStatus as IncomeStatus,
} from '@island.is/clients/social-insurance-administration'
import {
Expand All @@ -26,6 +27,7 @@ import { mapToPaymentGroupType } from './models/payments/paymentGroupType.model'
import { IncomePlan } from './models/income/incomePlan.model'
import { IncomePlanStatus, LOG_CATEGORY } from './socialInsurance.type'
import { IncomePlanEligbility } from './models/income/incomePlanEligibility.model'
import { TemporaryCalculationInput } from './dtos/temporaryCalculation.input'

@Injectable()
export class SocialInsuranceService {
Expand Down Expand Up @@ -204,6 +206,13 @@ export class SocialInsuranceService {
}
}

async getTemporaryCalculations(
user: User,
input: TemporaryCalculationInput,
): Promise<TrWebCommonsExternalPortalsApiModelsPaymentPlanPaymentPlanDto> {
return await this.socialInsuranceApi.getTemporaryCalculations(user, input)
}

parseIncomePlanStatus = (status: IncomeStatus): IncomePlanStatus => {
switch (status) {
case 'Accepted':
Expand Down
3 changes: 2 additions & 1 deletion libs/application/core/src/lib/fieldBuilders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,11 @@ export function buildDescriptionField(
space,
marginBottom,
marginTop,
doesNotRequireAnswer = true,
} = data
return {
...extractCommonFields(data),
doesNotRequireAnswer: true,
doesNotRequireAnswer,
children: undefined,
description,
titleVariant,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
ApplicationDTO,
TrWebCommonsExternalPortalsApiModelsDocumentsDocument as Attachment,
Employer as TrWebEmployer,
IncomeTypes,
} from '@island.is/clients/social-insurance-administration'
import {
ApplicationType,
Expand Down Expand Up @@ -34,6 +35,12 @@ import {
getApplicationExternalData as getPSApplicationExternalData,
} from '@island.is/application/templates/social-insurance-administration/pension-supplement'

import {
INCOME,
getApplicationAnswers as getIPApplicationAnswers,
getApplicationExternalData as getIPApplicationExternalData,
} from '@island.is/application/templates/social-insurance-administration/income-plan'

export const transformApplicationToOldAgePensionDTO = (
application: Application,
uploads: Attachment[],
Expand Down Expand Up @@ -298,6 +305,87 @@ export const transformApplicationToPensionSupplementDTO = (
return pensionSupplementDTO
}

export const transformApplicationToIncomePlanDTO = (
application: Application,
): ApplicationDTO => {
const { userProfileEmail, userProfilePhoneNumber, incomePlanConditions } =
getIPApplicationExternalData(application.externalData)

const incomePlanDTO: ApplicationDTO = {
applicantInfo: {
email: userProfileEmail,
phonenumber: userProfilePhoneNumber,
},
period: {
year: new Date().getFullYear(),
month: new Date().getMonth(),
},
applicationId: application.id,
incomePlan: {
incomeYear: incomePlanConditions.incomePlanYear,
incomeTypes: getIncomeTypes(application),
},
}

return incomePlanDTO
}

export const getIncomeTypes = (application: Application): IncomeTypes[] => {
const { incomePlan } = getIPApplicationAnswers(application.answers)
const { categorizedIncomeTypes } = getIPApplicationExternalData(
application.externalData,
)

return incomePlan.map((i) => ({
incomeTypeNumber:
categorizedIncomeTypes.find((c) => c.incomeTypeName === i.incomeType)
?.incomeTypeNumber ?? 0,
incomeTypeCode:
categorizedIncomeTypes.find((c) => c.incomeTypeName === i.incomeType)
?.incomeTypeCode ?? '',
incomeTypeName: i.incomeType,
currencyCode: i.currency,
incomeCategoryNumber:
categorizedIncomeTypes.find((c) => c.incomeTypeName === i.incomeType)
?.categoryNumber ?? 0,
incomeCategoryCode:
categorizedIncomeTypes.find((c) => c.incomeTypeName === i.incomeType)
?.categoryCode ?? '',
incomeCategoryName: i.incomeCategory,
...(i.income === RatioType.MONTHLY &&
i?.incomeCategory === INCOME &&
i?.unevenIncomePerYear?.[0] === YES
? {
amountJan: Number(i.january),
amountFeb: Number(i.february),
amountMar: Number(i.march),
amountApr: Number(i.april),
amountMay: Number(i.may),
amountJun: Number(i.june),
amountJul: Number(i.july),
amountAug: Number(i.august),
amountSep: Number(i.september),
amountOct: Number(i.october),
amountNov: Number(i.november),
amountDec: Number(i.december),
}
: {
amountJan: Number(i.incomePerYear) / 12,
amountFeb: Number(i.incomePerYear) / 12,
amountMar: Number(i.incomePerYear) / 12,
amountApr: Number(i.incomePerYear) / 12,
amountMay: Number(i.incomePerYear) / 12,
amountJun: Number(i.incomePerYear) / 12,
amountJul: Number(i.incomePerYear) / 12,
amountAug: Number(i.incomePerYear) / 12,
amountSep: Number(i.incomePerYear) / 12,
amountOct: Number(i.incomePerYear) / 12,
amountNov: Number(i.incomePerYear) / 12,
amountDec: Number(i.incomePerYear) / 12,
}),
}))
}

export const getMonthNumber = (monthName: string): number => {
// Parse the month name and get the month number (0-based)
const monthNumber = parse(monthName, 'MMMM', new Date())
Expand Down
Loading

0 comments on commit ed805ae

Please sign in to comment.