Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ads-my-pages): ADS explicit and vaccine - hotfix #17206

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import { UserService } from '../user/user.service'
import type { User as AuthUser } from '@island.is/auth-nest-tools'
import { ExplicitFlight } from './dto/ExplicitFlight.dto'
import { CreateSuperExplicitDiscountCodeParams } from './dto'
import type { Logger } from '@island.is/logging'
import { LOGGER_PROVIDER } from '@island.is/logging'

interface CachedDiscount {
user: User
Expand Down Expand Up @@ -47,6 +49,8 @@ export class DiscountService {

@InjectModel(ExplicitCode)
private explicitModel: typeof ExplicitCode,
@Inject(LOGGER_PROVIDER)
private readonly logger: Logger,

private readonly userService: UserService,
) {}
Expand Down Expand Up @@ -197,13 +201,19 @@ export class DiscountService {
unConnectedFlights: Flight[] | ExplicitFlight[],
isExplicit: boolean,
flightLegs = 1,
isManual?: boolean,
): Promise<Array<Discount> | null> {
const user = await this.userService.getUserInfoByNationalId(
nationalId,
auth,
isExplicit,
isManual,
)

if (!user) {
this.logger.warn('User by national id not found for explicit discount.', {
category: 'ads-backend',
})
return null
}
// overwrite credit since validation may return 0 depending on what the problem is
Expand All @@ -212,10 +222,19 @@ export class DiscountService {
user.fund.credit = 2 //making sure we can get flight from and to
user.fund.total = 2
} else {
this.logger.warn(
`User fund used requirements not met: ${user.fund.used}.`,
{
category: 'ads-backend',
},
)
return null
}
}
if (user.fund.credit === 0 && user.fund.total !== undefined) {
this.logger.warn(`User fund no credit, has total: ${user.fund.total}.`, {
category: 'ads-backend',
})
return null
}

Expand Down Expand Up @@ -477,6 +496,7 @@ export class DiscountService {
],
}

const isManual = true
const discount = await this.createExplicitDiscountCode(
auth,
body.nationalId,
Expand All @@ -487,6 +507,7 @@ export class DiscountService {
body.needsConnectionFlight ? [flight] : [],
isExplicit,
1,
isManual,
)
if (!discount) {
throw new Error(`Could not create explicit discount`)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ describe('DiscountService', () => {
{
provide: LOGGER_PROVIDER,
useClass: jest.fn(() => ({
error: () => ({}),
error: jest.fn(),
info: jest.fn(),
warn: jest.fn(),
})),
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ const ONE_WEEK = 604800 // seconds
const CACHE_KEY = 'userService'
const MAX_AGE_LIMIT = 18

const DEFAULT_FUND: Fund = {
credit: 2,
total: 2,
used: 0,
}

interface CustodianCache {
custodians: Array<NationalRegistryUser | null>
}
Expand All @@ -42,14 +48,15 @@ export class UserService {
private async getFund(
user: NationalRegistryUser,
auth?: AuthUser,
isManual?: boolean,
): Promise<Fund> {
const { used, unused, total } =
await this.flightService.countThisYearsFlightLegsByNationalId(
user.nationalId,
)
let meetsADSRequirements = false

if (this.flightService.isADSPostalCode(user.postalcode)) {
if (this.flightService.isADSPostalCode(user.postalcode) || isManual) {
meetsADSRequirements = true
} else if (info(user.nationalId).age < MAX_AGE_LIMIT) {
// NationalId is a minor and doesn't live in ADS postal codes.
Expand Down Expand Up @@ -95,20 +102,33 @@ export class UserService {
nationalId: string,
model: new (user: NationalRegistryUser, fund: Fund) => T,
auth: AuthUser,
isExplicit?: boolean,
isManual?: boolean,
): Promise<T | null> {
const user = await this.nationalRegistryService.getUser(nationalId, auth)
if (!user) {
return null
}
const fund = await this.getFund(user, auth)
if (isExplicit) {
return new model(user, DEFAULT_FUND)
}
const fund = await this.getFund(user, auth, isManual)
return new model(user, fund)
}

async getUserInfoByNationalId(
nationalId: string,
auth: AuthUser,
isExplicit?: boolean,
isManual?: boolean,
): Promise<User | null> {
return this.getUserByNationalId<User>(nationalId, User, auth)
return this.getUserByNationalId<User>(
nationalId,
User,
auth,
isExplicit,
isManual,
)
}

async getMultipleUsersByNationalIdArray(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,7 @@
"schema": { "type": "string" }
},
{
"name": "age",
"name": "agePatient",
"required": true,
"in": "query",
"schema": { "type": "number" }
Expand All @@ -613,6 +613,12 @@
"required": true,
"in": "query",
"schema": { "type": "array", "items": { "type": "string" } }
},
{
"name": "vaccineCodes",
"required": true,
"in": "query",
"schema": { "type": "array", "items": { "type": "string" } }
}
],
"responses": {
Expand Down Expand Up @@ -820,6 +826,7 @@
"diseaseId": { "type": "string" },
"order": { "type": "number" },
"type": { "type": "object" },
"vaccineCodes": { "type": "string" },
"cond1Type": { "type": "string" },
"cond1Min": { "type": "number" },
"cond1Max": { "type": "number" },
Expand Down Expand Up @@ -859,6 +866,7 @@
"description": { "type": "string" },
"isFeatured": { "type": "boolean" },
"isVisible": { "type": "boolean" },
"hideIfNoVaccinations": { "type": "boolean" },
"vaccines": {
"type": "array",
"items": { "$ref": "#/components/schemas/VaccineDiseaseDto" }
Expand All @@ -877,6 +885,7 @@
"name",
"isFeatured",
"isVisible",
"hideIfNoVaccinations",
"vaccines",
"rules",
"translations"
Expand All @@ -890,6 +899,7 @@
"description": { "type": "string" },
"isFeatured": { "type": "boolean" },
"isVisible": { "type": "boolean" },
"hideIfNoVaccinations": { "type": "boolean" },
"vaccines": {
"type": "array",
"items": { "$ref": "#/components/schemas/VaccineDiseaseDto" }
Expand All @@ -909,6 +919,7 @@
"properties": {
"order": { "type": "number" },
"type": { "type": "object" },
"vaccineCodes": { "type": "string" },
"cond1Type": { "type": "string" },
"cond1Min": { "type": "number" },
"cond1Max": { "type": "number" },
Expand Down Expand Up @@ -938,6 +949,7 @@
"diseaseId": { "type": "string" },
"order": { "type": "number" },
"type": { "type": "object" },
"vaccineCodes": { "type": "string" },
"cond1Type": { "type": "string" },
"cond1Min": { "type": "number" },
"cond1Max": { "type": "number" },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React, { useMemo, useState } from 'react'
import {
Text,
Table as T,
Icon,
TagVariant,
Table as T,
Tag,
TagVariant,
Text,
} from '@island.is/island-ui/core'
import * as styles from './SortableTable.css'
import React, { useMemo, useState } from 'react'
import { ExpandHeader, ExpandRow } from '../ExpandableTable'
import * as styles from './SortableTable.css'

type ConfigType = { direction: 'ascending' | 'descending'; key: string }

Expand Down Expand Up @@ -166,7 +166,7 @@ export const SortableTable = (props: SortableTableProps) => {
data={valueItems.map((valueItem, i) => ({
value:
valueItems.length - 1 === i && tag ? (
<Tag variant={tag} outlined={props.tagOutlined}>
<Tag variant={tag} outlined={props.tagOutlined} disabled>
{valueItem}
</Tag>
) : (
Expand All @@ -187,7 +187,11 @@ export const SortableTable = (props: SortableTableProps) => {
return (
<T.Data key={`body-${id}-${i}`}>
{lastItem && tag ? (
<Tag variant={tag} outlined={props.tagOutlined}>
<Tag
variant={tag}
outlined={props.tagOutlined}
disabled
>
{valueItem}
</Tag>
) : (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
import { useUserInfo } from '@island.is/react-spa/bff'
import {
AlertMessage,
Box,
Text,
Button,
GridColumn,
GridRow,
Icon,
SkeletonLoader,
Stack,
Text,
toast,
Icon,
} from '@island.is/island-ui/core'
import { useLocale, useNamespaces } from '@island.is/localization'
import { Problem } from '@island.is/react-spa/shared'
import {
IntroHeader,
IntroWrapper,
SJUKRATRYGGINGAR_SLUG,
StackWithBottomDivider,
UserInfoLine,
Expand All @@ -24,6 +22,8 @@ import {
isDateAfterToday,
m,
} from '@island.is/portals/my-pages/core'
import { useUserInfo } from '@island.is/react-spa/bff'
import { Problem } from '@island.is/react-spa/shared'
import { useEffect, useState } from 'react'
import { messages } from '../../lib/messages'
import { HealthPaths } from '../../lib/paths'
Expand Down Expand Up @@ -85,15 +85,13 @@ export const HealthOverview = () => {
)

return (
<Box>
<Box marginBottom={CONTENT_GAP_LG}>
<IntroHeader
title={formatMessage(user.profile.name)}
intro={formatMessage(messages.overviewIntro)}
serviceProviderSlug={SJUKRATRYGGINGAR_SLUG}
serviceProviderTooltip={formatMessage(messages.healthTooltip)}
/>
</Box>
<IntroWrapper
marginBottom={CONTENT_GAP_LG}
title={formatMessage(user.profile.name)}
intro={formatMessage(messages.overviewIntro)}
serviceProviderSlug={SJUKRATRYGGINGAR_SLUG}
serviceProviderTooltip={formatMessage(messages.healthTooltip)}
>
{error ? (
<Problem error={error} noBorder={false} />
) : loading ? (
Expand Down Expand Up @@ -209,7 +207,7 @@ export const HealthOverview = () => {
)}
</Stack>
)}
</Box>
</IntroWrapper>
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { useLocale, useNamespaces } from '@island.is/localization'
import { Box, SkeletonLoader, Tabs } from '@island.is/island-ui/core'
import { useLocale, useNamespaces } from '@island.is/localization'
import {
EmptyTable,
HEALTH_DIRECTORATE_SLUG,
IntroHeader,
IntroWrapper,
LinkButton,
EmptyTable,
} from '@island.is/portals/my-pages/core'
import { Problem } from '@island.is/react-spa/shared'
import { isDefined } from '@island.is/shared/utils'
import { messages as m } from '../../lib/messages'
import { SECTION_GAP } from '../../utils/constants'
import { useGetVaccinationsQuery } from './Vaccinations.generated'
import { SortedVaccinationsTable } from './tables/SortedVaccinationsTable'
import { isDefined } from '@island.is/shared/utils'
import { Problem } from '@island.is/react-spa/shared'

export const VaccinationsWrapper = () => {
useNamespaces('sp.health')
Expand Down Expand Up @@ -39,13 +39,12 @@ export const VaccinationsWrapper = () => {
].filter(isDefined)

return (
<Box>
<IntroHeader
title={formatMessage(m.vaccinations)}
intro={formatMessage(m.vaccinationsIntro)}
serviceProviderSlug={HEALTH_DIRECTORATE_SLUG}
serviceProviderTooltip={formatMessage(m.landlaeknirVaccinationsTooltip)}
/>
<IntroWrapper
title={formatMessage(m.vaccinations)}
intro={formatMessage(m.vaccinationsIntro)}
serviceProviderSlug={HEALTH_DIRECTORATE_SLUG}
serviceProviderTooltip={formatMessage(m.landlaeknirVaccinationsTooltip)}
>
{/* Buttons */}
<Box printHidden display="flex" flexDirection="row" marginBottom={6}>
<LinkButton
Expand Down Expand Up @@ -91,7 +90,7 @@ export const VaccinationsWrapper = () => {
/>
</Box>
)}
</Box>
</IntroWrapper>
)
}
export default VaccinationsWrapper
Loading
Loading