diff --git a/packages/esm-form-entry-app/src/app/form-creation/form-creation.service.ts b/packages/esm-form-entry-app/src/app/form-creation/form-creation.service.ts index 1529fc4fbe..bcebc28114 100644 --- a/packages/esm-form-entry-app/src/app/form-creation/form-creation.service.ts +++ b/packages/esm-form-entry-app/src/app/form-creation/form-creation.service.ts @@ -243,9 +243,22 @@ export class FormCreationService { private setDefaultValues(form: Form, createFormParams: CreateFormParams) { const { session } = createFormParams; + const config = this.configResourceService.getConfig(); + let currentDate; + + if (config.customEncounterDatetime === true) { + const visitStartDatetime = moment(this.singleSpaPropsService.getProp('visitStartDatetime')).format(); + // If the visit start date is before the current date, use the visit start date as the default date. + if (visitStartDatetime && moment(visitStartDatetime).isBefore(currentDate, 'date')) { + currentDate = visitStartDatetime; + } else { + currentDate = moment().format(); + } + } else { + currentDate = moment().format(); + } // Encounter date and time. - const currentDate = moment().format(); const encounterDate = form.searchNodeByQuestionId('encDate'); if (encounterDate.length > 0) { encounterDate[0].control.setValue(currentDate); diff --git a/packages/esm-form-entry-app/src/app/form-submission/form-submission.service.ts b/packages/esm-form-entry-app/src/app/form-submission/form-submission.service.ts index 05eb09ba3c..56844cf312 100644 --- a/packages/esm-form-entry-app/src/app/form-submission/form-submission.service.ts +++ b/packages/esm-form-entry-app/src/app/form-submission/form-submission.service.ts @@ -21,6 +21,7 @@ import { SingleSpaPropsService } from '../single-spa-props/single-spa-props.serv import { v4 } from 'uuid'; import { VisitResourceService } from '../openmrs-api/visit-resource.service'; import { PatientResourceService } from '../openmrs-api/patient-resource.service'; +import { ConfigResourceService } from '../services/config-resource.service'; /** * The result of submitting a form via the {@link FormSubmissionService.submitPayload} function. @@ -42,6 +43,7 @@ export class FormSubmissionService { private readonly singleSpaPropsService: SingleSpaPropsService, private readonly visitResourceService: VisitResourceService, private readonly patientResourceService: PatientResourceService, + private readonly configResourceService: ConfigResourceService, ) {} public submitPayload(form: Form): Observable { @@ -147,20 +149,31 @@ export class FormSubmissionService { if (!encounterCreate) { return of(undefined); } + const config = this.configResourceService.getConfig(); const visitUuid = this.singleSpaPropsService.getPropOrThrow('visitUuid'); const visitStartDatetime = this.singleSpaPropsService.getProp('visitStartDatetime'); const visitStopDatetime = this.singleSpaPropsService.getProp('visitStopDatetime'); - if (encounterCreate.uuid) { - if (visitStartDatetime && new Date(encounterCreate.encounterDatetime) < new Date(visitStartDatetime)) { - return this.visitResourceService - .updateVisitDates(visitUuid, encounterCreate.encounterDatetime, visitStopDatetime) - .pipe(switchMap(() => this.updateOrSaveEncounter(encounterCreate))); - } else if (visitStopDatetime && new Date(encounterCreate.encounterDatetime) > new Date(visitStopDatetime)) { - return this.visitResourceService - .updateVisitDates(visitUuid, visitStartDatetime, encounterCreate.encounterDatetime) - .pipe(switchMap(() => this.updateOrSaveEncounter(encounterCreate))); + if (config.customEncounterDatetime === false) { + if (encounterCreate.uuid) { + if ( + visitStartDatetime && + new Date(encounterCreate.encounterDatetime) < new Date(visitStartDatetime) && + this.confirmVisitDateAdjustment() + ) { + return this.visitResourceService + .updateVisitDates(visitUuid, encounterCreate.encounterDatetime, visitStopDatetime) + .pipe(switchMap(() => this.updateOrSaveEncounter(encounterCreate))); + } else if ( + visitStopDatetime && + new Date(encounterCreate.encounterDatetime) > new Date(visitStopDatetime) && + this.confirmVisitDateAdjustment() + ) { + return this.visitResourceService + .updateVisitDates(visitUuid, visitStartDatetime, encounterCreate.encounterDatetime) + .pipe(switchMap(() => this.updateOrSaveEncounter(encounterCreate))); + } } } diff --git a/packages/esm-form-entry-app/src/app/openmrs-api/program-resource.service.ts b/packages/esm-form-entry-app/src/app/openmrs-api/program-resource.service.ts index 5c85454a0c..d605f92c3b 100644 --- a/packages/esm-form-entry-app/src/app/openmrs-api/program-resource.service.ts +++ b/packages/esm-form-entry-app/src/app/openmrs-api/program-resource.service.ts @@ -3,11 +3,13 @@ import { HttpClient } from '@angular/common/http'; import { WindowRef } from '../window-ref'; import { Form } from '@openmrs/ngx-formentry'; -import { MetaData } from '../types'; +import { MetaData, PatientProgram } from '../types'; import { parseDate, showNotification, showToast } from '@openmrs/esm-framework'; import { SingleSpaPropsService } from '../single-spa-props/single-spa-props.service'; import { EncounterResourceService } from './encounter-resource.service'; import moment from 'moment'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; @Injectable() export class ProgramResourceService { @@ -57,24 +59,28 @@ export class ProgramResourceService { location: locationUuuid, }; - this.httpClient.post(this.programEnrollmentUrl(), payload).subscribe( - (response) => { - showToast({ - title: 'Program enrollment', - description: 'Patient has been enrolled successfully', - kind: 'success', - }); - }, - (err) => { - // void created encounter to prevent enrollment missing an encounter - this.encounterResourceService.voidEncounter(encounterUuid); - showNotification({ - title: 'Enrollment error', - description: 'An error occurred during care program enrollment, this encounter has been voided', - kind: 'error', - }); - }, - ); + this.isPatientEnrolled(patientUuid, programUuid).subscribe((result: boolean) => { + if (!result) { + this.httpClient.post(this.programEnrollmentUrl(), payload).subscribe( + (response) => { + showToast({ + title: 'Program enrollment', + description: 'Patient has been enrolled successfully', + kind: 'success', + }); + }, + (err) => { + // void created encounter to prevent enrollment missing an encounter + this.encounterResourceService.voidEncounter(encounterUuid); + showNotification({ + title: 'Enrollment error', + description: 'An error occurred during care program enrollment, this encounter has been voided', + kind: 'error', + }); + }, + ); + } + }); } public discontinuePatientFromCareProgram(discontinuationDate: string, encounterUuid: string) { @@ -114,4 +120,18 @@ export class ProgramResourceService { }, ); } + + public isPatientEnrolled(patientUuid: string, programUuid: string): Observable { + const url = this.programEnrollmentUrl() + `?patient=${patientUuid}&v=full`; + return this.httpClient.get(url).pipe( + map((response: any) => { + if (response && response.results) { + return !!response.results.find((patientProgram: PatientProgram) => { + return patientProgram.program.uuid === programUuid && patientProgram.dateCompleted === null; + }); + } + return false; + }), + ); + } } diff --git a/packages/esm-form-entry-app/src/app/types/index.ts b/packages/esm-form-entry-app/src/app/types/index.ts index b611b960db..657f764a9a 100644 --- a/packages/esm-form-entry-app/src/app/types/index.ts +++ b/packages/esm-form-entry-app/src/app/types/index.ts @@ -227,6 +227,7 @@ export interface FormEntryConfig { moduleExport: 'default' | string; }[]; appointmentsResourceUrl: string; + customEncounterDatetime: boolean; } export interface ListResult { diff --git a/packages/esm-form-entry-app/src/config-schema.ts b/packages/esm-form-entry-app/src/config-schema.ts index cc94771e88..82214bf811 100644 --- a/packages/esm-form-entry-app/src/config-schema.ts +++ b/packages/esm-form-entry-app/src/config-schema.ts @@ -41,4 +41,10 @@ export const configSchema = { _description: 'Custom URL to load resources required for appointment monthly schedule feature (under `dataSources`).', }, + customEncounterDatetime: { + _type: 'Boolean', + _default: false, + _description: + 'Weather to default the encounterDate to visitStartDatetime if the visitStartDatetime is before current Date.', + }, };