Skip to content

Commit

Permalink
fix: add practitioner role entry in download bundle (#8338)
Browse files Browse the repository at this point in the history
* fix: add practitioner role entry in download bundle

* fix: update search result declaration's assignment status

* fix: refactor creation of practitioner role entry

* fix: amend assignment property of download button component

* fix: amend assignment logic for record audit
  • Loading branch information
Nil20 authored Jan 16, 2025
1 parent 888cf50 commit f4eebcb
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 45 deletions.
11 changes: 10 additions & 1 deletion packages/client/src/components/interface/DownloadButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import ReactTooltip from 'react-tooltip'
import { useModal } from '@client/hooks/useModal'
import { usePermissions } from '@client/hooks/useAuthorization'
import styled from 'styled-components'
import { useDeclaration } from '@client/declarations/selectors'

interface IDownloadConfig {
event: string
Expand Down Expand Up @@ -131,7 +132,12 @@ export function DownloadButton({
status,
className,
declarationStatus,
downloadConfigs: { assignment, event, compositionId, action }
downloadConfigs: {
assignment: declarationAssignment,
event,
compositionId,
action
}
}: DownloadButtonProps) {
const intl = useIntl()
const client = useApolloClient()
Expand All @@ -146,6 +152,9 @@ export function DownloadButton({
const [modal, openModal] = useModal()
const { isRecordActionable } = usePermissions()

const declaration = useDeclaration(compositionId)
const assignment = declarationAssignment ?? declaration?.assignmentStatus

const assignedToSomeoneElse =
assignment && assignment.practitionerId !== practitionerId
const assignedToMe = assignment?.practitionerId === practitionerId
Expand Down
3 changes: 2 additions & 1 deletion packages/client/src/views/RecordAudit/RecordAudit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -541,10 +541,11 @@ const BodyContent = ({
...declaration,
status: data.fetchRegistration?.registration?.status[0]
.type as SUBMISSION_STATUS,
assignment: data.fetchRegistration?.registration?.assignment
assignment: draft?.assignmentStatus
}
} else {
declaration = getGQLDeclaration(data.fetchRegistration, language)
declaration.assignment = draft?.assignmentStatus
}

return (
Expand Down
28 changes: 25 additions & 3 deletions packages/workflow/src/records/fhir.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,13 @@ import {
getResourceFromBundleById,
TransactionResponse,
TaskIdentifierSystem,
Location
Location,
PractitionerRole,
URLReference
} from '@opencrvs/commons/types'
import { FHIR_URL } from '@workflow/constants'
import fetch from 'node-fetch'
import { getUUID, UUID } from '@opencrvs/commons'
import { getTokenPayload, getUUID, UUID } from '@opencrvs/commons'
import { MAKE_CORRECTION_EXTENSION_URL } from '@workflow/features/task/fhir/constants'
import {
ApproveRequestInput,
Expand All @@ -69,7 +71,9 @@ import { badRequest, internal } from '@hapi/boom'
import { getUserOrSystem, isSystem } from './user'
import {
getLoggedInPractitionerResource,
getPractitionerOfficeId
getPractitionerOfficeId,
getPractitionerRoleByPractitionerId,
getUser
} from '@workflow/features/user/utils'
import { z } from 'zod'
import { fetchLocationHierarchy } from '@workflow/utils/location'
Expand Down Expand Up @@ -1162,6 +1166,24 @@ export async function sendBundleToHearth(
return responseBundle
}

export async function getPractitionerRoleFromToken(
token: string
): Promise<BundleEntry<PractitionerRole>> {
const tokenPayload = getTokenPayload(token)
const userDetails = await getUser(tokenPayload.sub, { Authorization: token })
const practitionerId = userDetails.practitionerId
const practitionerRoleBundle = (await getPractitionerRoleByPractitionerId(
practitionerId as UUID
)) as Bundle<PractitionerRole>

const practitionerRoleResource = practitionerRoleBundle.entry[0].resource
return {
fullUrl:
`/fhir/PractitionerRole/${practitionerRoleResource.id}/_history/${practitionerRoleResource.meta?.versionId}` as URLReference,
resource: practitionerRoleResource
}
}

function findSavedReference(
temporaryReference: URNReference,
resourceBundle: Bundle,
Expand Down
8 changes: 3 additions & 5 deletions packages/workflow/src/records/handler/download.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,8 @@ export async function downloadRecordHandler(
throw new Error("Task didn't have any status. This should never happen")
}

const { downloadedRecordWithTaskOnly, downloadedRecord } = await toDownloaded(
record,
token
)
const { downloadedBundleWithResources, downloadedRecord } =
await toDownloaded(record, token)

const assignment = findAssignment(record)
if (assignment) {
Expand All @@ -69,7 +67,7 @@ export async function downloadRecordHandler(
process.nextTick(async () => {
try {
// Here the sent bundle is saved with task only
await sendBundleToHearth(downloadedRecordWithTaskOnly)
await sendBundleToHearth(downloadedBundleWithResources)
await auditEvent('assigned', downloadedRecord, token)

await indexBundleToRoute(downloadedRecord, token, '/events/assigned')
Expand Down
18 changes: 4 additions & 14 deletions packages/workflow/src/records/handler/view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import * as Hapi from '@hapi/hapi'
import { getToken } from '@workflow/utils/auth-utils'
import { getValidRecordById } from '@workflow/records/index'
import { Bundle } from '@opencrvs/commons/types'
import { toViewed } from '@workflow/records/state-transitions'
import { sendBundleToHearth } from '@workflow/records/fhir'
import { auditEvent } from '@workflow/records/audit'
Expand All @@ -24,19 +23,10 @@ export async function viewRecordHandler(
const recordId = request.params.id
const record = await getValidRecordById(recordId, token, true)

const viewedRecord = await toViewed(record, token)

const viewedRecordWithSpecificEntries: Bundle = {
...viewedRecord,
entry: [
...viewedRecord.entry.filter(
(e) =>
e.resource.resourceType === 'Task' ||
/* PractitionerRole needs to exist in bundle it's needed for creating history of a record */
e.resource.resourceType === 'PractitionerRole'
)
]
}
const { viewedRecord, viewedRecordWithSpecificEntries } = await toViewed(
record,
token
)

await sendBundleToHearth(viewedRecordWithSpecificEntries)
await auditEvent('viewed', viewedRecord, token)
Expand Down
61 changes: 40 additions & 21 deletions packages/workflow/src/records/state-transitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ import {
toHistoryResource,
TaskHistory,
RejectedRecord,
SupportedPatientIdentifierCode
SupportedPatientIdentifierCode,
PractitionerRole
} from '@opencrvs/commons/types'
import { getTokenPayload, getUUID, logger, UUID } from '@opencrvs/commons'
import { getUUID, logger, UUID } from '@opencrvs/commons'
import {
REG_NUMBER_SYSTEM,
SECTION_CODE
Expand Down Expand Up @@ -105,14 +106,11 @@ import {
withPractitionerDetails,
mergeChangedResourcesIntoRecord,
createReinstateTask,
mergeBundles
mergeBundles,
getPractitionerRoleFromToken
} from '@workflow/records/fhir'
import { REG_NUMBER_GENERATION_FAILED } from '@workflow/features/registration/fhir/constants'
import { tokenExchangeHandler } from './token-exchange-handler'
import {
getPractitionerRoleByPractitionerId,
getUser
} from '@workflow/features/user/utils'

export async function toCorrected(
record: RegisteredRecord | CertifiedRecord | IssuedRecord,
Expand Down Expand Up @@ -299,20 +297,15 @@ export async function toUpdated(
export async function toViewed<T extends ValidRecord>(
record: T,
token: string
): Promise<T> {
) {
const previousTask: SavedTask = getTaskFromSavedBundle(record)
const viewedTask = await createViewTask(previousTask, token)

const taskHistoryEntry = resourceToBundleEntry(
toHistoryResource(previousTask)
) as SavedBundleEntry<TaskHistory>

const tokenPayload = getTokenPayload(token)
const userDetails = await getUser(tokenPayload.sub, { Authorization: token })
const practitionerId = userDetails.practitionerId
const practitionerRoleBundle = await getPractitionerRoleByPractitionerId(
practitionerId as UUID
)
const practitionerRoleEntry = await getPractitionerRoleFromToken(token)

const filteredEntries = record.entry.filter(
(e) => e.resource.resourceType !== 'Task'
Expand All @@ -333,11 +326,24 @@ export async function toViewed<T extends ValidRecord>(
/* PractitionerRole resource is saved in the bundle
since PractitionerRole is fetched from bundle
in the resolvers during readying history of a record */
practitionerRoleBundle.entry[0]
practitionerRoleEntry
]
} as T

return viewedRecord
const viewedRecordWithSpecificEntries: Bundle = {
...viewedRecord,
entry: [
{
fullUrl: record.entry.filter(
(e) => e.resource.resourceType === 'Task'
)[0].fullUrl,
resource: viewedTask
},
practitionerRoleEntry
]
}

return { viewedRecord, viewedRecordWithSpecificEntries }
}

export function toIdentifierUpserted<T extends ValidRecord>(
Expand Down Expand Up @@ -379,7 +385,7 @@ export async function toDownloaded(
token: string
): Promise<{
downloadedRecord: ValidRecord
downloadedRecordWithTaskOnly: Bundle<SavedTask>
downloadedBundleWithResources: Bundle<SavedTask | PractitionerRole>
}> {
const previousTask = getTaskFromSavedBundle(record)
const taskWithoutPractitionerDetails = createDownloadTask(previousTask)
Expand All @@ -401,23 +407,36 @@ export async function toDownloaded(
resource: downloadedTask
}

/*
When a user tries to access a record for the first time,
practitionerRoleBundle is necessary to create the history of the record
*/
const practitionerRoleEntry = await getPractitionerRoleFromToken(token)
const updatedBundle = {
...record,
entry: [...filteredEntriesWithoutTask, newTaskEntry, taskHistoryEntry]
entry: [
...filteredEntriesWithoutTask,
newTaskEntry,
taskHistoryEntry,
practitionerRoleEntry
]
}

const downloadedRecord = mergeBundles(
updatedBundle,
practitionerDetailsBundle
) as ValidRecord

const downloadedRecordWithTaskOnly: Bundle<SavedTask> = {
const downloadedBundleWithResources: Bundle<SavedTask | PractitionerRole> = {
resourceType: 'Bundle',
type: 'document',
entry: [{ resource: downloadedTask }]
entry: [
{ resource: downloadedTask },
{ resource: practitionerRoleEntry.resource }
]
}

return { downloadedRecord, downloadedRecordWithTaskOnly }
return { downloadedRecord, downloadedBundleWithResources }
}

export async function toRejected(
Expand Down

0 comments on commit f4eebcb

Please sign in to comment.