diff --git a/packages/openchs-android/package-lock.json b/packages/openchs-android/package-lock.json
index d96abb1ec..1132341fd 100644
--- a/packages/openchs-android/package-lock.json
+++ b/packages/openchs-android/package-lock.json
@@ -33,7 +33,7 @@
"lodash": "4.17.21",
"moment": "2.29.4",
"native-base": "3.4.9",
- "openchs-models": "1.31.14",
+ "openchs-models": "1.31.16",
"prop-types": "15.8.1",
"react": "18.2.0",
"react-native": "0.72.3",
@@ -16433,9 +16433,9 @@
}
},
"node_modules/openchs-models": {
- "version": "1.31.14",
- "resolved": "https://registry.npmjs.org/openchs-models/-/openchs-models-1.31.14.tgz",
- "integrity": "sha512-y3ngUTqsvFJSH44/lQrQlAi2YUWXW2fKiacE5KSuKJV7NyOdd/WXUQu11JZW9y5o7MTWw4uuNSMh7NaDjRQcnA==",
+ "version": "1.31.16",
+ "resolved": "https://registry.npmjs.org/openchs-models/-/openchs-models-1.31.16.tgz",
+ "integrity": "sha512-OcgGFTYGgFhDPFcb+taZkMA1/p7TvGZCZk4vWcBAIyF8byba0PRrkY88EcRnqeWzIi3So3qYZohQoZlkIYMsPQ==",
"dependencies": {
"uuid": "^9.0.1"
},
@@ -35159,9 +35159,9 @@
}
},
"openchs-models": {
- "version": "1.31.14",
- "resolved": "https://registry.npmjs.org/openchs-models/-/openchs-models-1.31.14.tgz",
- "integrity": "sha512-y3ngUTqsvFJSH44/lQrQlAi2YUWXW2fKiacE5KSuKJV7NyOdd/WXUQu11JZW9y5o7MTWw4uuNSMh7NaDjRQcnA==",
+ "version": "1.31.16",
+ "resolved": "https://registry.npmjs.org/openchs-models/-/openchs-models-1.31.16.tgz",
+ "integrity": "sha512-OcgGFTYGgFhDPFcb+taZkMA1/p7TvGZCZk4vWcBAIyF8byba0PRrkY88EcRnqeWzIi3So3qYZohQoZlkIYMsPQ==",
"requires": {
"uuid": "^9.0.1"
}
diff --git a/packages/openchs-android/src/action/program/ProgramEncounterCancelState.js b/packages/openchs-android/src/action/program/ProgramEncounterCancelState.js
index 66bde03ec..e6b9ff5f2 100644
--- a/packages/openchs-android/src/action/program/ProgramEncounterCancelState.js
+++ b/packages/openchs-android/src/action/program/ProgramEncounterCancelState.js
@@ -62,7 +62,7 @@ class ProgramEncounterCancelState extends AbstractDataEntryState {
}
getNextScheduledVisits(ruleService, context) {
- const nextScheduledVisits = ruleService.getNextScheduledVisits(this.getEntity(), this.getEntityType());
+ const nextScheduledVisits = ruleService.getNextScheduledVisits(this.getEntity(), this.getEntityType()).filter((x) => !this.isAlreadyScheduled(this.programEncounter.programEnrolment, x));
return context.get(IndividualService).validateAndInjectOtherSubjectForScheduledVisit(this.getEntity().individual, nextScheduledVisits);
}
diff --git a/packages/openchs-android/src/state/AbstractDataEntryState.js b/packages/openchs-android/src/state/AbstractDataEntryState.js
index 183f05e04..85cccd08e 100644
--- a/packages/openchs-android/src/state/AbstractDataEntryState.js
+++ b/packages/openchs-android/src/state/AbstractDataEntryState.js
@@ -350,6 +350,15 @@ class AbstractDataEntryState {
getEntityResultSetByType(context) {
return []
}
+
+ isAlreadyScheduled(programEnrolment, newlyScheduledEncounter) {
+ //paranoid code
+ if (_.isNil(programEnrolment) || _.isNil(programEnrolment.everScheduledEncountersOfType)) return false;
+
+ return _.some(programEnrolment.everScheduledEncountersOfType(newlyScheduledEncounter.encounterType), (alreadyScheduledEncounter) => {
+ return General.datesAreSame(newlyScheduledEncounter.earliestDate, alreadyScheduledEncounter.earliestVisitDateTime) && General.datesAreSame(newlyScheduledEncounter.maxDate, alreadyScheduledEncounter.maxVisitDateTime) && newlyScheduledEncounter.name === alreadyScheduledEncounter.name;
+ });
+ }
}
export default AbstractDataEntryState;
diff --git a/packages/openchs-android/src/state/ProgramEncounterState.js b/packages/openchs-android/src/state/ProgramEncounterState.js
index 83f145cdc..71c785350 100644
--- a/packages/openchs-android/src/state/ProgramEncounterState.js
+++ b/packages/openchs-android/src/state/ProgramEncounterState.js
@@ -1,17 +1,13 @@
import AbstractDataEntryState from "./AbstractDataEntryState";
import Wizard from "./Wizard";
-import {
- AbstractEncounter,
- ObservationsHolder,
- ProgramEncounter,
- StaticFormElementGroup
-} from "avni-models";
+import {AbstractEncounter, ObservationsHolder, ProgramEncounter, StaticFormElementGroup} from "avni-models";
import ConceptService from "../service/ConceptService";
import _ from 'lodash';
import IndividualService from "../service/IndividualService";
import EntityService from "../service/EntityService";
import ObservationHolderActions from "../action/common/ObservationsHolderActions";
import TimerState from "./TimerState";
+import General from "../utility/General";
class ProgramEncounterState extends AbstractDataEntryState {
constructor(formElementGroup, wizard, isNewEntity, programEncounter, filteredFormElements, workLists, messageDisplayed, timerState, isFirstFlow) {
@@ -109,6 +105,7 @@ class ProgramEncounterState extends AbstractDataEntryState {
getNextScheduledVisits(ruleService, context) {
const nextScheduledVisits = ruleService.getNextScheduledVisits(this.programEncounter, ProgramEncounter.schema.name, [])
+ .filter((x) => !this.isAlreadyScheduled(this.programEncounter.programEnrolment, x))
.map(k => _.assignIn({}, k));
return context.get(IndividualService).validateAndInjectOtherSubjectForScheduledVisit(this.programEncounter.individual, nextScheduledVisits);
}
diff --git a/packages/openchs-android/src/state/ProgramEnrolmentState.js b/packages/openchs-android/src/state/ProgramEnrolmentState.js
index cb8ad1a90..6e1e599f1 100644
--- a/packages/openchs-android/src/state/ProgramEnrolmentState.js
+++ b/packages/openchs-android/src/state/ProgramEnrolmentState.js
@@ -132,12 +132,12 @@ class ProgramEnrolmentState extends AbstractDataEntryState {
getNextScheduledVisits(ruleService, context) {
if (this.usage === ProgramEnrolmentState.UsageKeys.Enrol) {
- const nextScheduledVisits = ruleService.getNextScheduledVisits(this.enrolment, ProgramEnrolment.schema.name, []);
+ const nextScheduledVisits = ruleService.getNextScheduledVisits(this.enrolment, ProgramEnrolment.schema.name, [])
+ .filter((x) => !this.isAlreadyScheduled(this.enrolment, x));
return context.get(IndividualService).validateAndInjectOtherSubjectForScheduledVisit(this.enrolment.individual, nextScheduledVisits);
} else {
return null;
}
-
}
static isInitialised(programEnrolmentState) {
diff --git a/packages/openchs-android/src/utility/General.js b/packages/openchs-android/src/utility/General.js
index 87a80b189..088886a4a 100644
--- a/packages/openchs-android/src/utility/General.js
+++ b/packages/openchs-android/src/utility/General.js
@@ -201,8 +201,14 @@ class General {
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
}
+ static toISTDate(x) {
+ if (x.toString().includes("18:30:00"))
+ return moment(x).add(330, "m").toDate();
+ return x;
+ }
+
static datesAreSame(a, b) {
- return moment(a).isSame(moment(b), 'day');
+ return moment(General.toISTDate(a)).isSame(moment(General.toISTDate(b)), 'day');
}
static dateAIsAfterB(a, b) {
diff --git a/packages/openchs-android/src/views/settings/DevSettingsView.js b/packages/openchs-android/src/views/settings/DevSettingsView.js
index 15e39b25b..2bedc8b85 100644
--- a/packages/openchs-android/src/views/settings/DevSettingsView.js
+++ b/packages/openchs-android/src/views/settings/DevSettingsView.js
@@ -18,6 +18,7 @@ import RuleEvaluationService from "../../service/RuleEvaluationService";
import {Rule} from 'openchs-models';
import SelectableItemGroup from "../primitives/SelectableItemGroup";
import UserInfoService from "../../service/UserInfoService";
+import moment from "moment";
@Path('/devSettingsView')
class DevSettingsView extends AbstractComponent {
@@ -93,6 +94,10 @@ class DevSettingsView extends AbstractComponent {
Server URL:
this.dispatchAction(Actions.ON_SERVER_URL_CHANGE, {value: text})}/>
+
+ Current App Time:
+ {moment().format("DD MMM YYYY hh:mm a")}
+
);
}
}