Skip to content
This repository has been archived by the owner on Jan 9, 2023. It is now read-only.

Commit

Permalink
feat(patients): adds a friendlyId
Browse files Browse the repository at this point in the history
fix #1709
  • Loading branch information
jackcmeyer committed Jan 8, 2020
1 parent bd54bb7 commit 318de6f
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 9 deletions.
1 change: 1 addition & 0 deletions src/__tests__/containers/HospitalRun.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ describe('HospitalRun', () => {
givenName: 'test',
familyName: 'test',
suffix: 'test',
friendlyId: 'P00001',
} as Patient

mockedPatientRepository.find.mockResolvedValue(patient)
Expand Down
1 change: 1 addition & 0 deletions src/__tests__/patients/patient-slice.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ describe('patients slice', () => {
sex: '',
dateOfBirth: '',
fullName: '',
friendlyId: '',
})
})

Expand Down
7 changes: 4 additions & 3 deletions src/__tests__/patients/view/ViewPatient.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ describe('ViewPatient', () => {
phoneNumber: 'phoneNumber',
email: '[email protected]',
address: 'address',
friendlyId: 'P00001',
dateOfBirth: new Date().toISOString(),
} as Patient

Expand Down Expand Up @@ -62,7 +63,7 @@ describe('ViewPatient', () => {
await setup()
})
expect(titleUtil.default).toHaveBeenCalledWith(
`${patient.givenName} ${patient.familyName} ${patient.suffix}`,
`${patient.givenName} ${patient.familyName} ${patient.suffix} (${patient.friendlyId})`,
)
})

Expand Down Expand Up @@ -177,12 +178,12 @@ describe('ViewPatient', () => {

wrapper.update()

const ageInput = wrapper.findWhere((w) => w.prop('name') === 'age')
const ageInput = wrapper.findWhere((w: any) => w.prop('name') === 'age')
expect(ageInput.prop('value')).toEqual('0')
expect(ageInput.prop('label')).toEqual('patient.approximateAge')
expect(ageInput.prop('isEditable')).toBeFalsy()

const dateOfBirthInput = wrapper.findWhere((w) => w.prop('name') === 'dateOfBirth')
const dateOfBirthInput = wrapper.findWhere((w: any) => w.prop('name') === 'dateOfBirth')
expect(dateOfBirthInput.prop('value')).toEqual(new Date(patient.dateOfBirth))
expect(dateOfBirthInput.prop('label')).toEqual('patient.approximateDateOfBirth')
expect(dateOfBirthInput.prop('isEditable')).toBeFalsy()
Expand Down
31 changes: 31 additions & 0 deletions src/clients/db/PatientRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,41 @@ import Patient from '../../model/Patient'
import Repository from './Repository'
import { patients } from '../../config/pouchdb'

const formatFriendlyId = (prefix: string, sequenceNumber: string) => `${prefix}${sequenceNumber}`

const generateSequenceNumber = (currentNumber: number): string => {
const newNumber = currentNumber + 1
if (newNumber < 10000) {
return newNumber.toString().padStart(5, '0')
}

return newNumber.toString()
}

export class PatientRepository extends Repository<Patient> {
constructor() {
super(patients)
}

async getFriendlyId(): Promise<string> {
const storedPatients = await this.findAll()

if (storedPatients.length === 0) {
return formatFriendlyId('P', generateSequenceNumber(0))
}

const maxPatient = storedPatients[0]
const { friendlyId } = maxPatient
const currentSequenceNumber = friendlyId.slice(1, friendlyId.length)

return formatFriendlyId('P', generateSequenceNumber(parseInt(currentSequenceNumber, 10)))
}

async save(entity: Patient): Promise<Patient> {
const friendlyId = await this.getFriendlyId()
entity.friendlyId = friendlyId
return super.save(entity)
}
}

export default new PatientRepository()
4 changes: 4 additions & 0 deletions src/model/Patient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@ export default class Patient extends AbstractDBModel {

type?: string

friendlyId: string

constructor(
id: string,
friendlyId: string,
rev: string,
sex: string,
dateOfBirth: string,
Expand Down Expand Up @@ -62,5 +65,6 @@ export default class Patient extends AbstractDBModel {
this.occupation = occupation
this.type = type
this.fullName = getPatientName(this.givenName, this.familyName, this.suffix)
this.friendlyId = friendlyId
}
}
2 changes: 1 addition & 1 deletion src/patients/list/Patients.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const Patients = () => {
<ul>
{patients.map((p) => (
<ListItem action key={p.id} onClick={() => history.push(`/patients/${p.id}`)}>
{p.givenName} {p.familyName}
{p.givenName} {p.familyName} ({p.friendlyId})
</ListItem>
))}
</ul>
Expand Down
11 changes: 10 additions & 1 deletion src/patients/patient-slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ interface PatientState {
const initialState: PatientState = {
isLoading: false,
isUpdatedSuccessfully: false,
patient: new Patient('', '', '', ''),
patient: new Patient('', '', '', '', ''),
}

function startLoading(state: PatientState) {
Expand Down Expand Up @@ -54,6 +54,15 @@ export const fetchPatient = (id: string): AppThunk => async (dispatch) => {
}
}

export const deletePatient = (patient: Patient, history: any): AppThunk => async () => {
try {
await PatientRepository.delete(patient)
history.push('/patients')
} catch (error) {
console.log(error)
}
}

export const updatePatient = (patient: Patient): AppThunk => async (dispatch) => {
try {
const updatedPatient = await PatientRepository.saveOrUpdate(patient)
Expand Down
28 changes: 24 additions & 4 deletions src/patients/view/ViewPatient.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import React, { useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { useParams, withRouter } from 'react-router-dom'
import { Panel, Spinner } from '@hospitalrun/components'
import { useHistory, useParams, withRouter } from 'react-router-dom'
import { Panel, Row, Spinner, Button } from '@hospitalrun/components'
import { useTranslation } from 'react-i18next'
import { differenceInYears } from 'date-fns'
import useTitle from '../../util/useTitle'
import { fetchPatient } from '../patient-slice'
import { deletePatient, fetchPatient } from '../patient-slice'
import { RootState } from '../../store'
import TextFieldWithLabelFormGroup from '../../components/input/TextFieldWithLabelFormGroup'
import TextInputWithLabelFormGroup from '../../components/input/TextInputWithLabelFormGroup'
import SelectWithLabelFormGroup from '../../components/input/SelectWithLableFormGroup'
import DatePickerWithLabelFormGroup from '../../components/input/DatePickerWithLabelFormGroup'
import { getPatientFullName } from '../../util/patient-name-util'
import Patient from '../../model/Patient'

const getPatientAge = (dateOfBirth: string | undefined): string => {
if (!dateOfBirth) {
Expand All @@ -30,11 +31,20 @@ const getPatientDateOfBirth = (dateOfBirth: string | undefined): Date | undefine
return new Date(dateOfBirth)
}

const getFriendlyId = (p: Patient): string => {
if (p) {
return p.friendlyId
}

return ''
}

const ViewPatient = () => {
const history = useHistory()
const { t } = useTranslation()
const dispatch = useDispatch()
const { patient } = useSelector((state: RootState) => state.patient)
useTitle(getPatientFullName(patient))
useTitle(`${getPatientFullName(patient)} (${getFriendlyId(patient)})`)

const { id } = useParams()
useEffect(() => {
Expand All @@ -47,8 +57,18 @@ const ViewPatient = () => {
return <Spinner color="blue" loading size={[10, 25]} type="ScaleLoader" />
}

const deleteCurrentPatient = () => {
dispatch(deletePatient(patient, history))
}

return (
<div>
<Row>
<Button color="danger" onClick={deleteCurrentPatient}>
Delete
</Button>
</Row>

<Panel title={t('patient.basicInformation')} color="primary" collapsible>
<div className="row">
<div className="col">
Expand Down

0 comments on commit 318de6f

Please sign in to comment.