16135 lines
929 KiB
JavaScript
16135 lines
929 KiB
JavaScript
"use strict";
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {},
|
|
function() {
|
|
var hostUrl = localStorage.getItem("host") ? "https://" + localStorage.getItem("host") : "",
|
|
rootDir = localStorage.getItem("rootDir") || "",
|
|
RESTWS = hostUrl + "/openmrs/ws/rest",
|
|
RESTWS_V1 = hostUrl + "/openmrs/ws/rest/v1",
|
|
BAHMNI_CORE = RESTWS_V1 + "/bahmnicore",
|
|
EMRAPI = RESTWS + "/emrapi",
|
|
BACTERIOLOGY = RESTWS_V1,
|
|
BASE_URL = hostUrl + "/bahmni_config/openmrs/apps/",
|
|
CUSTOM_URL = hostUrl + "/implementation_config/openmrs/apps/",
|
|
serverErrorMessages = [{
|
|
serverMessage: "Cannot have more than one active order for the same orderable and care setting at same time",
|
|
clientMessage: "One or more drugs you are trying to order are already active. Please change the start date of the conflicting drug or remove them from the new prescription."
|
|
}, {
|
|
serverMessage: "[Order.cannot.have.more.than.one]",
|
|
clientMessage: "One or more drugs you are trying to order are already active. Please change the start date of the conflicting drug or remove them from the new prescription."
|
|
}],
|
|
representation = "custom:(uuid,name,names,conceptClass,setMembers:(uuid,name,names,conceptClass,setMembers:(uuid,name,names,conceptClass,setMembers:(uuid,name,names,conceptClass))))",
|
|
unAuthenticatedReferenceDataMap = {
|
|
"/openmrs/ws/rest/v1/location?tags=Login+Location&s=byTags&v=default": "LoginLocations",
|
|
"/openmrs/ws/rest/v1/bahmnicore/sql/globalproperty?property=locale.allowed.list": "LocaleList"
|
|
},
|
|
authenticatedReferenceDataMap = {
|
|
"/openmrs/ws/rest/v1/idgen/identifiertype": "IdentifierTypes",
|
|
"/openmrs/module/addresshierarchy/ajax/getOrderedAddressHierarchyLevels.form": "AddressHierarchyLevels",
|
|
"/openmrs/ws/rest/v1/bahmnicore/sql/globalproperty?property=mrs.genders": "Genders",
|
|
"/openmrs/ws/rest/v1/bahmnicore/sql/globalproperty?property=bahmni.encountersession.duration": "encounterSessionDuration",
|
|
"/openmrs/ws/rest/v1/bahmnicore/sql/globalproperty?property=bahmni.relationshipTypeMap": "RelationshipTypeMap",
|
|
"/openmrs/ws/rest/v1/bahmnicore/config/bahmniencounter?callerContext=REGISTRATION_CONCEPTS": "RegistrationConcepts",
|
|
"/openmrs/ws/rest/v1/relationshiptype?v=custom:(aIsToB,bIsToA,uuid)": "RelationshipType",
|
|
"/openmrs/ws/rest/v1/personattributetype?v=custom:(uuid,name,sortWeight,description,format,concept)": "PersonAttributeType",
|
|
"/openmrs/ws/rest/v1/entitymapping?mappingType=loginlocation_visittype&s=byEntityAndMappingType": "LoginLocationToVisitTypeMapping",
|
|
"/openmrs/ws/rest/v1/bahmnicore/config/patient": "PatientConfig",
|
|
"/openmrs/ws/rest/v1/concept?s=byFullySpecifiedName&name=Consultation+Note&v=custom:(uuid,name,answers)": "ConsultationNote",
|
|
"/openmrs/ws/rest/v1/concept?s=byFullySpecifiedName&name=Lab+Order+Notes&v=custom:(uuid,name)": "LabOrderNotes",
|
|
"/openmrs/ws/rest/v1/concept?s=byFullySpecifiedName&name=Impression&v=custom:(uuid,name)": "RadiologyImpressionConfig",
|
|
"/openmrs/ws/rest/v1/concept?s=byFullySpecifiedName&name=All_Tests_and_Panels&v=custom:(uuid,name:(uuid,name),setMembers:(uuid,name:(uuid,name)))": "AllTestsAndPanelsConcept",
|
|
"/openmrs/ws/rest/v1/concept?s=byFullySpecifiedName&name=Dosage+Frequency&v=custom:(uuid,name,answers)": "DosageFrequencyConfig",
|
|
"/openmrs/ws/rest/v1/concept?s=byFullySpecifiedName&name=Dosage+Instructions&v=custom:(uuid,name,answers)": "DosageInstructionConfig",
|
|
"/openmrs/ws/rest/v1/bahmnicore/sql/globalproperty?property=bahmni.encounterType.default": "DefaultEncounterType",
|
|
"/openmrs/ws/rest/v1/concept?s=byFullySpecifiedName&name=Stopped+Order+Reason&v=custom:(uuid,name,answers)": "StoppedOrderReasonConfig",
|
|
"/openmrs/ws/rest/v1/ordertype": "OrderType",
|
|
"/openmrs/ws/rest/v1/bahmnicore/config/drugOrders": "DrugOrderConfig",
|
|
"/openmrs/ws/rest/v1/bahmnicore/sql/globalproperty?property=drugOrder.drugOther": "NonCodedDrugConcept"
|
|
};
|
|
authenticatedReferenceDataMap["/openmrs/ws/rest/v1/entitymapping?mappingType=location_encountertype&s=byEntityAndMappingType&entityUuid=" + (localStorage.getItem("LoginInformation") ? JSON.parse(localStorage.getItem("LoginInformation")).currentLocation.uuid : "")] = "LoginLocationToEncounterTypeMapping", Bahmni.Common.Constants = {
|
|
hostURL: hostUrl,
|
|
dateFormat: "dd/mm/yyyy",
|
|
dateDisplayFormat: "DD-MMM-YYYY",
|
|
timeDisplayFormat: "hh:mm",
|
|
emrapiDiagnosisUrl: EMRAPI + "/diagnosis",
|
|
bahmniDiagnosisUrl: BAHMNI_CORE + "/diagnosis/search",
|
|
bahmniDeleteDiagnosisUrl: BAHMNI_CORE + "/diagnosis/delete",
|
|
diseaseTemplateUrl: BAHMNI_CORE + "/diseaseTemplates",
|
|
AllDiseaseTemplateUrl: BAHMNI_CORE + "/diseaseTemplate",
|
|
emrapiConceptUrl: EMRAPI + "/concept",
|
|
encounterConfigurationUrl: BAHMNI_CORE + "/config/bahmniencounter",
|
|
patientConfigurationUrl: BAHMNI_CORE + "/config/patient",
|
|
drugOrderConfigurationUrl: BAHMNI_CORE + "/config/drugOrders",
|
|
emrEncounterUrl: EMRAPI + "/encounter",
|
|
encounterUrl: RESTWS_V1 + "/encounter",
|
|
locationUrl: RESTWS_V1 + "/location",
|
|
bahmniVisitLocationUrl: BAHMNI_CORE + "/visitLocation",
|
|
bahmniOrderUrl: BAHMNI_CORE + "/orders",
|
|
bahmniDrugOrderUrl: BAHMNI_CORE + "/drugOrders",
|
|
bahmniDispositionByVisitUrl: BAHMNI_CORE + "/disposition/visit",
|
|
bahmniDispositionByPatientUrl: BAHMNI_CORE + "/disposition/patient",
|
|
bahmniSearchUrl: BAHMNI_CORE + "/search",
|
|
bahmniLabOrderResultsUrl: BAHMNI_CORE + "/labOrderResults",
|
|
bahmniEncounterUrl: BAHMNI_CORE + "/bahmniencounter",
|
|
conceptUrl: RESTWS_V1 + "/concept",
|
|
bahmniConceptAnswerUrl: RESTWS_V1 + "/bahmniconceptanswer",
|
|
conceptSearchByFullNameUrl: RESTWS_V1 + "/concept?s=byFullySpecifiedName",
|
|
visitUrl: RESTWS_V1 + "/visit",
|
|
endVisitUrl: BAHMNI_CORE + "/visit/endVisit",
|
|
endVisitAndCreateEncounterUrl: BAHMNI_CORE + "/visit/endVisitAndCreateEncounter",
|
|
visitTypeUrl: RESTWS_V1 + "/visittype",
|
|
patientImageUrlByPatientUuid: RESTWS_V1 + "/patientImage?patientUuid=",
|
|
labResultUploadedFileNameUrl: "/uploaded_results/",
|
|
visitSummaryUrl: BAHMNI_CORE + "/visit/summary",
|
|
encounterModifierUrl: BAHMNI_CORE + "/bahmniencountermodifier",
|
|
openmrsUrl: hostUrl + "/openmrs",
|
|
loggingUrl: hostUrl + "/log/",
|
|
idgenConfigurationURL: RESTWS_V1 + "/idgen/identifiertype",
|
|
bahmniRESTBaseURL: BAHMNI_CORE + "",
|
|
observationsUrl: BAHMNI_CORE + "/observations",
|
|
obsRelationshipUrl: BAHMNI_CORE + "/obsrelationships",
|
|
encounterImportUrl: BAHMNI_CORE + "/admin/upload/encounter",
|
|
programImportUrl: BAHMNI_CORE + "/admin/upload/program",
|
|
conceptImportUrl: BAHMNI_CORE + "/admin/upload/concept",
|
|
conceptSetImportUrl: BAHMNI_CORE + "/admin/upload/conceptset",
|
|
drugImportUrl: BAHMNI_CORE + "/admin/upload/drug",
|
|
labResultsImportUrl: BAHMNI_CORE + "/admin/upload/labResults",
|
|
referenceTermsImportUrl: BAHMNI_CORE + "/admin/upload/referenceterms",
|
|
relationshipImportUrl: BAHMNI_CORE + "/admin/upload/relationship",
|
|
conceptSetExportUrl: BAHMNI_CORE + "/admin/export/conceptset?conceptName=:conceptName",
|
|
patientImportUrl: BAHMNI_CORE + "/admin/upload/patient",
|
|
adminImportStatusUrl: BAHMNI_CORE + "/admin/upload/status",
|
|
programUrl: RESTWS_V1 + "/program",
|
|
programEnrollPatientUrl: RESTWS_V1 + "/bahmniprogramenrollment",
|
|
programStateDeletionUrl: RESTWS_V1 + "/programenrollment",
|
|
programEnrollmentDefaultInformation: "default",
|
|
programEnrollmentFullInformation: "full",
|
|
programAttributeTypes: RESTWS_V1 + "/programattributetype",
|
|
relationshipTypesUrl: RESTWS_V1 + "/relationshiptype",
|
|
personAttributeTypeUrl: RESTWS_V1 + "/personattributetype",
|
|
diseaseSummaryPivotUrl: BAHMNI_CORE + "/diseaseSummaryData",
|
|
allTestsAndPanelsConceptName: "All_Tests_and_Panels",
|
|
dosageFrequencyConceptName: "Dosage Frequency",
|
|
dosageInstructionConceptName: "Dosage Instructions",
|
|
stoppedOrderReasonConceptName: "Stopped Order Reason",
|
|
consultationNoteConceptName: "Consultation Note",
|
|
diagnosisConceptSet: "Diagnosis Concept Set",
|
|
radiologyOrderType: "Radiology Order",
|
|
radiologyResultConceptName: "Radiology Result",
|
|
investigationEncounterType: "INVESTIGATION",
|
|
validationNotesEncounterType: "VALIDATION NOTES",
|
|
labOrderNotesConcept: "Lab Order Notes",
|
|
impressionConcept: "Impression",
|
|
qualifiedByRelationshipType: "qualified-by",
|
|
dispositionConcept: "Disposition",
|
|
dispositionGroupConcept: "Disposition Set",
|
|
dispositionNoteConcept: "Disposition Note",
|
|
ruledOutDiagnosisConceptName: "Ruled Out Diagnosis",
|
|
emrapiConceptMappingSource: "org.openmrs.module.emrapi",
|
|
abbreviationConceptMappingSource: "Abbreviation",
|
|
includeAllObservations: !1,
|
|
openmrsObsUrl: RESTWS_V1 + "/obs",
|
|
openmrsObsRepresentation: "custom:(uuid,obsDatetime,value:(uuid,name:(uuid,name)))",
|
|
admissionCode: "ADMIT",
|
|
dischargeCode: "DISCHARGE",
|
|
transferCode: "TRANSFER",
|
|
undoDischargeCode: "UNDO_DISCHARGE",
|
|
vitalsConceptName: "Vitals",
|
|
heightConceptName: "HEIGHT",
|
|
weightConceptName: "WEIGHT",
|
|
bmiConceptName: "BMI",
|
|
bmiStatusConceptName: "BMI STATUS",
|
|
abnormalObservationConceptName: "IS_ABNORMAL",
|
|
documentsPath: "/document_images",
|
|
documentsConceptName: "Document",
|
|
miscConceptClassName: "Misc",
|
|
abnormalConceptClassName: "Abnormal",
|
|
unknownConceptClassName: "Unknown",
|
|
durationConceptClassName: "Duration",
|
|
conceptDetailsClassName: "Concept Details",
|
|
admissionEncounterTypeName: "ADMISSION",
|
|
dischargeEncounterTypeName: "DISCHARGE",
|
|
imageClassName: "Image",
|
|
videoClassName: "Video",
|
|
locationCookieName: "bahmni.user.location",
|
|
retrospectiveEntryEncounterDateCookieName: "bahmni.clinical.retrospectiveEncounterDate",
|
|
JSESSIONID: "JSESSIONID",
|
|
rootScopeRetrospectiveEntry: "retrospectiveEntry.encounterDate",
|
|
patientFileConceptName: "Patient file",
|
|
serverErrorMessages: serverErrorMessages,
|
|
currentUser: "bahmni.user",
|
|
retrospectivePrivilege: "app:clinical:retrospective",
|
|
locationPickerPrivilege: "app:clinical:locationpicker",
|
|
onBehalfOfPrivilege: "app:clinical:onbehalf",
|
|
nutritionalConceptName: "Nutritional Values",
|
|
messageForNoObservation: "NO_OBSERVATIONS_CAPTURED",
|
|
messageForNoDisposition: "NO_DISPOSTIONS_AVAILABLE_MESSAGE_KEY",
|
|
messageForNoFulfillment: "NO_FULFILMENT_MESSAGE",
|
|
reportsUrl: "/bahmnireports",
|
|
uploadReportTemplateUrl: "/bahmnireports/upload",
|
|
ruledOutdiagnosisStatus: "Ruled Out Diagnosis",
|
|
registartionConsultationPrivilege: "app:common:registration_consultation_link",
|
|
manageIdentifierSequencePrivilege: "Manage Identifier Sequence",
|
|
closeVisitPrivilege: "app:common:closeVisit",
|
|
deleteDiagnosisPrivilege: "app:clinical:deleteDiagnosis",
|
|
viewPatientsPrivilege: "View Patients",
|
|
editPatientsPrivilege: "Edit Patients",
|
|
addVisitsPrivilege: "Add Visits",
|
|
deleteVisitsPrivilege: "Delete Visits",
|
|
grantProviderAccess: "app:clinical:grantProviderAccess",
|
|
grantProviderAccessDataCookieName: "app.clinical.grantProviderAccessData",
|
|
globalPropertyUrl: BAHMNI_CORE + "/sql/globalproperty",
|
|
passwordPolicyUrl: BAHMNI_CORE + "/globalProperty/passwordPolicyProperties",
|
|
fulfillmentConfiguration: "fulfillment",
|
|
fulfillmentFormSuffix: " Fulfillment Form",
|
|
noNavigationLinksMessage: "NO_NAVIGATION_LINKS_AVAILABLE_MESSAGE",
|
|
conceptSetRepresentationForOrderFulfillmentConfig: representation,
|
|
entityMappingUrl: RESTWS_V1 + "/entitymapping",
|
|
encounterTypeUrl: RESTWS_V1 + "/encountertype",
|
|
defaultExtensionName: "default",
|
|
orderSetMemberAttributeTypeUrl: RESTWS_V1 + "/ordersetmemberattributetype",
|
|
orderSetUrl: RESTWS_V1 + "/bahmniorderset",
|
|
primaryOrderSetMemberAttributeTypeName: "Primary",
|
|
bahmniBacteriologyResultsUrl: BACTERIOLOGY + "/specimen",
|
|
bedFromVisit: RESTWS_V1 + "/beds",
|
|
ordersUrl: RESTWS_V1 + "/order",
|
|
formDataUrl: RESTWS_V1 + "/obs",
|
|
providerUrl: RESTWS_V1 + "/provider",
|
|
drugUrl: RESTWS_V1 + "/drug",
|
|
orderTypeUrl: RESTWS_V1 + "/ordertype",
|
|
userUrl: RESTWS_V1 + "/user",
|
|
passwordUrl: RESTWS_V1 + "/password",
|
|
formUrl: RESTWS_V1 + "/form",
|
|
allFormsUrl: RESTWS_V1 + "/bahmniie/form/allForms",
|
|
latestPublishedForms: RESTWS_V1 + "/bahmniie/form/latestPublishedForms",
|
|
formTranslationsUrl: RESTWS_V1 + "/bahmniie/form/translations",
|
|
sqlUrl: BAHMNI_CORE + "/sql",
|
|
patientAttributeDateFieldFormat: "org.openmrs.util.AttributableDate",
|
|
platform: "user.platform",
|
|
RESTWS_V1: RESTWS_V1,
|
|
baseUrl: BASE_URL,
|
|
customUrl: CUSTOM_URL,
|
|
faviconUrl: hostUrl + "/bahmni/favicon.ico",
|
|
platformType: {
|
|
other: "other"
|
|
},
|
|
numericDataType: "Numeric",
|
|
encryptionType: {
|
|
SHA3: "SHA3"
|
|
},
|
|
LoginInformation: "LoginInformation",
|
|
ServerDateTimeFormat: "YYYY-MM-DDTHH:mm:ssZZ",
|
|
calculateDose: BAHMNI_CORE + "/calculateDose",
|
|
unAuthenticatedReferenceDataMap: unAuthenticatedReferenceDataMap,
|
|
authenticatedReferenceDataMap: authenticatedReferenceDataMap,
|
|
rootDir: rootDir,
|
|
dischargeUrl: BAHMNI_CORE + "/discharge",
|
|
uuidRegex: "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}",
|
|
eventlogFilterUrl: hostUrl + "/openmrs/ws/rest/v1/eventlog/filter",
|
|
bahmniConnectMetaDataDb: "metaData",
|
|
serverDateTimeUrl: "/cgi-bin/systemdate",
|
|
loginText: "/bahmni_config/openmrs/apps/home/whiteLabel.json",
|
|
auditLogUrl: RESTWS_V1 + "/auditlog",
|
|
appointmentServiceUrl: RESTWS_V1 + "/appointmentService",
|
|
conditionUrl: EMRAPI + "/condition",
|
|
conditionHistoryUrl: EMRAPI + "/conditionhistory",
|
|
followUpConditionConcept: "Follow-up Condition",
|
|
localeLangs: "/bahmni_config/openmrs/apps/home/locale_languages.json",
|
|
privilegeRequiredErrorMessage: "PRIVILEGE_REQUIRED",
|
|
defaultPossibleRelativeSearchLimit: 10
|
|
}
|
|
}(),
|
|
function() {
|
|
function n(n, t) {
|
|
return n.set(t[0], t[1]), n
|
|
}
|
|
|
|
function t(n, t) {
|
|
return n.add(t), n
|
|
}
|
|
|
|
function r(n, t, r) {
|
|
switch (r.length) {
|
|
case 0:
|
|
return n.call(t);
|
|
case 1:
|
|
return n.call(t, r[0]);
|
|
case 2:
|
|
return n.call(t, r[0], r[1]);
|
|
case 3:
|
|
return n.call(t, r[0], r[1], r[2])
|
|
}
|
|
return n.apply(t, r)
|
|
}
|
|
|
|
function e(n, t, r, e) {
|
|
for (var u = -1, o = n.length; ++u < o;) {
|
|
var i = n[u];
|
|
t(e, i, r(i), n)
|
|
}
|
|
return e
|
|
}
|
|
|
|
function u(n, t) {
|
|
for (var r = -1, e = n.length; ++r < e && !1 !== t(n[r], r, n););
|
|
return n
|
|
}
|
|
|
|
function o(n, t) {
|
|
for (var r = -1, e = n.length; ++r < e;)
|
|
if (!t(n[r], r, n)) return !1;
|
|
return !0
|
|
}
|
|
|
|
function i(n, t) {
|
|
for (var r = -1, e = n.length, u = -1, o = []; ++r < e;) {
|
|
var i = n[r];
|
|
t(i, r, n) && (o[++u] = i)
|
|
}
|
|
return o
|
|
}
|
|
|
|
function f(n, t) {
|
|
return !!n.length && -1 < d(n, t, 0)
|
|
}
|
|
|
|
function c(n, t, r) {
|
|
for (var e = -1, u = n.length; ++e < u;)
|
|
if (r(t, n[e])) return !0;
|
|
return !1
|
|
}
|
|
|
|
function a(n, t) {
|
|
for (var r = -1, e = n.length, u = Array(e); ++r < e;) u[r] = t(n[r], r, n);
|
|
return u
|
|
}
|
|
|
|
function l(n, t) {
|
|
for (var r = -1, e = t.length, u = n.length; ++r < e;) n[u + r] = t[r];
|
|
return n
|
|
}
|
|
|
|
function s(n, t, r, e) {
|
|
var u = -1,
|
|
o = n.length;
|
|
for (e && o && (r = n[++u]); ++u < o;) r = t(r, n[u], u, n);
|
|
return r
|
|
}
|
|
|
|
function h(n, t, r, e) {
|
|
var u = n.length;
|
|
for (e && u && (r = n[--u]); u--;) r = t(r, n[u], u, n);
|
|
return r
|
|
}
|
|
|
|
function p(n, t) {
|
|
for (var r = -1, e = n.length; ++r < e;)
|
|
if (t(n[r], r, n)) return !0;
|
|
return !1
|
|
}
|
|
|
|
function _(n, t, r) {
|
|
for (var e = -1, u = n.length; ++e < u;) {
|
|
var o = n[e],
|
|
i = t(o);
|
|
if (null != i && (f === Z ? i === i : r(i, f))) var f = i,
|
|
c = o
|
|
}
|
|
return c
|
|
}
|
|
|
|
function g(n, t, r, e) {
|
|
var u;
|
|
return r(n, function(n, r, o) {
|
|
return t(n, r, o) ? (u = e ? r : n, !1) : void 0
|
|
}), u
|
|
}
|
|
|
|
function v(n, t, r) {
|
|
for (var e = n.length, u = r ? e : -1; r ? u-- : ++u < e;)
|
|
if (t(n[u], u, n)) return u;
|
|
return -1
|
|
}
|
|
|
|
function d(n, t, r) {
|
|
if (t !== t) return B(n, r);
|
|
--r;
|
|
for (var e = n.length; ++r < e;)
|
|
if (n[r] === t) return r;
|
|
return -1
|
|
}
|
|
|
|
function y(n, t, r, e, u) {
|
|
return u(n, function(n, u, o) {
|
|
r = e ? (e = !1, n) : t(r, n, u, o)
|
|
}), r
|
|
}
|
|
|
|
function b(n, t) {
|
|
var r = n.length;
|
|
for (n.sort(t); r--;) n[r] = n[r].c;
|
|
return n
|
|
}
|
|
|
|
function x(n, t) {
|
|
for (var r, e = -1, u = n.length; ++e < u;) {
|
|
var o = t(n[e]);
|
|
o !== Z && (r = r === Z ? o : r + o)
|
|
}
|
|
return r
|
|
}
|
|
|
|
function j(n, t) {
|
|
for (var r = -1, e = Array(n); ++r < n;) e[r] = t(r);
|
|
return e
|
|
}
|
|
|
|
function m(n, t) {
|
|
return a(t, function(t) {
|
|
return [t, n[t]]
|
|
})
|
|
}
|
|
|
|
function w(n) {
|
|
return function(t) {
|
|
return n(t)
|
|
}
|
|
}
|
|
|
|
function A(n, t) {
|
|
return a(t, function(t) {
|
|
return n[t]
|
|
})
|
|
}
|
|
|
|
function O(n, t) {
|
|
for (var r = -1, e = n.length; ++r < e && -1 < d(t, n[r], 0););
|
|
return r
|
|
}
|
|
|
|
function k(n, t) {
|
|
for (var r = n.length; r-- && -1 < d(t, n[r], 0););
|
|
return r
|
|
}
|
|
|
|
function E(n) {
|
|
return n && n.Object === Object ? n : null
|
|
}
|
|
|
|
function I(n, t) {
|
|
if (n !== t) {
|
|
var r = null === n,
|
|
e = n === Z,
|
|
u = n === n,
|
|
o = null === t,
|
|
i = t === Z,
|
|
f = t === t;
|
|
if (n > t && !o || !u || r && !i && f || e && f) return 1;
|
|
if (t > n && !r || !f || o && !e && u || i && u) return -1
|
|
}
|
|
return 0
|
|
}
|
|
|
|
function S(n) {
|
|
return Un[n]
|
|
}
|
|
|
|
function R(n) {
|
|
return zn[n]
|
|
}
|
|
|
|
function W(n) {
|
|
return "\\" + $n[n]
|
|
}
|
|
|
|
function B(n, t, r) {
|
|
var e = n.length;
|
|
for (t += r ? 0 : -1; r ? t-- : ++t < e;) {
|
|
var u = n[t];
|
|
if (u !== u) return t
|
|
}
|
|
return -1
|
|
}
|
|
|
|
function C(n) {
|
|
var t = !1;
|
|
if (null != n && "function" != typeof n.toString) try {
|
|
t = !!(n + "")
|
|
} catch (r) {}
|
|
return t
|
|
}
|
|
|
|
function U(n, t) {
|
|
return n = "number" == typeof n || yn.test(n) ? +n : -1, n > -1 && 0 == n % 1 && (null == t ? 9007199254740991 : t) > n
|
|
}
|
|
|
|
function z(n) {
|
|
for (var t, r = []; !(t = n.next()).done;) r.push(t.value);
|
|
return r
|
|
}
|
|
|
|
function M(n) {
|
|
var t = -1,
|
|
r = Array(n.size);
|
|
return n.forEach(function(n, e) {
|
|
r[++t] = [e, n]
|
|
}), r
|
|
}
|
|
|
|
function L(n, t) {
|
|
for (var r = -1, e = n.length, u = -1, o = []; ++r < e;) n[r] === t && (n[r] = "__lodash_placeholder__", o[++u] = r);
|
|
return o
|
|
}
|
|
|
|
function $(n) {
|
|
var t = -1,
|
|
r = Array(n.size);
|
|
return n.forEach(function(n) {
|
|
r[++t] = n
|
|
}), r
|
|
}
|
|
|
|
function F(n) {
|
|
if (!n || !En.test(n)) return n.length;
|
|
for (var t = kn.lastIndex = 0; kn.test(n);) t++;
|
|
return t
|
|
}
|
|
|
|
function N(n) {
|
|
return Mn[n]
|
|
}
|
|
|
|
function D(E) {
|
|
function yn(n) {
|
|
if (je(n) && !No(n) && !(n instanceof An)) {
|
|
if (n instanceof wn) return n;
|
|
if (cu.call(n, "__wrapped__")) return Zr(n)
|
|
}
|
|
return new wn(n)
|
|
}
|
|
|
|
function mn() {}
|
|
|
|
function wn(n, t) {
|
|
this.__wrapped__ = n, this.__actions__ = [], this.__chain__ = !!t, this.__index__ = 0, this.__values__ = Z
|
|
}
|
|
|
|
function An(n) {
|
|
this.__wrapped__ = n, this.__actions__ = [], this.__dir__ = 1, this.__filtered__ = !1, this.__iteratees__ = [], this.__takeCount__ = 4294967295, this.__views__ = []
|
|
}
|
|
|
|
function Un() {}
|
|
|
|
function zn(n) {
|
|
var t = -1,
|
|
r = n ? n.length : 0;
|
|
for (this.clear(); ++t < r;) {
|
|
var e = n[t];
|
|
this.set(e[0], e[1])
|
|
}
|
|
}
|
|
|
|
function Mn(n) {
|
|
var t = -1,
|
|
r = n ? n.length : 0;
|
|
for (this.__data__ = new zn; ++t < r;) this.push(n[t])
|
|
}
|
|
|
|
function Ln(n, t) {
|
|
var r = n.__data__;
|
|
return Ur(t) ? (r = r.__data__, "__lodash_hash_undefined__" === ("string" == typeof t ? r.string : r.hash)[t]) : r.has(t)
|
|
}
|
|
|
|
function $n(n) {
|
|
var t = -1,
|
|
r = n ? n.length : 0;
|
|
for (this.clear(); ++t < r;) {
|
|
var e = n[t];
|
|
this.set(e[0], e[1])
|
|
}
|
|
}
|
|
|
|
function Dn(n, t) {
|
|
var r = qn(n, t);
|
|
return !(0 > r) && (r == n.length - 1 ? n.pop() : Ou.call(n, r, 1), !0)
|
|
}
|
|
|
|
function Zn(n, t) {
|
|
var r = qn(n, t);
|
|
return 0 > r ? Z : n[r][1]
|
|
}
|
|
|
|
function qn(n, t) {
|
|
for (var r = n.length; r--;)
|
|
if (se(n[r][0], t)) return r;
|
|
return -1
|
|
}
|
|
|
|
function Pn(n, t, r) {
|
|
var e = qn(n, t);
|
|
0 > e ? n.push([t, r]) : n[e][1] = r
|
|
}
|
|
|
|
function Tn(n, t, r, e) {
|
|
return n === Z || se(n, iu[r]) && !cu.call(e, r) ? t : n
|
|
}
|
|
|
|
function Gn(n, t, r) {
|
|
(r !== Z && !se(n[t], r) || "number" == typeof t && r === Z && !(t in n)) && (n[t] = r)
|
|
}
|
|
|
|
function Yn(n, t, r) {
|
|
var e = n[t];
|
|
(!se(e, r) || se(e, iu[t]) && !cu.call(n, t) || r === Z && !(t in n)) && (n[t] = r)
|
|
}
|
|
|
|
function Hn(n, t, r, e) {
|
|
return Ju(n, function(n, u, o) {
|
|
t(e, n, r(n), o)
|
|
}), e
|
|
}
|
|
|
|
function Qn(n, t) {
|
|
return n && Ht(t, Fe(t), n)
|
|
}
|
|
|
|
function Xn(n, t) {
|
|
for (var r = -1, e = null == n, u = t.length, o = Array(u); ++r < u;) o[r] = e ? Z : Me(n, t[r]);
|
|
return o
|
|
}
|
|
|
|
function nt(n, t, r) {
|
|
return n === n && (r !== Z && (n = n > r ? r : n), t !== Z && (n = t > n ? t : n)), n
|
|
}
|
|
|
|
function tt(n, t, r, e, o, i) {
|
|
var f;
|
|
if (r && (f = o ? r(n, e, o, i) : r(n)), f !== Z) return f;
|
|
if (!xe(n)) return n;
|
|
if (e = No(n)) {
|
|
if (f = Ir(n), !t) return Yt(n, f)
|
|
} else {
|
|
var c = kr(n),
|
|
a = "[object Function]" == c || "[object GeneratorFunction]" == c;
|
|
if (Do(n)) return Kt(n, t);
|
|
if ("[object Object]" != c && "[object Arguments]" != c && (!a || o)) return Cn[c] ? Rr(n, c, t) : o ? n : {};
|
|
if (C(n)) return o ? n : {};
|
|
if (f = Sr(a ? {} : n), !t) return Xt(n, Qn(f, n))
|
|
}
|
|
return i || (i = new $n), (o = i.get(n)) ? o : (i.set(n, f), (e ? u : at)(n, function(e, u) {
|
|
Yn(f, u, tt(e, t, r, u, n, i))
|
|
}), e ? f : Xt(n, f))
|
|
}
|
|
|
|
function rt(n) {
|
|
var t = Fe(n),
|
|
r = t.length;
|
|
return function(e) {
|
|
if (null == e) return !r;
|
|
for (var u = r; u--;) {
|
|
var o = t[u],
|
|
i = n[o],
|
|
f = e[o];
|
|
if (f === Z && !(o in Object(e)) || !i(f)) return !1
|
|
}
|
|
return !0
|
|
}
|
|
}
|
|
|
|
function et(n, t, r) {
|
|
if ("function" != typeof n) throw new uu("Expected a function");
|
|
return Au(function() {
|
|
n.apply(Z, r)
|
|
}, t)
|
|
}
|
|
|
|
function ut(n, t, r, e) {
|
|
var u = -1,
|
|
o = f,
|
|
i = !0,
|
|
l = n.length,
|
|
s = [],
|
|
h = t.length;
|
|
if (!l) return s;
|
|
r && (t = a(t, w(r))), e ? (o = c, i = !1) : t.length >= 200 && (o = Ln, i = !1, t = new Mn(t));
|
|
n: for (; ++u < l;) {
|
|
var p = n[u],
|
|
_ = r ? r(p) : p;
|
|
if (i && _ === _) {
|
|
for (var g = h; g--;)
|
|
if (t[g] === _) continue n;
|
|
s.push(p)
|
|
} else o(t, _, e) || s.push(p)
|
|
}
|
|
return s
|
|
}
|
|
|
|
function ot(n, t) {
|
|
var r = !0;
|
|
return Ju(n, function(n, e, u) {
|
|
return r = !!t(n, e, u)
|
|
}), r
|
|
}
|
|
|
|
function it(n, t) {
|
|
var r = [];
|
|
return Ju(n, function(n, e, u) {
|
|
t(n, e, u) && r.push(n)
|
|
}), r
|
|
}
|
|
|
|
function ft(n, t, r, e) {
|
|
e || (e = []);
|
|
for (var u = -1, o = n.length; ++u < o;) {
|
|
var i = n[u];
|
|
ge(i) && (r || No(i) || pe(i)) ? t ? ft(i, t, r, e) : l(e, i) : r || (e[e.length] = i)
|
|
}
|
|
return e
|
|
}
|
|
|
|
function ct(n, t) {
|
|
return null == n ? n : Hu(n, t, Ne)
|
|
}
|
|
|
|
function at(n, t) {
|
|
return n && Hu(n, t, Fe)
|
|
}
|
|
|
|
function lt(n, t) {
|
|
return n && Qu(n, t, Fe)
|
|
}
|
|
|
|
function st(n, t) {
|
|
return i(t, function(t) {
|
|
return de(n[t])
|
|
})
|
|
}
|
|
|
|
function ht(n, t) {
|
|
t = Cr(t, n) ? [t + ""] : Nt(t);
|
|
for (var r = 0, e = t.length; null != n && e > r;) n = n[t[r++]];
|
|
return r && r == e ? n : Z
|
|
}
|
|
|
|
function pt(n, t) {
|
|
return cu.call(n, t) || "object" == typeof n && t in n && null === xu(n)
|
|
}
|
|
|
|
function _t(n, t) {
|
|
return t in Object(n)
|
|
}
|
|
|
|
function gt(n, t, r) {
|
|
for (var e = r ? c : f, u = n.length, o = u, i = Array(u), l = []; o--;) {
|
|
var s = n[o];
|
|
o && t && (s = a(s, w(t))), i[o] = r || !t && 120 > s.length ? Z : new Mn(o && s)
|
|
}
|
|
var s = n[0],
|
|
h = -1,
|
|
p = s.length,
|
|
_ = i[0];
|
|
n: for (; ++h < p;) {
|
|
var g = s[h],
|
|
v = t ? t(g) : g;
|
|
if (_ ? !Ln(_, v) : !e(l, v, r)) {
|
|
for (o = u; --o;) {
|
|
var d = i[o];
|
|
if (d ? !Ln(d, v) : !e(n[o], v, r)) continue n
|
|
}
|
|
_ && _.push(v), l.push(g)
|
|
}
|
|
}
|
|
return l
|
|
}
|
|
|
|
function vt(n, t, r, e) {
|
|
return at(n, function(n, u, o) {
|
|
t(e, r(n), u, o)
|
|
}), e
|
|
}
|
|
|
|
function dt(n, t, e) {
|
|
return Cr(t, n) || (t = Nt(t), n = $r(n, t), t = Kr(t)), t = null == n ? n : n[t], null == t ? Z : r(t, n, e)
|
|
}
|
|
|
|
function yt(n, t, r, e, u) {
|
|
if (n === t) return !0;
|
|
if (null == n || null == t || !xe(n) && !je(t)) return n !== n && t !== t;
|
|
n: {
|
|
var o = No(n),
|
|
i = No(t),
|
|
f = "[object Array]",
|
|
c = "[object Array]";o || (f = kr(n), "[object Arguments]" == f ? f = "[object Object]" : "[object Object]" != f && (o = Ie(n))),
|
|
i || (c = kr(t), "[object Arguments]" == c ? c = "[object Object]" : "[object Object]" != c && Ie(t));
|
|
var a = "[object Object]" == f && !C(n),
|
|
i = "[object Object]" == c && !C(t),
|
|
c = f == c;
|
|
if (!c || o || a) {
|
|
if (!(2 & e) && (f = a && cu.call(n, "__wrapped__"), i = i && cu.call(t, "__wrapped__"), f || i)) {
|
|
n = yt(f ? n.value() : n, i ? t.value() : t, r, e, u);
|
|
break n
|
|
}
|
|
c ? (u || (u = new $n), n = (o ? br : jr)(n, t, yt, r, e, u)) : n = !1
|
|
} else n = xr(n, t, f, yt, r, e)
|
|
}
|
|
return n
|
|
}
|
|
|
|
function bt(n, t, r, e) {
|
|
var u = r.length,
|
|
o = u,
|
|
i = !e;
|
|
if (null == n) return !o;
|
|
for (n = Object(n); u--;) {
|
|
var f = r[u];
|
|
if (i && f[2] ? f[1] !== n[f[0]] : !(f[0] in n)) return !1
|
|
}
|
|
for (; ++u < o;) {
|
|
var f = r[u],
|
|
c = f[0],
|
|
a = n[c],
|
|
l = f[1];
|
|
if (i && f[2]) {
|
|
if (a === Z && !(c in n)) return !1
|
|
} else if (f = new $n, c = e ? e(a, l, c, n, t, f) : Z, c === Z ? !yt(l, a, e, 3, f) : !c) return !1
|
|
}
|
|
return !0
|
|
}
|
|
|
|
function xt(n) {
|
|
var t = typeof n;
|
|
return "function" == t ? n : null == n ? Ve : "object" == t ? No(n) ? At(n[0], n[1]) : wt(n) : Qe(n)
|
|
}
|
|
|
|
function jt(n) {
|
|
n = null == n ? n : Object(n);
|
|
var t, r = [];
|
|
for (t in n) r.push(t);
|
|
return r
|
|
}
|
|
|
|
function mt(n, t) {
|
|
var r = -1,
|
|
e = _e(n) ? Array(n.length) : [];
|
|
return Ju(n, function(n, u, o) {
|
|
e[++r] = t(n, u, o)
|
|
}), e
|
|
}
|
|
|
|
function wt(n) {
|
|
var t = Ar(n);
|
|
if (1 == t.length && t[0][2]) {
|
|
var r = t[0][0],
|
|
e = t[0][1];
|
|
return function(n) {
|
|
return null != n && (n[r] === e && (e !== Z || r in Object(n)))
|
|
}
|
|
}
|
|
return function(r) {
|
|
return r === n || bt(r, n, t)
|
|
}
|
|
}
|
|
|
|
function At(n, t) {
|
|
return function(r) {
|
|
var e = Me(r, n);
|
|
return e === Z && e === t ? $e(r, n) : yt(t, e, Z, 3)
|
|
}
|
|
}
|
|
|
|
function Ot(n, t, r, e, o) {
|
|
if (n !== t) {
|
|
var i = No(t) || Ie(t) ? Z : Ne(t);
|
|
u(i || t, function(u, f) {
|
|
if (i && (f = u, u = t[f]), xe(u)) {
|
|
o || (o = new $n);
|
|
var c = f,
|
|
a = o,
|
|
l = n[c],
|
|
s = t[c],
|
|
h = a.get(s);
|
|
if (!h) {
|
|
var h = e ? e(l, s, c + "", n, t, a) : Z,
|
|
p = h === Z;
|
|
p && (h = s, No(s) || Ie(s) ? No(l) ? h = r ? Yt(l) : l : ge(l) ? h = Yt(l) : (p = !1, h = tt(s)) : Ae(s) || pe(s) ? pe(l) ? h = Ue(l) : !xe(l) || r && de(l) ? (p = !1, h = tt(s)) : h = r ? tt(l) : l : p = !1), a.set(s, h), p && Ot(h, s, r, e, a)
|
|
}
|
|
Gn(n, c, h)
|
|
} else c = e ? e(n[f], u, f + "", n, t, o) : Z, c === Z && (c = u), Gn(n, f, c)
|
|
})
|
|
}
|
|
}
|
|
|
|
function kt(n, t, r) {
|
|
var e = -1,
|
|
u = wr();
|
|
return t = a(t.length ? t : Array(1), function(n) {
|
|
return u(n)
|
|
}), n = mt(n, function(n, r, u) {
|
|
return {
|
|
a: a(t, function(t) {
|
|
return t(n)
|
|
}),
|
|
b: ++e,
|
|
c: n
|
|
}
|
|
}), b(n, function(n, t) {
|
|
var e;
|
|
n: {
|
|
e = -1;
|
|
for (var u = n.a, o = t.a, i = u.length, f = r.length; ++e < i;) {
|
|
var c = I(u[e], o[e]);
|
|
if (c) {
|
|
if (e >= f) {
|
|
e = c;
|
|
break n
|
|
}
|
|
e = c * ("desc" == r[e] ? -1 : 1);
|
|
break n
|
|
}
|
|
}
|
|
e = n.b - t.b
|
|
}
|
|
return e
|
|
})
|
|
}
|
|
|
|
function Et(n, t) {
|
|
return n = Object(n), s(t, function(t, r) {
|
|
return r in n && (t[r] = n[r]), t
|
|
}, {})
|
|
}
|
|
|
|
function It(n, t) {
|
|
var r = {};
|
|
return ct(n, function(n, e) {
|
|
t(n, e) && (r[e] = n)
|
|
}), r
|
|
}
|
|
|
|
function St(n) {
|
|
return function(t) {
|
|
return null == t ? Z : t[n]
|
|
}
|
|
}
|
|
|
|
function Rt(n) {
|
|
return function(t) {
|
|
return ht(t, n)
|
|
}
|
|
}
|
|
|
|
function Wt(n, t, r) {
|
|
var e = -1,
|
|
u = t.length,
|
|
o = n;
|
|
for (r && (o = a(n, function(n) {
|
|
return r(n)
|
|
})); ++e < u;)
|
|
for (var i = 0, f = t[e], f = r ? r(f) : f; - 1 < (i = d(o, f, i));) o !== n && Ou.call(o, i, 1), Ou.call(n, i, 1);
|
|
return n
|
|
}
|
|
|
|
function Bt(n, t) {
|
|
for (var r = n ? t.length : 0, e = r - 1; r--;) {
|
|
var u = t[r];
|
|
if (e == r || u != o) {
|
|
var o = u;
|
|
if (U(u)) Ou.call(n, u, 1);
|
|
else if (Cr(u, n)) delete n[u];
|
|
else {
|
|
var u = Nt(u),
|
|
i = $r(n, u);
|
|
null != i && delete i[Kr(u)]
|
|
}
|
|
}
|
|
}
|
|
return n
|
|
}
|
|
|
|
function Ct(n, t) {
|
|
return n + Eu(Uu() * (t - n + 1))
|
|
}
|
|
|
|
function Ut(n, t, r, e) {
|
|
t = Cr(t, n) ? [t + ""] : Nt(t);
|
|
for (var u = -1, o = t.length, i = o - 1, f = n; null != f && ++u < o;) {
|
|
var c = t[u];
|
|
if (xe(f)) {
|
|
var a = r;
|
|
if (u != i) {
|
|
var l = f[c],
|
|
a = e ? e(l, c, f) : Z;
|
|
a === Z && (a = null == l ? U(t[u + 1]) ? [] : {} : l)
|
|
}
|
|
Yn(f, c, a)
|
|
}
|
|
f = f[c]
|
|
}
|
|
return n
|
|
}
|
|
|
|
function zt(n, t, r) {
|
|
var e = -1,
|
|
u = n.length;
|
|
for (0 > t && (t = -t > u ? 0 : u + t), r = r > u ? u : r, 0 > r && (r += u), u = t > r ? 0 : r - t >>> 0, t >>>= 0, r = Array(u); ++e < u;) r[e] = n[e + t];
|
|
return r
|
|
}
|
|
|
|
function Mt(n, t) {
|
|
var r;
|
|
return Ju(n, function(n, e, u) {
|
|
return r = t(n, e, u), !r
|
|
}), !!r
|
|
}
|
|
|
|
function Lt(n, t, r) {
|
|
var e = 0,
|
|
u = n ? n.length : e;
|
|
if ("number" == typeof t && t === t && 2147483647 >= u) {
|
|
for (; u > e;) {
|
|
var o = e + u >>> 1,
|
|
i = n[o];
|
|
(r ? t >= i : t > i) && null !== i ? e = o + 1 : u = o
|
|
}
|
|
return u
|
|
}
|
|
return $t(n, t, Ve, r)
|
|
}
|
|
|
|
function $t(n, t, r, e) {
|
|
t = r(t);
|
|
for (var u = 0, o = n ? n.length : 0, i = t !== t, f = null === t, c = t === Z; o > u;) {
|
|
var a = Eu((u + o) / 2),
|
|
l = r(n[a]),
|
|
s = l !== Z,
|
|
h = l === l;
|
|
(i ? h || e : f ? h && s && (e || null != l) : c ? h && (e || s) : null == l ? 0 : e ? t >= l : t > l) ? u = a + 1: o = a
|
|
}
|
|
return Bu(o, 4294967294)
|
|
}
|
|
|
|
function Ft(n, t) {
|
|
for (var r = 0, e = n.length, u = n[0], o = t ? t(u) : u, i = o, f = 0, c = [u]; ++r < e;) u = n[r], o = t ? t(u) : u, se(o, i) || (i = o, c[++f] = u);
|
|
return c
|
|
}
|
|
|
|
function Nt(n) {
|
|
return No(n) ? n : Fr(n)
|
|
}
|
|
|
|
function Dt(n, t, r) {
|
|
var e = -1,
|
|
u = f,
|
|
o = n.length,
|
|
i = !0,
|
|
a = [],
|
|
l = a;
|
|
if (r) i = !1, u = c;
|
|
else if (o < 200) l = t ? [] : a;
|
|
else {
|
|
if (u = t ? null : no(n)) return $(u);
|
|
i = !1, u = Ln, l = new Mn
|
|
}
|
|
n: for (; ++e < o;) {
|
|
var s = n[e],
|
|
h = t ? t(s) : s;
|
|
if (i && h === h) {
|
|
for (var p = l.length; p--;)
|
|
if (l[p] === h) continue n;
|
|
t && l.push(h), a.push(s)
|
|
} else u(l, h, r) || (l !== a && l.push(h), a.push(s))
|
|
}
|
|
return a
|
|
}
|
|
|
|
function Zt(n, t, r, e) {
|
|
for (var u = n.length, o = e ? u : -1;
|
|
(e ? o-- : ++o < u) && t(n[o], o, n););
|
|
return r ? zt(n, e ? 0 : o, e ? o + 1 : u) : zt(n, e ? o + 1 : 0, e ? u : o)
|
|
}
|
|
|
|
function qt(n, t) {
|
|
var r = n;
|
|
return r instanceof An && (r = r.value()), s(t, function(n, t) {
|
|
return t.func.apply(t.thisArg, l([n], t.args))
|
|
}, r)
|
|
}
|
|
|
|
function Pt(n, t, r) {
|
|
for (var e = -1, u = n.length; ++e < u;) var o = o ? l(ut(o, n[e], t, r), ut(n[e], o, t, r)) : n[e];
|
|
return o && o.length ? Dt(o, t, r) : []
|
|
}
|
|
|
|
function Tt(n, t, r) {
|
|
for (var e = -1, u = n.length, o = t.length, i = {}; ++e < u;) r(i, n[e], o > e ? t[e] : Z);
|
|
return i
|
|
}
|
|
|
|
function Kt(n, t) {
|
|
if (t) return n.slice();
|
|
var r = new n.constructor(n.length);
|
|
return n.copy(r), r
|
|
}
|
|
|
|
function Gt(n) {
|
|
var t = new n.constructor(n.byteLength);
|
|
return new du(t).set(new du(n)), t
|
|
}
|
|
|
|
function Vt(n, t, r) {
|
|
for (var e = r.length, u = -1, o = Wu(n.length - e, 0), i = -1, f = t.length, c = Array(f + o); ++i < f;) c[i] = t[i];
|
|
for (; ++u < e;) c[r[u]] = n[u];
|
|
for (; o--;) c[i++] = n[u++];
|
|
return c
|
|
}
|
|
|
|
function Jt(n, t, r) {
|
|
for (var e = -1, u = r.length, o = -1, i = Wu(n.length - u, 0), f = -1, c = t.length, a = Array(i + c); ++o < i;) a[o] = n[o];
|
|
for (i = o; ++f < c;) a[i + f] = t[f];
|
|
for (; ++e < u;) a[i + r[e]] = n[o++];
|
|
return a
|
|
}
|
|
|
|
function Yt(n, t) {
|
|
var r = -1,
|
|
e = n.length;
|
|
for (t || (t = Array(e)); ++r < e;) t[r] = n[r];
|
|
return t
|
|
}
|
|
|
|
function Ht(n, t, r) {
|
|
return Qt(n, t, r)
|
|
}
|
|
|
|
function Qt(n, t, r, e) {
|
|
r || (r = {});
|
|
for (var u = -1, o = t.length; ++u < o;) {
|
|
var i = t[u],
|
|
f = e ? e(r[i], n[i], i, r, n) : n[i];
|
|
Yn(r, i, f)
|
|
}
|
|
return r
|
|
}
|
|
|
|
function Xt(n, t) {
|
|
return Ht(n, eo(n), t)
|
|
}
|
|
|
|
function nr(n, t) {
|
|
return function(r, u) {
|
|
var o = No(r) ? e : Hn,
|
|
i = t ? t() : {};
|
|
return o(r, n, wr(u), i)
|
|
}
|
|
}
|
|
|
|
function tr(n) {
|
|
return le(function(t, r) {
|
|
var e = -1,
|
|
u = r.length,
|
|
o = u > 1 ? r[u - 1] : Z,
|
|
i = u > 2 ? r[2] : Z,
|
|
o = "function" == typeof o ? (u--, o) : Z;
|
|
for (i && Br(r[0], r[1], i) && (o = 3 > u ? Z : o, u = 1), t = Object(t); ++e < u;)(i = r[e]) && n(t, i, e, o);
|
|
return t
|
|
})
|
|
}
|
|
|
|
function rr(n, t) {
|
|
return function(r, e) {
|
|
if (null == r) return r;
|
|
if (!_e(r)) return n(r, e);
|
|
for (var u = r.length, o = t ? u : -1, i = Object(r);
|
|
(t ? o-- : ++o < u) && !1 !== e(i[o], o, i););
|
|
return r
|
|
}
|
|
}
|
|
|
|
function er(n) {
|
|
return function(t, r, e) {
|
|
var u = -1,
|
|
o = Object(t);
|
|
e = e(t);
|
|
for (var i = e.length; i--;) {
|
|
var f = e[n ? i : ++u];
|
|
if (!1 === r(o[f], f, o)) break
|
|
}
|
|
return t
|
|
}
|
|
}
|
|
|
|
function ur(n, t, r) {
|
|
function e() {
|
|
return (this && this !== Vn && this instanceof e ? o : n).apply(u ? r : this, arguments)
|
|
}
|
|
var u = 1 & t,
|
|
o = fr(n);
|
|
return e
|
|
}
|
|
|
|
function or(n) {
|
|
return function(t) {
|
|
t = ze(t);
|
|
var r = En.test(t) ? t.match(kn) : Z,
|
|
e = r ? r[0] : t.charAt(0);
|
|
return t = r ? r.slice(1).join("") : t.slice(1), e[n]() + t
|
|
}
|
|
}
|
|
|
|
function ir(n) {
|
|
return function(t) {
|
|
return s(Ke(Pe(t)), n, "")
|
|
}
|
|
}
|
|
|
|
function fr(n) {
|
|
return function() {
|
|
var t = arguments;
|
|
switch (t.length) {
|
|
case 0:
|
|
return new n;
|
|
case 1:
|
|
return new n(t[0]);
|
|
case 2:
|
|
return new n(t[0], t[1]);
|
|
case 3:
|
|
return new n(t[0], t[1], t[2]);
|
|
case 4:
|
|
return new n(t[0], t[1], t[2], t[3]);
|
|
case 5:
|
|
return new n(t[0], t[1], t[2], t[3], t[4]);
|
|
case 6:
|
|
return new n(t[0], t[1], t[2], t[3], t[4], t[5]);
|
|
case 7:
|
|
return new n(t[0], t[1], t[2], t[3], t[4], t[5], t[6])
|
|
}
|
|
var r = Vu(n.prototype),
|
|
t = n.apply(r, t);
|
|
return xe(t) ? t : r
|
|
}
|
|
}
|
|
|
|
function cr(n, t, e) {
|
|
function u() {
|
|
for (var i = arguments.length, f = i, c = Array(i), a = this && this !== Vn && this instanceof u ? o : n, l = yn.placeholder || u.placeholder; f--;) c[f] = arguments[f];
|
|
return f = 3 > i && c[0] !== l && c[i - 1] !== l ? [] : L(c, l), i -= f.length, e > i ? vr(n, t, lr, l, Z, c, f, Z, Z, e - i) : r(a, this, c)
|
|
}
|
|
var o = fr(n);
|
|
return u
|
|
}
|
|
|
|
function ar(n) {
|
|
return le(function(t) {
|
|
t = ft(t);
|
|
var r = t.length,
|
|
e = r,
|
|
u = wn.prototype.thru;
|
|
for (n && t.reverse(); e--;) {
|
|
var o = t[e];
|
|
if ("function" != typeof o) throw new uu("Expected a function");
|
|
if (u && !i && "wrapper" == mr(o)) var i = new wn([], (!0))
|
|
}
|
|
for (e = i ? e : r; ++e < r;) var o = t[e],
|
|
u = mr(o),
|
|
f = "wrapper" == u ? to(o) : Z,
|
|
i = f && zr(f[0]) && 424 == f[1] && !f[4].length && 1 == f[9] ? i[mr(f[0])].apply(i, f[3]) : 1 == o.length && zr(o) ? i[u]() : i.thru(o);
|
|
return function() {
|
|
var n = arguments,
|
|
e = n[0];
|
|
if (i && 1 == n.length && No(e) && e.length >= 200) return i.plant(e).value();
|
|
for (var u = 0, n = r ? t[u].apply(this, n) : e; ++u < r;) n = t[u].call(this, n);
|
|
return n
|
|
}
|
|
})
|
|
}
|
|
|
|
function lr(n, t, r, e, u, o, i, f, c, a) {
|
|
function l() {
|
|
for (var y = arguments.length, b = y, x = Array(y); b--;) x[b] = arguments[b];
|
|
if (e && (x = Vt(x, e, u)), o && (x = Jt(x, o, i)), _ || g) {
|
|
var b = yn.placeholder || l.placeholder,
|
|
j = L(x, b),
|
|
y = y - j.length;
|
|
if (a > y) return vr(n, t, lr, b, r, x, j, f, c, a - y)
|
|
}
|
|
if (y = h ? r : this, b = p ? y[n] : n, f)
|
|
for (var j = x.length, m = Bu(f.length, j), w = Yt(x); m--;) {
|
|
var A = f[m];
|
|
x[m] = U(A, j) ? w[A] : Z
|
|
} else v && x.length > 1 && x.reverse();
|
|
return s && x.length > c && (x.length = c), this && this !== Vn && this instanceof l && (b = d || fr(b)), b.apply(y, x)
|
|
}
|
|
var s = 128 & t,
|
|
h = 1 & t,
|
|
p = 2 & t,
|
|
_ = 8 & t,
|
|
g = 16 & t,
|
|
v = 512 & t,
|
|
d = p ? Z : fr(n);
|
|
return l
|
|
}
|
|
|
|
function sr(n, t) {
|
|
return function(r, e) {
|
|
return vt(r, n, t(e), {})
|
|
}
|
|
}
|
|
|
|
function hr(n) {
|
|
return le(function(t) {
|
|
return t = a(ft(t), wr()), le(function(e) {
|
|
var u = this;
|
|
return n(t, function(n) {
|
|
return r(n, u, e)
|
|
})
|
|
})
|
|
})
|
|
}
|
|
|
|
function pr(n, t, r) {
|
|
return t = We(t), n = F(n), t && t > n ? (t -= n, r = r === Z ? " " : r + "", n = Te(r, ku(t / F(r))), En.test(r) ? n.match(kn).slice(0, t).join("") : n.slice(0, t)) : ""
|
|
}
|
|
|
|
function _r(n, t, e, u) {
|
|
function o() {
|
|
for (var t = -1, c = arguments.length, a = -1, l = u.length, s = Array(l + c), h = this && this !== Vn && this instanceof o ? f : n; ++a < l;) s[a] = u[a];
|
|
for (; c--;) s[a++] = arguments[++t];
|
|
return r(h, i ? e : this, s)
|
|
}
|
|
var i = 1 & t,
|
|
f = fr(n);
|
|
return o
|
|
}
|
|
|
|
function gr(n) {
|
|
return function(t, r, e) {
|
|
e && "number" != typeof e && Br(t, r, e) && (r = e = Z), t = Ce(t), t = t === t ? t : 0, r === Z ? (r = t, t = 0) : r = Ce(r) || 0, e = e === Z ? r > t ? 1 : -1 : Ce(e) || 0;
|
|
var u = -1;
|
|
r = Wu(ku((r - t) / (e || 1)), 0);
|
|
for (var o = Array(r); r--;) o[n ? r : ++u] = t, t += e;
|
|
return o
|
|
}
|
|
}
|
|
|
|
function vr(n, t, r, e, u, o, i, f, c, a) {
|
|
var l = 8 & t;
|
|
f = f ? Yt(f) : Z;
|
|
var s = l ? i : Z;
|
|
i = l ? Z : i;
|
|
var h = l ? o : Z;
|
|
return o = l ? Z : o, t = (t | (l ? 32 : 64)) & ~(l ? 64 : 32), 4 & t || (t &= -4), t = [n, t, u, h, s, o, i, f, c, a], r = r.apply(Z, t), zr(n) && uo(r, t), r.placeholder = e, r
|
|
}
|
|
|
|
function dr(n) {
|
|
var t = ru[n];
|
|
return function(n, r) {
|
|
if (n = Ce(n), r = We(r)) {
|
|
var e = (ze(n) + "e").split("e"),
|
|
e = t(e[0] + "e" + (+e[1] + r)),
|
|
e = (ze(e) + "e").split("e");
|
|
return +(e[0] + "e" + (+e[1] - r))
|
|
}
|
|
return t(n)
|
|
}
|
|
}
|
|
|
|
function yr(n, t, r, e, u, o, i, f) {
|
|
var c = 2 & t;
|
|
if (!c && "function" != typeof n) throw new uu("Expected a function");
|
|
var a = e ? e.length : 0;
|
|
if (a || (t &= -97, e = u = Z), i = i === Z ? i : Wu(We(i), 0), f = f === Z ? f : We(f), a -= u ? u.length : 0, 64 & t) {
|
|
var l = e,
|
|
s = u;
|
|
e = u = Z
|
|
}
|
|
var h = c ? Z : to(n);
|
|
return o = [n, t, r, e, u, l, s, o, i, f], h && (r = o[1], n = h[1], t = r | n, e = 128 == n && 8 == r || 128 == n && 256 == r && h[8] >= o[7].length || 384 == n && h[8] >= h[7].length && 8 == r, 131 > t || e) && (1 & n && (o[2] = h[2], t |= 1 & r ? 0 : 4), (r = h[3]) && (e = o[3], o[3] = e ? Vt(e, r, h[4]) : Yt(r), o[4] = e ? L(o[3], "__lodash_placeholder__") : Yt(h[4])), (r = h[5]) && (e = o[5], o[5] = e ? Jt(e, r, h[6]) : Yt(r), o[6] = e ? L(o[5], "__lodash_placeholder__") : Yt(h[6])), (r = h[7]) && (o[7] = Yt(r)), 128 & n && (o[8] = null == o[8] ? h[8] : Bu(o[8], h[8])), null == o[9] && (o[9] = h[9]), o[0] = h[0], o[1] = t), n = o[0], t = o[1], r = o[2], e = o[3], u = o[4], f = o[9] = null == o[9] ? c ? 0 : n.length : Wu(o[9] - a, 0), !f && 24 & t && (t &= -25), c = t && 1 != t ? 8 == t || 16 == t ? cr(n, t, f) : 32 != t && 33 != t || u.length ? lr.apply(Z, o) : _r(n, t, r, e) : ur(n, t, r), (h ? Xu : uo)(c, o)
|
|
}
|
|
|
|
function br(n, t, r, e, u, o) {
|
|
var i = -1,
|
|
f = 2 & u,
|
|
c = 1 & u,
|
|
a = n.length,
|
|
l = t.length;
|
|
if (!(a == l || f && l > a)) return !1;
|
|
if (l = o.get(n)) return l == t;
|
|
for (l = !0, o.set(n, t); ++i < a;) {
|
|
var s = n[i],
|
|
h = t[i];
|
|
if (e) var _ = f ? e(h, s, i, t, n, o) : e(s, h, i, n, t, o);
|
|
if (_ !== Z) {
|
|
if (_) continue;
|
|
l = !1;
|
|
break
|
|
}
|
|
if (c) {
|
|
if (!p(t, function(n) {
|
|
return s === n || r(s, n, e, u, o)
|
|
})) {
|
|
l = !1;
|
|
break
|
|
}
|
|
} else if (s !== h && !r(s, h, e, u, o)) {
|
|
l = !1;
|
|
break
|
|
}
|
|
}
|
|
return o["delete"](n), l
|
|
}
|
|
|
|
function xr(n, t, r, e, u, o) {
|
|
switch (r) {
|
|
case "[object ArrayBuffer]":
|
|
if (n.byteLength != t.byteLength || !e(new du(n), new du(t))) break;
|
|
return !0;
|
|
case "[object Boolean]":
|
|
case "[object Date]":
|
|
return +n == +t;
|
|
case "[object Error]":
|
|
return n.name == t.name && n.message == t.message;
|
|
case "[object Number]":
|
|
return n != +n ? t != +t : n == +t;
|
|
case "[object RegExp]":
|
|
case "[object String]":
|
|
return n == t + "";
|
|
case "[object Map]":
|
|
var i = M;
|
|
case "[object Set]":
|
|
return i || (i = $), (2 & o || n.size == t.size) && e(i(n), i(t), u, 1 | o);
|
|
case "[object Symbol]":
|
|
return !!vu && Tu.call(n) == Tu.call(t)
|
|
}
|
|
return !1
|
|
}
|
|
|
|
function jr(n, t, r, e, u, o) {
|
|
var i = 2 & u,
|
|
f = Fe(n),
|
|
c = f.length,
|
|
a = Fe(t).length;
|
|
if (c != a && !i) return !1;
|
|
for (var l = c; l--;) {
|
|
var s = f[l];
|
|
if (!(i ? s in t : pt(t, s))) return !1
|
|
}
|
|
if (a = o.get(n)) return a == t;
|
|
a = !0, o.set(n, t);
|
|
for (var h = i; ++l < c;) {
|
|
var s = f[l],
|
|
p = n[s],
|
|
_ = t[s];
|
|
if (e) var g = i ? e(_, p, s, t, n, o) : e(p, _, s, n, t, o);
|
|
if (g === Z ? p !== _ && !r(p, _, e, u, o) : !g) {
|
|
a = !1;
|
|
break
|
|
}
|
|
h || (h = "constructor" == s)
|
|
}
|
|
return a && !h && (r = n.constructor, e = t.constructor, r != e && "constructor" in n && "constructor" in t && !("function" == typeof r && r instanceof r && "function" == typeof e && e instanceof e) && (a = !1)), o["delete"](n), a
|
|
}
|
|
|
|
function mr(n) {
|
|
for (var t = n.name + "", r = Gu[t], e = cu.call(Gu, t) ? r.length : 0; e--;) {
|
|
var u = r[e],
|
|
o = u.func;
|
|
if (null == o || o == n) return u.name
|
|
}
|
|
return t
|
|
}
|
|
|
|
function wr() {
|
|
var n = yn.iteratee || Je,
|
|
n = n === Je ? xt : n;
|
|
return arguments.length ? n(arguments[0], arguments[1]) : n
|
|
}
|
|
|
|
function Ar(n) {
|
|
n = De(n);
|
|
for (var t = n.length; t--;) {
|
|
var r, e = n[t];
|
|
r = n[t][1], r = r === r && !xe(r), e[2] = r
|
|
}
|
|
return n
|
|
}
|
|
|
|
function Or(n, t) {
|
|
var r = null == n ? Z : n[t];
|
|
return me(r) ? r : Z
|
|
}
|
|
|
|
function kr(n) {
|
|
return su.call(n)
|
|
}
|
|
|
|
function Er(n, t, r) {
|
|
if (null == n) return !1;
|
|
var e = r(n, t);
|
|
return e || Cr(t) || (t = Nt(t), n = $r(n, t), null != n && (t = Kr(t), e = r(n, t))), r = n ? n.length : Z, e || !!r && be(r) && U(t, r) && (No(n) || ke(n) || pe(n))
|
|
}
|
|
|
|
function Ir(n) {
|
|
var t = n.length,
|
|
r = n.constructor(t);
|
|
return t && "string" == typeof n[0] && cu.call(n, "index") && (r.index = n.index, r.input = n.input), r
|
|
}
|
|
|
|
function Sr(n) {
|
|
return Mr(n) ? {} : (n = n.constructor, Vu(de(n) ? n.prototype : Z))
|
|
}
|
|
|
|
function Rr(r, e, u) {
|
|
var o = r.constructor;
|
|
switch (e) {
|
|
case "[object ArrayBuffer]":
|
|
return Gt(r);
|
|
case "[object Boolean]":
|
|
case "[object Date]":
|
|
return new o((+r));
|
|
case "[object Float32Array]":
|
|
case "[object Float64Array]":
|
|
case "[object Int8Array]":
|
|
case "[object Int16Array]":
|
|
case "[object Int32Array]":
|
|
case "[object Uint8Array]":
|
|
case "[object Uint8ClampedArray]":
|
|
case "[object Uint16Array]":
|
|
case "[object Uint32Array]":
|
|
return e = r.buffer, new r.constructor(u ? Gt(e) : e, r.byteOffset, r.length);
|
|
case "[object Map]":
|
|
return u = r.constructor, s(M(r), n, new u);
|
|
case "[object Number]":
|
|
case "[object String]":
|
|
return new o(r);
|
|
case "[object RegExp]":
|
|
return u = new r.constructor(r.source, hn.exec(r)), u.lastIndex = r.lastIndex, u;
|
|
case "[object Set]":
|
|
return u = r.constructor, s($(r), t, new u);
|
|
case "[object Symbol]":
|
|
return vu ? Object(Tu.call(r)) : {}
|
|
}
|
|
}
|
|
|
|
function Wr(n) {
|
|
var t = n ? n.length : Z;
|
|
return be(t) && (No(n) || ke(n) || pe(n)) ? j(t, String) : null
|
|
}
|
|
|
|
function Br(n, t, r) {
|
|
if (!xe(r)) return !1;
|
|
var e = typeof t;
|
|
return !!("number" == e ? _e(r) && U(t, r.length) : "string" == e && t in r) && se(r[t], n)
|
|
}
|
|
|
|
function Cr(n, t) {
|
|
return "number" == typeof n || !No(n) && (rn.test(n) || !tn.test(n) || null != t && n in Object(t))
|
|
}
|
|
|
|
function Ur(n) {
|
|
var t = typeof n;
|
|
return "number" == t || "boolean" == t || "string" == t && "__proto__" !== n || null == n
|
|
}
|
|
|
|
function zr(n) {
|
|
var t = mr(n),
|
|
r = yn[t];
|
|
return "function" == typeof r && t in An.prototype && (n === r || (t = to(r), !!t && n === t[0]))
|
|
}
|
|
|
|
function Mr(n) {
|
|
var t = n && n.constructor;
|
|
return n === ("function" == typeof t && t.prototype || iu)
|
|
}
|
|
|
|
function Lr(n, t, r, e, u, o) {
|
|
return xe(n) && xe(t) && (o.set(t, n), Ot(n, t, Z, Lr, o)), n
|
|
}
|
|
|
|
function $r(n, t) {
|
|
return 1 == t.length ? n : Me(n, zt(t, 0, -1))
|
|
}
|
|
|
|
function Fr(n) {
|
|
var t = [];
|
|
return ze(n).replace(en, function(n, r, e, u) {
|
|
t.push(e ? u.replace(ln, "$1") : r || n)
|
|
}), t
|
|
}
|
|
|
|
function Nr(n) {
|
|
return ge(n) ? n : []
|
|
}
|
|
|
|
function Dr(n) {
|
|
return "function" == typeof n ? n : Ve
|
|
}
|
|
|
|
function Zr(n) {
|
|
if (n instanceof An) return n.clone();
|
|
var t = new wn(n.__wrapped__, n.__chain__);
|
|
return t.__actions__ = Yt(n.__actions__), t.__index__ = n.__index__, t.__values__ = n.__values__, t
|
|
}
|
|
|
|
function qr(n, t, r) {
|
|
var e = n ? n.length : 0;
|
|
return e ? (t = r || t === Z ? 1 : We(t), zt(n, 0 > t ? 0 : t, e)) : []
|
|
}
|
|
|
|
function Pr(n, t, r) {
|
|
var e = n ? n.length : 0;
|
|
return e ? (t = r || t === Z ? 1 : We(t), t = e - t, zt(n, 0, 0 > t ? 0 : t)) : []
|
|
}
|
|
|
|
function Tr(n) {
|
|
return n ? n[0] : Z
|
|
}
|
|
|
|
function Kr(n) {
|
|
var t = n ? n.length : 0;
|
|
return t ? n[t - 1] : Z
|
|
}
|
|
|
|
function Gr(n, t) {
|
|
return n && n.length && t && t.length ? Wt(n, t) : n
|
|
}
|
|
|
|
function Vr(n) {
|
|
return n ? zu.call(n) : n
|
|
}
|
|
|
|
function Jr(n) {
|
|
if (!n || !n.length) return [];
|
|
var t = 0;
|
|
return n = i(n, function(n) {
|
|
return ge(n) ? (t = Wu(n.length, t), !0) : void 0
|
|
}), j(t, function(t) {
|
|
return a(n, St(t))
|
|
})
|
|
}
|
|
|
|
function Yr(n, t) {
|
|
if (!n || !n.length) return [];
|
|
var e = Jr(n);
|
|
return null == t ? e : a(e, function(n) {
|
|
return r(t, Z, n)
|
|
})
|
|
}
|
|
|
|
function Hr(n) {
|
|
return n = yn(n), n.__chain__ = !0, n
|
|
}
|
|
|
|
function Qr(n, t) {
|
|
return t(n)
|
|
}
|
|
|
|
function Xr() {
|
|
return this
|
|
}
|
|
|
|
function ne(n, t) {
|
|
return "function" == typeof t && No(n) ? u(n, t) : Ju(n, Dr(t))
|
|
}
|
|
|
|
function te(n, t) {
|
|
var r;
|
|
if ("function" == typeof t && No(n)) {
|
|
for (r = n.length; r-- && !1 !== t(n[r], r, n););
|
|
r = n
|
|
} else r = Yu(n, Dr(t));
|
|
return r
|
|
}
|
|
|
|
function re(n, t) {
|
|
return (No(n) ? a : mt)(n, wr(t, 3))
|
|
}
|
|
|
|
function ee(n, t) {
|
|
var r = -1,
|
|
e = Re(n),
|
|
u = e.length,
|
|
o = u - 1;
|
|
for (t = nt(We(t), 0, u); ++r < t;) {
|
|
var u = Ct(r, o),
|
|
i = e[u];
|
|
e[u] = e[r], e[r] = i
|
|
}
|
|
return e.length = t, e
|
|
}
|
|
|
|
function ue(n, t, r) {
|
|
return t = r ? Z : t, t = n && null == t ? n.length : t, yr(n, 128, Z, Z, Z, Z, t)
|
|
}
|
|
|
|
function oe(n, t) {
|
|
var r;
|
|
if ("function" != typeof t) throw new uu("Expected a function");
|
|
return n = We(n),
|
|
function() {
|
|
return 0 < --n && (r = t.apply(this, arguments)), 1 >= n && (t = Z), r
|
|
}
|
|
}
|
|
|
|
function ie(n, t, r) {
|
|
return t = r ? Z : t, n = yr(n, 8, Z, Z, Z, Z, Z, t), n.placeholder = yn.placeholder || ie.placeholder, n
|
|
}
|
|
|
|
function fe(n, t, r) {
|
|
return t = r ? Z : t, n = yr(n, 16, Z, Z, Z, Z, Z, t), n.placeholder = yn.placeholder || fe.placeholder, n
|
|
}
|
|
|
|
function ce(n, t, r) {
|
|
function e() {
|
|
p && yu(p), a && yu(a), g = 0, c = a = h = p = _ = Z
|
|
}
|
|
|
|
function u(t, r) {
|
|
r && yu(r), a = p = _ = Z, t && (g = Wo(), l = n.apply(h, c), p || a || (c = h = Z))
|
|
}
|
|
|
|
function o() {
|
|
var n = t - (Wo() - s);
|
|
0 >= n || n > t ? u(_, a) : p = Au(o, n)
|
|
}
|
|
|
|
function i() {
|
|
u(y, p)
|
|
}
|
|
|
|
function f() {
|
|
if (c = arguments, s = Wo(), h = this, _ = y && (p || !v), !1 === d) var r = v && !p;
|
|
else {
|
|
g || a || v || (g = s);
|
|
var e = d - (s - g),
|
|
u = 0 >= e || e > d;
|
|
u ? (a && (a = yu(a)), g = s, l = n.apply(h, c)) : a || (a = Au(i, e))
|
|
}
|
|
return u && p ? p = yu(p) : p || t === d || (p = Au(o, t)), r && (u = !0, l = n.apply(h, c)), !u || p || a || (c = h = Z), l
|
|
}
|
|
var c, a, l, s, h, p, _, g = 0,
|
|
v = !1,
|
|
d = !1,
|
|
y = !0;
|
|
if ("function" != typeof n) throw new uu("Expected a function");
|
|
return t = Ce(t) || 0, xe(r) && (v = !!r.leading, d = "maxWait" in r && Wu(Ce(r.maxWait) || 0, t), y = "trailing" in r ? !!r.trailing : y), f.cancel = e, f.flush = function() {
|
|
return (p && _ || a && y) && (l = n.apply(h, c)), e(), l
|
|
}, f
|
|
}
|
|
|
|
function ae(n, t) {
|
|
if ("function" != typeof n || t && "function" != typeof t) throw new uu("Expected a function");
|
|
var r = function() {
|
|
var e = arguments,
|
|
u = t ? t.apply(this, e) : e[0],
|
|
o = r.cache;
|
|
return o.has(u) ? o.get(u) : (e = n.apply(this, e), r.cache = o.set(u, e), e)
|
|
};
|
|
return r.cache = new ae.Cache, r
|
|
}
|
|
|
|
function le(n, t) {
|
|
if ("function" != typeof n) throw new uu("Expected a function");
|
|
return t = Wu(t === Z ? n.length - 1 : We(t), 0),
|
|
function() {
|
|
for (var e = arguments, u = -1, o = Wu(e.length - t, 0), i = Array(o); ++u < o;) i[u] = e[t + u];
|
|
switch (t) {
|
|
case 0:
|
|
return n.call(this, i);
|
|
case 1:
|
|
return n.call(this, e[0], i);
|
|
case 2:
|
|
return n.call(this, e[0], e[1], i)
|
|
}
|
|
for (o = Array(t + 1), u = -1; ++u < t;) o[u] = e[u];
|
|
return o[t] = i, r(n, this, o)
|
|
}
|
|
}
|
|
|
|
function se(n, t) {
|
|
return n === t || n !== n && t !== t
|
|
}
|
|
|
|
function he(n, t) {
|
|
return n > t
|
|
}
|
|
|
|
function pe(n) {
|
|
return ge(n) && cu.call(n, "callee") && (!wu.call(n, "callee") || "[object Arguments]" == su.call(n))
|
|
}
|
|
|
|
function _e(n) {
|
|
return null != n && !("function" == typeof n && de(n)) && be(ro(n))
|
|
}
|
|
|
|
function ge(n) {
|
|
return je(n) && _e(n)
|
|
}
|
|
|
|
function ve(n) {
|
|
return je(n) && "string" == typeof n.message && "[object Error]" == su.call(n)
|
|
}
|
|
|
|
function de(n) {
|
|
return n = xe(n) ? su.call(n) : "", "[object Function]" == n || "[object GeneratorFunction]" == n
|
|
}
|
|
|
|
function ye(n) {
|
|
return "number" == typeof n && n == We(n)
|
|
}
|
|
|
|
function be(n) {
|
|
return "number" == typeof n && n > -1 && 0 == n % 1 && 9007199254740991 >= n
|
|
}
|
|
|
|
function xe(n) {
|
|
var t = typeof n;
|
|
return !!n && ("object" == t || "function" == t)
|
|
}
|
|
|
|
function je(n) {
|
|
return !!n && "object" == typeof n
|
|
}
|
|
|
|
function me(n) {
|
|
return null != n && (de(n) ? pu.test(fu.call(n)) : je(n) && (C(n) ? pu : vn).test(n))
|
|
}
|
|
|
|
function we(n) {
|
|
return "number" == typeof n || je(n) && "[object Number]" == su.call(n)
|
|
}
|
|
|
|
function Ae(n) {
|
|
if (!je(n) || "[object Object]" != su.call(n) || C(n)) return !1;
|
|
var t = iu;
|
|
return "function" == typeof n.constructor && (t = xu(n)), null === t || (n = t.constructor, "function" == typeof n && n instanceof n && fu.call(n) == lu)
|
|
}
|
|
|
|
function Oe(n) {
|
|
return xe(n) && "[object RegExp]" == su.call(n)
|
|
}
|
|
|
|
function ke(n) {
|
|
return "string" == typeof n || !No(n) && je(n) && "[object String]" == su.call(n)
|
|
}
|
|
|
|
function Ee(n) {
|
|
return "symbol" == typeof n || je(n) && "[object Symbol]" == su.call(n)
|
|
}
|
|
|
|
function Ie(n) {
|
|
return je(n) && be(n.length) && !!Bn[su.call(n)]
|
|
}
|
|
|
|
function Se(n, t) {
|
|
return t > n
|
|
}
|
|
|
|
function Re(n) {
|
|
if (!n) return [];
|
|
if (_e(n)) return ke(n) ? n.match(kn) : Yt(n);
|
|
if (mu && n[mu]) return z(n[mu]());
|
|
var t = kr(n);
|
|
return ("[object Map]" == t ? M : "[object Set]" == t ? $ : Ze)(n)
|
|
}
|
|
|
|
function We(n) {
|
|
if (!n) return 0 === n ? n : 0;
|
|
if (n = Ce(n), n === q || n === -q) return 1.7976931348623157e308 * (0 > n ? -1 : 1);
|
|
var t = n % 1;
|
|
return n === n ? t ? n - t : n : 0
|
|
}
|
|
|
|
function Be(n) {
|
|
return n ? nt(We(n), 0, 4294967295) : 0
|
|
}
|
|
|
|
function Ce(n) {
|
|
if (xe(n) && (n = de(n.valueOf) ? n.valueOf() : n, n = xe(n) ? n + "" : n), "string" != typeof n) return 0 === n ? n : +n;
|
|
n = n.replace(fn, "");
|
|
var t = gn.test(n);
|
|
return t || dn.test(n) ? Nn(n.slice(2), t ? 2 : 8) : _n.test(n) ? P : +n
|
|
}
|
|
|
|
function Ue(n) {
|
|
return Ht(n, Ne(n))
|
|
}
|
|
|
|
function ze(n) {
|
|
if ("string" == typeof n) return n;
|
|
if (null == n) return "";
|
|
if (Ee(n)) return vu ? Ku.call(n) : "";
|
|
var t = n + "";
|
|
return "0" == t && 1 / n == -q ? "-0" : t
|
|
}
|
|
|
|
function Me(n, t, r) {
|
|
return n = null == n ? Z : ht(n, t), n === Z ? r : n
|
|
}
|
|
|
|
function Le(n, t) {
|
|
return Er(n, t, pt)
|
|
}
|
|
|
|
function $e(n, t) {
|
|
return Er(n, t, _t)
|
|
}
|
|
|
|
function Fe(n) {
|
|
var t = Mr(n);
|
|
if (!t && !_e(n)) return Ru(Object(n));
|
|
var r, e = Wr(n),
|
|
u = !!e,
|
|
e = e || [],
|
|
o = e.length;
|
|
for (r in n) !pt(n, r) || u && ("length" == r || U(r, o)) || t && "constructor" == r || e.push(r);
|
|
return e
|
|
}
|
|
|
|
function Ne(n) {
|
|
for (var t = -1, r = Mr(n), e = jt(n), u = e.length, o = Wr(n), i = !!o, o = o || [], f = o.length; ++t < u;) {
|
|
var c = e[t];
|
|
i && ("length" == c || U(c, f)) || "constructor" == c && (r || !cu.call(n, c)) || o.push(c)
|
|
}
|
|
return o
|
|
}
|
|
|
|
function De(n) {
|
|
return m(n, Fe(n))
|
|
}
|
|
|
|
function Ze(n) {
|
|
return n ? A(n, Fe(n)) : []
|
|
}
|
|
|
|
function qe(n) {
|
|
return ii(ze(n).toLowerCase())
|
|
}
|
|
|
|
function Pe(n) {
|
|
return (n = ze(n)) && n.replace(bn, S).replace(On, "")
|
|
}
|
|
|
|
function Te(n, t) {
|
|
n = ze(n), t = We(t);
|
|
var r = "";
|
|
if (!n || 1 > t || t > 9007199254740991) return r;
|
|
do t % 2 && (r += n), t = Eu(t / 2), n += n; while (t);
|
|
return r
|
|
}
|
|
|
|
function Ke(n, t, r) {
|
|
return n = ze(n), t = r ? Z : t, t === Z && (t = Rn.test(n) ? Sn : In), n.match(t) || []
|
|
}
|
|
|
|
function Ge(n) {
|
|
return function() {
|
|
return n
|
|
}
|
|
}
|
|
|
|
function Ve(n) {
|
|
return n
|
|
}
|
|
|
|
function Je(n) {
|
|
return xt("function" == typeof n ? n : tt(n, !0))
|
|
}
|
|
|
|
function Ye(n, t, r) {
|
|
var e = Fe(t),
|
|
o = st(t, e);
|
|
null != r || xe(t) && (o.length || !e.length) || (r = t, t = n, n = this, o = st(t, Fe(t)));
|
|
var i = !(xe(r) && "chain" in r) || r.chain,
|
|
f = de(n);
|
|
return u(o, function(r) {
|
|
var e = t[r];
|
|
n[r] = e, f && (n.prototype[r] = function() {
|
|
var t = this.__chain__;
|
|
if (i || t) {
|
|
var r = n(this.__wrapped__);
|
|
return (r.__actions__ = Yt(this.__actions__)).push({
|
|
func: e,
|
|
args: arguments,
|
|
thisArg: n
|
|
}), r.__chain__ = t, r
|
|
}
|
|
return e.apply(n, l([this.value()], arguments))
|
|
})
|
|
}), n
|
|
}
|
|
|
|
function He() {}
|
|
|
|
function Qe(n) {
|
|
return Cr(n) ? St(n) : Rt(n)
|
|
}
|
|
|
|
function Xe(n) {
|
|
return n && n.length ? x(n, Ve) : 0
|
|
}
|
|
E = E ? Jn.defaults({}, E, Jn.pick(Vn, Wn)) : Vn;
|
|
var nu = E.Date,
|
|
tu = E.Error,
|
|
ru = E.Math,
|
|
eu = E.RegExp,
|
|
uu = E.TypeError,
|
|
ou = E.Array.prototype,
|
|
iu = E.Object.prototype,
|
|
fu = E.Function.prototype.toString,
|
|
cu = iu.hasOwnProperty,
|
|
au = 0,
|
|
lu = fu.call(Object),
|
|
su = iu.toString,
|
|
hu = Vn._,
|
|
pu = eu("^" + fu.call(cu).replace(un, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$"),
|
|
_u = Kn ? E.Buffer : Z,
|
|
gu = E.Reflect,
|
|
vu = E.Symbol,
|
|
du = E.Uint8Array,
|
|
yu = E.clearTimeout,
|
|
bu = gu ? gu.enumerate : Z,
|
|
xu = Object.getPrototypeOf,
|
|
ju = Object.getOwnPropertySymbols,
|
|
mu = "symbol" == typeof(mu = vu && vu.iterator) ? mu : Z,
|
|
wu = iu.propertyIsEnumerable,
|
|
Au = E.setTimeout,
|
|
Ou = ou.splice,
|
|
ku = ru.ceil,
|
|
Eu = ru.floor,
|
|
Iu = E.isFinite,
|
|
Su = ou.join,
|
|
Ru = Object.keys,
|
|
Wu = ru.max,
|
|
Bu = ru.min,
|
|
Cu = E.parseInt,
|
|
Uu = ru.random,
|
|
zu = ou.reverse,
|
|
Mu = Or(E, "Map"),
|
|
Lu = Or(E, "Set"),
|
|
$u = Or(E, "WeakMap"),
|
|
Fu = Or(Object, "create"),
|
|
Nu = $u && new $u,
|
|
Du = Mu ? fu.call(Mu) : "",
|
|
Zu = Lu ? fu.call(Lu) : "",
|
|
qu = $u ? fu.call($u) : "",
|
|
Pu = vu ? vu.prototype : Z,
|
|
Tu = vu ? Pu.valueOf : Z,
|
|
Ku = vu ? Pu.toString : Z,
|
|
Gu = {};
|
|
yn.templateSettings = {
|
|
escape: Q,
|
|
evaluate: X,
|
|
interpolate: nn,
|
|
variable: "",
|
|
imports: {
|
|
_: yn
|
|
}
|
|
};
|
|
var Vu = function() {
|
|
function n() {}
|
|
return function(t) {
|
|
if (xe(t)) {
|
|
n.prototype = t;
|
|
var r = new n;
|
|
n.prototype = Z
|
|
}
|
|
return r || {}
|
|
}
|
|
}(),
|
|
Ju = rr(at),
|
|
Yu = rr(lt, !0),
|
|
Hu = er(),
|
|
Qu = er(!0);
|
|
bu && !wu.call({
|
|
valueOf: 1
|
|
}, "valueOf") && (jt = function(n) {
|
|
return z(bu(n))
|
|
});
|
|
var Xu = Nu ? function(n, t) {
|
|
return Nu.set(n, t), n
|
|
} : Ve,
|
|
no = Lu && 2 === new Lu([1, 2]).size ? function(n) {
|
|
return new Lu(n)
|
|
} : He,
|
|
to = Nu ? function(n) {
|
|
return Nu.get(n)
|
|
} : He,
|
|
ro = St("length"),
|
|
eo = ju || function() {
|
|
return []
|
|
};
|
|
(Mu && "[object Map]" != kr(new Mu) || Lu && "[object Set]" != kr(new Lu) || $u && "[object WeakMap]" != kr(new $u)) && (kr = function(n) {
|
|
var t = su.call(n);
|
|
if (n = "[object Object]" == t ? n.constructor : null, n = "function" == typeof n ? fu.call(n) : "") switch (n) {
|
|
case Du:
|
|
return "[object Map]";
|
|
case Zu:
|
|
return "[object Set]";
|
|
case qu:
|
|
return "[object WeakMap]"
|
|
}
|
|
return t
|
|
});
|
|
var uo = function() {
|
|
var n = 0,
|
|
t = 0;
|
|
return function(r, e) {
|
|
var u = Wo(),
|
|
o = 16 - (u - t);
|
|
if (t = u, o > 0) {
|
|
if (150 <= ++n) return r
|
|
} else n = 0;
|
|
return Xu(r, e)
|
|
}
|
|
}(),
|
|
oo = le(function(n, t) {
|
|
No(n) || (n = null == n ? [] : [Object(n)]), t = ft(t);
|
|
for (var r = n, e = t, u = -1, o = r.length, i = -1, f = e.length, c = Array(o + f); ++u < o;) c[u] = r[u];
|
|
for (; ++i < f;) c[u++] = e[i];
|
|
return c
|
|
}),
|
|
io = le(function(n, t) {
|
|
return ge(n) ? ut(n, ft(t, !1, !0)) : []
|
|
}),
|
|
fo = le(function(n, t) {
|
|
var r = Kr(t);
|
|
return ge(r) && (r = Z), ge(n) ? ut(n, ft(t, !1, !0), wr(r)) : []
|
|
}),
|
|
co = le(function(n, t) {
|
|
var r = Kr(t);
|
|
return ge(r) && (r = Z), ge(n) ? ut(n, ft(t, !1, !0), Z, r) : []
|
|
}),
|
|
ao = le(function(n) {
|
|
var t = a(n, Nr);
|
|
return t.length && t[0] === n[0] ? gt(t) : []
|
|
}),
|
|
lo = le(function(n) {
|
|
var t = Kr(n),
|
|
r = a(n, Nr);
|
|
return t === Kr(r) ? t = Z : r.pop(), r.length && r[0] === n[0] ? gt(r, wr(t)) : []
|
|
}),
|
|
so = le(function(n) {
|
|
var t = Kr(n),
|
|
r = a(n, Nr);
|
|
return t === Kr(r) ? t = Z : r.pop(), r.length && r[0] === n[0] ? gt(r, Z, t) : []
|
|
}),
|
|
ho = le(Gr),
|
|
po = le(function(n, t) {
|
|
t = a(ft(t), String);
|
|
var r = Xn(n, t);
|
|
return Bt(n, t.sort(I)), r
|
|
}),
|
|
_o = le(function(n) {
|
|
return Dt(ft(n, !1, !0))
|
|
}),
|
|
go = le(function(n) {
|
|
var t = Kr(n);
|
|
return ge(t) && (t = Z), Dt(ft(n, !1, !0), wr(t))
|
|
}),
|
|
vo = le(function(n) {
|
|
var t = Kr(n);
|
|
return ge(t) && (t = Z), Dt(ft(n, !1, !0), Z, t)
|
|
}),
|
|
yo = le(function(n, t) {
|
|
return ge(n) ? ut(n, t) : []
|
|
}),
|
|
bo = le(function(n) {
|
|
return Pt(i(n, ge))
|
|
}),
|
|
xo = le(function(n) {
|
|
var t = Kr(n);
|
|
return ge(t) && (t = Z), Pt(i(n, ge), wr(t))
|
|
}),
|
|
jo = le(function(n) {
|
|
var t = Kr(n);
|
|
return ge(t) && (t = Z), Pt(i(n, ge), Z, t)
|
|
}),
|
|
mo = le(Jr),
|
|
wo = le(function(n) {
|
|
var t = n.length,
|
|
t = t > 1 ? n[t - 1] : Z,
|
|
t = "function" == typeof t ? (n.pop(), t) : Z;
|
|
return Yr(n, t)
|
|
}),
|
|
Ao = le(function(n) {
|
|
n = ft(n);
|
|
var t = n.length,
|
|
r = t ? n[0] : 0,
|
|
e = this.__wrapped__,
|
|
u = function(t) {
|
|
return Xn(t, n)
|
|
};
|
|
return 1 >= t && !this.__actions__.length && e instanceof An && U(r) ? (e = e.slice(r, +r + (t ? 1 : 0)), e.__actions__.push({
|
|
func: Qr,
|
|
args: [u],
|
|
thisArg: Z
|
|
}), new wn(e, this.__chain__).thru(function(n) {
|
|
return t && !n.length && n.push(Z), n
|
|
})) : this.thru(u)
|
|
}),
|
|
Oo = nr(function(n, t, r) {
|
|
cu.call(n, r) ? ++n[r] : n[r] = 1
|
|
}),
|
|
ko = nr(function(n, t, r) {
|
|
cu.call(n, r) ? n[r].push(t) : n[r] = [t]
|
|
}),
|
|
Eo = le(function(n, t, e) {
|
|
var u = -1,
|
|
o = "function" == typeof t,
|
|
i = Cr(t),
|
|
f = _e(n) ? Array(n.length) : [];
|
|
return Ju(n, function(n) {
|
|
var c = o ? t : i && null != n ? n[t] : Z;
|
|
f[++u] = c ? r(c, n, e) : dt(n, t, e)
|
|
}), f
|
|
}),
|
|
Io = nr(function(n, t, r) {
|
|
n[r] = t
|
|
}),
|
|
So = nr(function(n, t, r) {
|
|
n[r ? 0 : 1].push(t)
|
|
}, function() {
|
|
return [
|
|
[],
|
|
[]
|
|
]
|
|
}),
|
|
Ro = le(function(n, t) {
|
|
if (null == n) return [];
|
|
var r = t.length;
|
|
return r > 1 && Br(n, t[0], t[1]) ? t = [] : r > 2 && Br(t[0], t[1], t[2]) && (t.length = 1), kt(n, ft(t), [])
|
|
}),
|
|
Wo = nu.now,
|
|
Bo = le(function(n, t, r) {
|
|
var e = 1;
|
|
if (r.length) var u = L(r, yn.placeholder || Bo.placeholder),
|
|
e = 32 | e;
|
|
return yr(n, e, t, r, u)
|
|
}),
|
|
Co = le(function(n, t, r) {
|
|
var e = 3;
|
|
if (r.length) var u = L(r, yn.placeholder || Co.placeholder),
|
|
e = 32 | e;
|
|
return yr(t, e, n, r, u)
|
|
}),
|
|
Uo = le(function(n, t) {
|
|
return et(n, 1, t)
|
|
}),
|
|
zo = le(function(n, t, r) {
|
|
return et(n, Ce(t) || 0, r)
|
|
}),
|
|
Mo = le(function(n, t) {
|
|
t = a(ft(t), wr());
|
|
var e = t.length;
|
|
return le(function(u) {
|
|
for (var o = -1, i = Bu(u.length, e); ++o < i;) u[o] = t[o].call(this, u[o]);
|
|
return r(n, this, u)
|
|
})
|
|
}),
|
|
Lo = le(function(n, t) {
|
|
var r = L(t, yn.placeholder || Lo.placeholder);
|
|
return yr(n, 32, Z, t, r)
|
|
}),
|
|
$o = le(function(n, t) {
|
|
var r = L(t, yn.placeholder || $o.placeholder);
|
|
return yr(n, 64, Z, t, r)
|
|
}),
|
|
Fo = le(function(n, t) {
|
|
return yr(n, 256, Z, Z, Z, ft(t))
|
|
}),
|
|
No = Array.isArray,
|
|
Do = _u ? function(n) {
|
|
return n instanceof _u
|
|
} : Ge(!1),
|
|
Zo = tr(function(n, t) {
|
|
Ht(t, Fe(t), n)
|
|
}),
|
|
qo = tr(function(n, t) {
|
|
Ht(t, Ne(t), n)
|
|
}),
|
|
Po = tr(function(n, t, r, e) {
|
|
Qt(t, Ne(t), n, e)
|
|
}),
|
|
To = tr(function(n, t, r, e) {
|
|
Qt(t, Fe(t), n, e)
|
|
}),
|
|
Ko = le(function(n, t) {
|
|
return Xn(n, ft(t))
|
|
}),
|
|
Go = le(function(n) {
|
|
return n.push(Z, Tn), r(Po, Z, n)
|
|
}),
|
|
Vo = le(function(n) {
|
|
return n.push(Z, Lr), r(Xo, Z, n)
|
|
}),
|
|
Jo = sr(function(n, t, r) {
|
|
n[t] = r
|
|
}, Ge(Ve)),
|
|
Yo = sr(function(n, t, r) {
|
|
cu.call(n, t) ? n[t].push(r) : n[t] = [r]
|
|
}, wr),
|
|
Ho = le(dt),
|
|
Qo = tr(function(n, t, r) {
|
|
Ot(n, t, r)
|
|
}),
|
|
Xo = tr(function(n, t, r, e) {
|
|
Ot(n, t, r, e)
|
|
}),
|
|
ni = le(function(n, t) {
|
|
return null == n ? {} : (t = a(ft(t), String), Et(n, ut(Ne(n), t)))
|
|
}),
|
|
ti = le(function(n, t) {
|
|
return null == n ? {} : Et(n, ft(t))
|
|
}),
|
|
ri = ir(function(n, t, r) {
|
|
return t = t.toLowerCase(), n + (r ? qe(t) : t)
|
|
}),
|
|
ei = ir(function(n, t, r) {
|
|
return n + (r ? "-" : "") + t.toLowerCase()
|
|
}),
|
|
ui = ir(function(n, t, r) {
|
|
return n + (r ? " " : "") + t.toLowerCase()
|
|
}),
|
|
oi = or("toLowerCase"),
|
|
ii = or("toUpperCase"),
|
|
fi = ir(function(n, t, r) {
|
|
return n + (r ? "_" : "") + t.toLowerCase()
|
|
}),
|
|
ci = ir(function(n, t, r) {
|
|
return n + (r ? " " : "") + qe(t)
|
|
}),
|
|
ai = ir(function(n, t, r) {
|
|
return n + (r ? " " : "") + t.toUpperCase()
|
|
}),
|
|
li = le(function(n, t) {
|
|
try {
|
|
return r(n, Z, t)
|
|
} catch (e) {
|
|
return xe(e) ? e : new tu(e)
|
|
}
|
|
}),
|
|
si = le(function(n, t) {
|
|
return u(ft(t), function(t) {
|
|
n[t] = Bo(n[t], n)
|
|
}), n
|
|
}),
|
|
hi = ar(),
|
|
pi = ar(!0),
|
|
_i = le(function(n, t) {
|
|
return function(r) {
|
|
return dt(r, n, t)
|
|
}
|
|
}),
|
|
gi = le(function(n, t) {
|
|
return function(r) {
|
|
return dt(n, r, t)
|
|
}
|
|
}),
|
|
vi = hr(a),
|
|
di = hr(o),
|
|
yi = hr(p),
|
|
bi = gr(),
|
|
xi = gr(!0),
|
|
ji = dr("ceil"),
|
|
mi = dr("floor"),
|
|
wi = dr("round");
|
|
return yn.prototype = mn.prototype, wn.prototype = Vu(mn.prototype), wn.prototype.constructor = wn, An.prototype = Vu(mn.prototype), An.prototype.constructor = An, Un.prototype = Fu ? Fu(null) : iu, zn.prototype.clear = function() {
|
|
this.__data__ = {
|
|
hash: new Un,
|
|
map: Mu ? new Mu : [],
|
|
string: new Un
|
|
}
|
|
}, zn.prototype["delete"] = function(n) {
|
|
var t = this.__data__;
|
|
return Ur(n) ? (t = "string" == typeof n ? t.string : t.hash, (Fu ? t[n] !== Z : cu.call(t, n)) && delete t[n]) : Mu ? t.map["delete"](n) : Dn(t.map, n)
|
|
}, zn.prototype.get = function(n) {
|
|
var t = this.__data__;
|
|
return Ur(n) ? (t = "string" == typeof n ? t.string : t.hash, Fu ? (n = t[n], n = "__lodash_hash_undefined__" === n ? Z : n) : n = cu.call(t, n) ? t[n] : Z, n) : Mu ? t.map.get(n) : Zn(t.map, n)
|
|
}, zn.prototype.has = function(n) {
|
|
var t = this.__data__;
|
|
return Ur(n) ? (t = "string" == typeof n ? t.string : t.hash, n = Fu ? t[n] !== Z : cu.call(t, n)) : n = Mu ? t.map.has(n) : -1 < qn(t.map, n), n
|
|
}, zn.prototype.set = function(n, t) {
|
|
var r = this.__data__;
|
|
return Ur(n) ? ("string" == typeof n ? r.string : r.hash)[n] = Fu && t === Z ? "__lodash_hash_undefined__" : t : Mu ? r.map.set(n, t) : Pn(r.map, n, t), this
|
|
}, Mn.prototype.push = function(n) {
|
|
var t = this.__data__;
|
|
Ur(n) ? (t = t.__data__, ("string" == typeof n ? t.string : t.hash)[n] = "__lodash_hash_undefined__") : t.set(n, "__lodash_hash_undefined__")
|
|
}, $n.prototype.clear = function() {
|
|
this.__data__ = {
|
|
array: [],
|
|
map: null
|
|
}
|
|
}, $n.prototype["delete"] = function(n) {
|
|
var t = this.__data__,
|
|
r = t.array;
|
|
return r ? Dn(r, n) : t.map["delete"](n)
|
|
}, $n.prototype.get = function(n) {
|
|
var t = this.__data__,
|
|
r = t.array;
|
|
return r ? Zn(r, n) : t.map.get(n)
|
|
}, $n.prototype.has = function(n) {
|
|
var t = this.__data__,
|
|
r = t.array;
|
|
return r ? -1 < qn(r, n) : t.map.has(n)
|
|
}, $n.prototype.set = function(n, t) {
|
|
var r = this.__data__,
|
|
e = r.array;
|
|
return e && (199 > e.length ? Pn(e, n, t) : (r.array = null, r.map = new zn(e))), (r = r.map) && r.set(n, t), this
|
|
}, ae.Cache = zn, yn.after = function(n, t) {
|
|
if ("function" != typeof t) throw new uu("Expected a function");
|
|
return n = We(n),
|
|
function() {
|
|
return 1 > --n ? t.apply(this, arguments) : void 0
|
|
}
|
|
}, yn.ary = ue, yn.assign = Zo, yn.assignIn = qo, yn.assignInWith = Po, yn.assignWith = To, yn.at = Ko, yn.before = oe, yn.bind = Bo, yn.bindAll = si, yn.bindKey = Co, yn.chain = Hr, yn.chunk = function(n, t) {
|
|
t = Wu(We(t), 0);
|
|
var r = n ? n.length : 0;
|
|
if (!r || 1 > t) return [];
|
|
for (var e = 0, u = -1, o = Array(ku(r / t)); r > e;) o[++u] = zt(n, e, e += t);
|
|
return o
|
|
}, yn.compact = function(n) {
|
|
for (var t = -1, r = n ? n.length : 0, e = -1, u = []; ++t < r;) {
|
|
var o = n[t];
|
|
o && (u[++e] = o)
|
|
}
|
|
return u
|
|
}, yn.concat = oo, yn.cond = function(n) {
|
|
var t = n ? n.length : 0,
|
|
e = wr();
|
|
return n = t ? a(n, function(n) {
|
|
if ("function" != typeof n[1]) throw new uu("Expected a function");
|
|
return [e(n[0]), n[1]]
|
|
}) : [], le(function(e) {
|
|
for (var u = -1; ++u < t;) {
|
|
var o = n[u];
|
|
if (r(o[0], this, e)) return r(o[1], this, e)
|
|
}
|
|
})
|
|
}, yn.conforms = function(n) {
|
|
return rt(tt(n, !0))
|
|
}, yn.constant = Ge, yn.countBy = Oo, yn.create = function(n, t) {
|
|
var r = Vu(n);
|
|
return t ? Qn(r, t) : r
|
|
}, yn.curry = ie, yn.curryRight = fe, yn.debounce = ce, yn.defaults = Go, yn.defaultsDeep = Vo, yn.defer = Uo, yn.delay = zo, yn.difference = io, yn.differenceBy = fo, yn.differenceWith = co, yn.drop = qr, yn.dropRight = Pr, yn.dropRightWhile = function(n, t) {
|
|
return n && n.length ? Zt(n, wr(t, 3), !0, !0) : []
|
|
}, yn.dropWhile = function(n, t) {
|
|
return n && n.length ? Zt(n, wr(t, 3), !0) : []
|
|
}, yn.fill = function(n, t, r, e) {
|
|
var u = n ? n.length : 0;
|
|
if (!u) return [];
|
|
for (r && "number" != typeof r && Br(n, t, r) && (r = 0, e = u), u = n.length, r = We(r), 0 > r && (r = -r > u ? 0 : u + r), e = e === Z || e > u ? u : We(e), 0 > e && (e += u), e = r > e ? 0 : Be(e); e > r;) n[r++] = t;
|
|
return n
|
|
}, yn.filter = function(n, t) {
|
|
return (No(n) ? i : it)(n, wr(t, 3))
|
|
}, yn.flatMap = function(n, t) {
|
|
return ft(re(n, t))
|
|
}, yn.flatten = function(n) {
|
|
return n && n.length ? ft(n) : []
|
|
}, yn.flattenDeep = function(n) {
|
|
return n && n.length ? ft(n, !0) : []
|
|
}, yn.flip = function(n) {
|
|
return yr(n, 512)
|
|
}, yn.flow = hi, yn.flowRight = pi, yn.fromPairs = function(n) {
|
|
for (var t = -1, r = n ? n.length : 0, e = {}; ++t < r;) {
|
|
var u = n[t];
|
|
e[u[0]] = u[1]
|
|
}
|
|
return e
|
|
}, yn.functions = function(n) {
|
|
return null == n ? [] : st(n, Fe(n))
|
|
}, yn.functionsIn = function(n) {
|
|
return null == n ? [] : st(n, Ne(n))
|
|
}, yn.groupBy = ko, yn.initial = function(n) {
|
|
return Pr(n, 1)
|
|
}, yn.intersection = ao, yn.intersectionBy = lo, yn.intersectionWith = so, yn.invert = Jo, yn.invertBy = Yo, yn.invokeMap = Eo, yn.iteratee = Je, yn.keyBy = Io, yn.keys = Fe, yn.keysIn = Ne, yn.map = re, yn.mapKeys = function(n, t) {
|
|
var r = {};
|
|
return t = wr(t, 3), at(n, function(n, e, u) {
|
|
r[t(n, e, u)] = n
|
|
}), r
|
|
}, yn.mapValues = function(n, t) {
|
|
var r = {};
|
|
return t = wr(t, 3), at(n, function(n, e, u) {
|
|
r[e] = t(n, e, u)
|
|
}), r
|
|
}, yn.matches = function(n) {
|
|
return wt(tt(n, !0))
|
|
}, yn.matchesProperty = function(n, t) {
|
|
return At(n, tt(t, !0))
|
|
}, yn.memoize = ae, yn.merge = Qo, yn.mergeWith = Xo, yn.method = _i, yn.methodOf = gi, yn.mixin = Ye, yn.negate = function(n) {
|
|
if ("function" != typeof n) throw new uu("Expected a function");
|
|
return function() {
|
|
return !n.apply(this, arguments)
|
|
}
|
|
}, yn.nthArg = function(n) {
|
|
return n = We(n),
|
|
function() {
|
|
return arguments[n]
|
|
}
|
|
}, yn.omit = ni, yn.omitBy = function(n, t) {
|
|
return t = wr(t, 2), It(n, function(n, r) {
|
|
return !t(n, r)
|
|
})
|
|
}, yn.once = function(n) {
|
|
return oe(2, n)
|
|
}, yn.orderBy = function(n, t, r, e) {
|
|
return null == n ? [] : (No(t) || (t = null == t ? [] : [t]), r = e ? Z : r, No(r) || (r = null == r ? [] : [r]), kt(n, t, r))
|
|
}, yn.over = vi, yn.overArgs = Mo, yn.overEvery = di, yn.overSome = yi, yn.partial = Lo, yn.partialRight = $o, yn.partition = So, yn.pick = ti, yn.pickBy = function(n, t) {
|
|
return null == n ? {} : It(n, wr(t, 2))
|
|
}, yn.property = Qe, yn.propertyOf = function(n) {
|
|
return function(t) {
|
|
return null == n ? Z : ht(n, t)
|
|
}
|
|
}, yn.pull = ho, yn.pullAll = Gr, yn.pullAllBy = function(n, t, r) {
|
|
return n && n.length && t && t.length ? Wt(n, t, wr(r)) : n
|
|
}, yn.pullAt = po, yn.range = bi, yn.rangeRight = xi, yn.rearg = Fo, yn.reject = function(n, t) {
|
|
var r = No(n) ? i : it;
|
|
return t = wr(t, 3), r(n, function(n, r, e) {
|
|
return !t(n, r, e)
|
|
})
|
|
}, yn.remove = function(n, t) {
|
|
var r = [];
|
|
if (!n || !n.length) return r;
|
|
var e = -1,
|
|
u = [],
|
|
o = n.length;
|
|
for (t = wr(t, 3); ++e < o;) {
|
|
var i = n[e];
|
|
t(i, e, n) && (r.push(i), u.push(e))
|
|
}
|
|
return Bt(n, u), r
|
|
}, yn.rest = le, yn.reverse = Vr, yn.sampleSize = ee, yn.set = function(n, t, r) {
|
|
return null == n ? n : Ut(n, t, r)
|
|
}, yn.setWith = function(n, t, r, e) {
|
|
return e = "function" == typeof e ? e : Z, null == n ? n : Ut(n, t, r, e)
|
|
}, yn.shuffle = function(n) {
|
|
return ee(n, 4294967295)
|
|
}, yn.slice = function(n, t, r) {
|
|
var e = n ? n.length : 0;
|
|
return e ? (r && "number" != typeof r && Br(n, t, r) ? (t = 0, r = e) : (t = null == t ? 0 : We(t), r = r === Z ? e : We(r)), zt(n, t, r)) : []
|
|
}, yn.sortBy = Ro, yn.sortedUniq = function(n) {
|
|
return n && n.length ? Ft(n) : []
|
|
}, yn.sortedUniqBy = function(n, t) {
|
|
return n && n.length ? Ft(n, wr(t)) : []
|
|
}, yn.split = function(n, t, r) {
|
|
return ze(n).split(t, r)
|
|
}, yn.spread = function(n, t) {
|
|
if ("function" != typeof n) throw new uu("Expected a function");
|
|
return t = t === Z ? 0 : Wu(We(t), 0), le(function(e) {
|
|
var u = e[t];
|
|
return e = e.slice(0, t), u && l(e, u), r(n, this, e)
|
|
})
|
|
}, yn.tail = function(n) {
|
|
return qr(n, 1)
|
|
}, yn.take = function(n, t, r) {
|
|
return n && n.length ? (t = r || t === Z ? 1 : We(t), zt(n, 0, 0 > t ? 0 : t)) : []
|
|
}, yn.takeRight = function(n, t, r) {
|
|
var e = n ? n.length : 0;
|
|
return e ? (t = r || t === Z ? 1 : We(t), t = e - t, zt(n, 0 > t ? 0 : t, e)) : []
|
|
}, yn.takeRightWhile = function(n, t) {
|
|
return n && n.length ? Zt(n, wr(t, 3), !1, !0) : []
|
|
}, yn.takeWhile = function(n, t) {
|
|
return n && n.length ? Zt(n, wr(t, 3)) : []
|
|
}, yn.tap = function(n, t) {
|
|
return t(n), n
|
|
}, yn.throttle = function(n, t, r) {
|
|
var e = !0,
|
|
u = !0;
|
|
if ("function" != typeof n) throw new uu("Expected a function");
|
|
return xe(r) && (e = "leading" in r ? !!r.leading : e, u = "trailing" in r ? !!r.trailing : u), ce(n, t, {
|
|
leading: e,
|
|
maxWait: t,
|
|
trailing: u
|
|
})
|
|
}, yn.thru = Qr, yn.toArray = Re, yn.toPairs = De, yn.toPairsIn = function(n) {
|
|
return m(n, Ne(n))
|
|
}, yn.toPath = function(n) {
|
|
return No(n) ? a(n, String) : Fr(n)
|
|
}, yn.toPlainObject = Ue, yn.transform = function(n, t, r) {
|
|
var e = No(n) || Ie(n);
|
|
if (t = wr(t, 4), null == r)
|
|
if (e || xe(n)) {
|
|
var o = n.constructor;
|
|
r = e ? No(n) ? new o : [] : Vu(de(o) ? o.prototype : Z)
|
|
} else r = {};
|
|
return (e ? u : at)(n, function(n, e, u) {
|
|
return t(r, n, e, u)
|
|
}), r
|
|
}, yn.unary = function(n) {
|
|
return ue(n, 1)
|
|
}, yn.union = _o, yn.unionBy = go, yn.unionWith = vo, yn.uniq = function(n) {
|
|
return n && n.length ? Dt(n) : []
|
|
}, yn.uniqBy = function(n, t) {
|
|
return n && n.length ? Dt(n, wr(t)) : []
|
|
}, yn.uniqWith = function(n, t) {
|
|
return n && n.length ? Dt(n, Z, t) : []
|
|
}, yn.unset = function(n, t) {
|
|
var r;
|
|
if (null == n) r = !0;
|
|
else {
|
|
r = n;
|
|
var e = t,
|
|
e = Cr(e, r) ? [e + ""] : Nt(e);
|
|
r = $r(r, e), e = Kr(e), r = null == r || !Le(r, e) || delete r[e]
|
|
}
|
|
return r
|
|
}, yn.unzip = Jr, yn.unzipWith = Yr, yn.values = Ze, yn.valuesIn = function(n) {
|
|
return null == n ? A(n, Ne(n)) : []
|
|
}, yn.without = yo, yn.words = Ke, yn.wrap = function(n, t) {
|
|
return t = null == t ? Ve : t, Lo(t, n)
|
|
}, yn.xor = bo, yn.xorBy = xo, yn.xorWith = jo, yn.zip = mo, yn.zipObject = function(n, t) {
|
|
return Tt(n || [], t || [], Yn)
|
|
}, yn.zipObjectDeep = function(n, t) {
|
|
return Tt(n || [], t || [], Ut)
|
|
}, yn.zipWith = wo, yn.extend = qo, yn.extendWith = Po, Ye(yn, yn), yn.add = function(n, t) {
|
|
var r;
|
|
return n === Z && t === Z ? 0 : (n !== Z && (r = n), t !== Z && (r = r === Z ? t : r + t), r)
|
|
}, yn.attempt = li, yn.camelCase = ri, yn.capitalize = qe, yn.ceil = ji, yn.clamp = function(n, t, r) {
|
|
return r === Z && (r = t, t = Z), r !== Z && (r = Ce(r), r = r === r ? r : 0), t !== Z && (t = Ce(t), t = t === t ? t : 0), nt(Ce(n), t, r)
|
|
}, yn.clone = function(n) {
|
|
return tt(n)
|
|
}, yn.cloneDeep = function(n) {
|
|
return tt(n, !0)
|
|
}, yn.cloneDeepWith = function(n, t) {
|
|
return tt(n, !0, t)
|
|
}, yn.cloneWith = function(n, t) {
|
|
return tt(n, !1, t)
|
|
}, yn.deburr = Pe, yn.endsWith = function(n, t, r) {
|
|
n = ze(n), t = "string" == typeof t ? t : t + "";
|
|
var e = n.length;
|
|
return r = r === Z ? e : nt(We(r), 0, e), r -= t.length, r >= 0 && n.indexOf(t, r) == r
|
|
}, yn.eq = se, yn.escape = function(n) {
|
|
return (n = ze(n)) && H.test(n) ? n.replace(J, R) : n
|
|
}, yn.escapeRegExp = function(n) {
|
|
return (n = ze(n)) && on.test(n) ? n.replace(un, "\\$&") : n
|
|
}, yn.every = function(n, t, r) {
|
|
var e = No(n) ? o : ot;
|
|
return r && Br(n, t, r) && (t = Z), e(n, wr(t, 3))
|
|
}, yn.find = function(n, t) {
|
|
if (t = wr(t, 3), No(n)) {
|
|
var r = v(n, t);
|
|
return r > -1 ? n[r] : Z
|
|
}
|
|
return g(n, t, Ju)
|
|
}, yn.findIndex = function(n, t) {
|
|
return n && n.length ? v(n, wr(t, 3)) : -1
|
|
}, yn.findKey = function(n, t) {
|
|
return g(n, wr(t, 3), at, !0)
|
|
}, yn.findLast = function(n, t) {
|
|
if (t = wr(t, 3), No(n)) {
|
|
var r = v(n, t, !0);
|
|
return r > -1 ? n[r] : Z
|
|
}
|
|
return g(n, t, Yu)
|
|
}, yn.findLastIndex = function(n, t) {
|
|
return n && n.length ? v(n, wr(t, 3), !0) : -1
|
|
}, yn.findLastKey = function(n, t) {
|
|
return g(n, wr(t, 3), lt, !0)
|
|
}, yn.floor = mi, yn.forEach = ne, yn.forEachRight = te, yn.forIn = function(n, t) {
|
|
return null == n ? n : Hu(n, Dr(t), Ne)
|
|
}, yn.forInRight = function(n, t) {
|
|
return null == n ? n : Qu(n, Dr(t), Ne)
|
|
}, yn.forOwn = function(n, t) {
|
|
return n && at(n, Dr(t))
|
|
}, yn.forOwnRight = function(n, t) {
|
|
return n && lt(n, Dr(t))
|
|
}, yn.get = Me, yn.gt = he, yn.gte = function(n, t) {
|
|
return n >= t
|
|
}, yn.has = Le, yn.hasIn = $e, yn.head = Tr, yn.identity = Ve, yn.includes = function(n, t, r, e) {
|
|
return n = _e(n) ? n : Ze(n), r = r && !e ? We(r) : 0, e = n.length, 0 > r && (r = Wu(e + r, 0)), ke(n) ? e >= r && -1 < n.indexOf(t, r) : !!e && -1 < d(n, t, r)
|
|
}, yn.indexOf = function(n, t, r) {
|
|
var e = n ? n.length : 0;
|
|
return e ? (r = We(r), 0 > r && (r = Wu(e + r, 0)), d(n, t, r)) : -1
|
|
}, yn.inRange = function(n, t, r) {
|
|
return t = Ce(t) || 0, r === Z ? (r = t, t = 0) : r = Ce(r) || 0, n = Ce(n), n >= Bu(t, r) && n < Wu(t, r)
|
|
}, yn.invoke = Ho, yn.isArguments = pe, yn.isArray = No, yn.isArrayBuffer = function(n) {
|
|
return je(n) && "[object ArrayBuffer]" == su.call(n)
|
|
}, yn.isArrayLike = _e, yn.isArrayLikeObject = ge, yn.isBoolean = function(n) {
|
|
return !0 === n || !1 === n || je(n) && "[object Boolean]" == su.call(n)
|
|
}, yn.isBuffer = Do, yn.isDate = function(n) {
|
|
return je(n) && "[object Date]" == su.call(n)
|
|
}, yn.isElement = function(n) {
|
|
return !!n && 1 === n.nodeType && je(n) && !Ae(n)
|
|
}, yn.isEmpty = function(n) {
|
|
if (_e(n) && (No(n) || ke(n) || de(n.splice) || pe(n))) return !n.length;
|
|
for (var t in n)
|
|
if (cu.call(n, t)) return !1;
|
|
return !0
|
|
}, yn.isEqual = function(n, t) {
|
|
return yt(n, t)
|
|
}, yn.isEqualWith = function(n, t, r) {
|
|
var e = (r = "function" == typeof r ? r : Z) ? r(n, t) : Z;
|
|
return e === Z ? yt(n, t, r) : !!e
|
|
}, yn.isError = ve, yn.isFinite = function(n) {
|
|
return "number" == typeof n && Iu(n)
|
|
}, yn.isFunction = de, yn.isInteger = ye, yn.isLength = be, yn.isMap = function(n) {
|
|
return je(n) && "[object Map]" == kr(n)
|
|
}, yn.isMatch = function(n, t) {
|
|
return n === t || bt(n, t, Ar(t))
|
|
}, yn.isMatchWith = function(n, t, r) {
|
|
return r = "function" == typeof r ? r : Z, bt(n, t, Ar(t), r)
|
|
}, yn.isNaN = function(n) {
|
|
return we(n) && n != +n
|
|
}, yn.isNative = me, yn.isNil = function(n) {
|
|
return null == n
|
|
}, yn.isNull = function(n) {
|
|
return null === n
|
|
}, yn.isNumber = we, yn.isObject = xe, yn.isObjectLike = je, yn.isPlainObject = Ae, yn.isRegExp = Oe, yn.isSafeInteger = function(n) {
|
|
return ye(n) && n >= -9007199254740991 && 9007199254740991 >= n
|
|
}, yn.isSet = function(n) {
|
|
return je(n) && "[object Set]" == kr(n)
|
|
}, yn.isString = ke, yn.isSymbol = Ee, yn.isTypedArray = Ie, yn.isUndefined = function(n) {
|
|
return n === Z
|
|
}, yn.isWeakMap = function(n) {
|
|
return je(n) && "[object WeakMap]" == kr(n)
|
|
}, yn.isWeakSet = function(n) {
|
|
return je(n) && "[object WeakSet]" == su.call(n)
|
|
}, yn.join = function(n, t) {
|
|
return n ? Su.call(n, t) : ""
|
|
}, yn.kebabCase = ei, yn.last = Kr, yn.lastIndexOf = function(n, t, r) {
|
|
var e = n ? n.length : 0;
|
|
if (!e) return -1;
|
|
var u = e;
|
|
if (r !== Z && (u = We(r), u = (0 > u ? Wu(e + u, 0) : Bu(u, e - 1)) + 1), t !== t) return B(n, u, !0);
|
|
for (; u--;)
|
|
if (n[u] === t) return u;
|
|
return -1
|
|
}, yn.lowerCase = ui, yn.lowerFirst = oi, yn.lt = Se, yn.lte = function(n, t) {
|
|
return t >= n
|
|
}, yn.max = function(n) {
|
|
return n && n.length ? _(n, Ve, he) : Z
|
|
}, yn.maxBy = function(n, t) {
|
|
return n && n.length ? _(n, wr(t), he) : Z
|
|
}, yn.mean = function(n) {
|
|
return Xe(n) / (n ? n.length : 0)
|
|
}, yn.min = function(n) {
|
|
return n && n.length ? _(n, Ve, Se) : Z
|
|
}, yn.minBy = function(n, t) {
|
|
return n && n.length ? _(n, wr(t), Se) : Z
|
|
}, yn.noConflict = function() {
|
|
return Vn._ === this && (Vn._ = hu), this
|
|
}, yn.noop = He, yn.now = Wo, yn.pad = function(n, t, r) {
|
|
n = ze(n), t = We(t);
|
|
var e = F(n);
|
|
return t && t > e ? (e = (t - e) / 2, t = Eu(e), e = ku(e), pr("", t, r) + n + pr("", e, r)) : n
|
|
}, yn.padEnd = function(n, t, r) {
|
|
return n = ze(n), n + pr(n, t, r)
|
|
}, yn.padStart = function(n, t, r) {
|
|
return n = ze(n), pr(n, t, r) + n
|
|
}, yn.parseInt = function(n, t, r) {
|
|
return r || null == t ? t = 0 : t && (t = +t), n = ze(n).replace(fn, ""), Cu(n, t || (pn.test(n) ? 16 : 10))
|
|
}, yn.random = function(n, t, r) {
|
|
if (r && "boolean" != typeof r && Br(n, t, r) && (t = r = Z), r === Z && ("boolean" == typeof t ? (r = t, t = Z) : "boolean" == typeof n && (r = n, n = Z)), n === Z && t === Z ? (n = 0, t = 1) : (n = Ce(n) || 0, t === Z ? (t = n, n = 0) : t = Ce(t) || 0), n > t) {
|
|
var e = n;
|
|
n = t, t = e
|
|
}
|
|
return r || n % 1 || t % 1 ? (r = Uu(), Bu(n + r * (t - n + Fn("1e-" + ((r + "").length - 1))), t)) : Ct(n, t)
|
|
}, yn.reduce = function(n, t, r) {
|
|
var e = No(n) ? s : y,
|
|
u = 3 > arguments.length;
|
|
return e(n, wr(t, 4), r, u, Ju)
|
|
}, yn.reduceRight = function(n, t, r) {
|
|
var e = No(n) ? h : y,
|
|
u = 3 > arguments.length;
|
|
return e(n, wr(t, 4), r, u, Yu)
|
|
}, yn.repeat = Te, yn.replace = function() {
|
|
var n = arguments,
|
|
t = ze(n[0]);
|
|
return 3 > n.length ? t : t.replace(n[1], n[2])
|
|
}, yn.result = function(n, t, r) {
|
|
if (Cr(t, n)) e = null == n ? Z : n[t];
|
|
else {
|
|
t = Nt(t);
|
|
var e = Me(n, t);
|
|
n = $r(n, t)
|
|
}
|
|
return e === Z && (e = r), de(e) ? e.call(n) : e
|
|
}, yn.round = wi, yn.runInContext = D, yn.sample = function(n) {
|
|
n = _e(n) ? n : Ze(n);
|
|
var t = n.length;
|
|
return t > 0 ? n[Ct(0, t - 1)] : Z
|
|
}, yn.size = function(n) {
|
|
if (null == n) return 0;
|
|
if (_e(n)) {
|
|
var t = n.length;
|
|
return t && ke(n) ? F(n) : t
|
|
}
|
|
return Fe(n).length
|
|
}, yn.snakeCase = fi, yn.some = function(n, t, r) {
|
|
var e = No(n) ? p : Mt;
|
|
return r && Br(n, t, r) && (t = Z), e(n, wr(t, 3))
|
|
}, yn.sortedIndex = function(n, t) {
|
|
return Lt(n, t)
|
|
}, yn.sortedIndexBy = function(n, t, r) {
|
|
return $t(n, t, wr(r))
|
|
}, yn.sortedIndexOf = function(n, t) {
|
|
var r = n ? n.length : 0;
|
|
if (r) {
|
|
var e = Lt(n, t);
|
|
if (r > e && se(n[e], t)) return e
|
|
}
|
|
return -1
|
|
}, yn.sortedLastIndex = function(n, t) {
|
|
return Lt(n, t, !0)
|
|
}, yn.sortedLastIndexBy = function(n, t, r) {
|
|
return $t(n, t, wr(r), !0)
|
|
}, yn.sortedLastIndexOf = function(n, t) {
|
|
if (n && n.length) {
|
|
var r = Lt(n, t, !0) - 1;
|
|
if (se(n[r], t)) return r
|
|
}
|
|
return -1
|
|
}, yn.startCase = ci, yn.startsWith = function(n, t, r) {
|
|
return n = ze(n), r = nt(We(r), 0, n.length), n.lastIndexOf(t, r) == r
|
|
}, yn.subtract = function(n, t) {
|
|
var r;
|
|
return n === Z && t === Z ? 0 : (n !== Z && (r = n), t !== Z && (r = r === Z ? t : r - t), r)
|
|
}, yn.sum = Xe, yn.sumBy = function(n, t) {
|
|
return n && n.length ? x(n, wr(t)) : 0
|
|
}, yn.template = function(n, t, r) {
|
|
var e = yn.templateSettings;
|
|
r && Br(n, t, r) && (t = Z), n = ze(n), t = Po({}, t, e, Tn), r = Po({}, t.imports, e.imports, Tn);
|
|
var u, o, i = Fe(r),
|
|
f = A(r, i),
|
|
c = 0;
|
|
r = t.interpolate || xn;
|
|
var a = "__p+='";
|
|
r = eu((t.escape || xn).source + "|" + r.source + "|" + (r === nn ? sn : xn).source + "|" + (t.evaluate || xn).source + "|$", "g");
|
|
var l = "sourceURL" in t ? "//# sourceURL=" + t.sourceURL + "\n" : "";
|
|
if (n.replace(r, function(t, r, e, i, f, l) {
|
|
return e || (e = i), a += n.slice(c, l).replace(jn, W), r && (u = !0, a += "'+__e(" + r + ")+'"), f && (o = !0, a += "';" + f + ";\n__p+='"), e && (a += "'+((__t=(" + e + "))==null?'':__t)+'"), c = l + t.length, t
|
|
}), a += "';", (t = t.variable) || (a = "with(obj){" + a + "}"), a = (o ? a.replace(T, "") : a).replace(K, "$1").replace(G, "$1;"), a = "function(" + (t || "obj") + "){" + (t ? "" : "obj||(obj={});") + "var __t,__p=''" + (u ? ",__e=_.escape" : "") + (o ? ",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}" : ";") + a + "return __p}", t = li(function() {
|
|
return Function(i, l + "return " + a).apply(Z, f)
|
|
}), t.source = a, ve(t)) throw t;
|
|
return t
|
|
}, yn.times = function(n, t) {
|
|
if (n = We(n), 1 > n || n > 9007199254740991) return [];
|
|
var r = 4294967295,
|
|
e = Bu(n, 4294967295);
|
|
for (t = Dr(t), n -= 4294967295, e = j(e, t); ++r < n;) t(r);
|
|
return e
|
|
}, yn.toInteger = We, yn.toLength = Be, yn.toLower = function(n) {
|
|
return ze(n).toLowerCase()
|
|
}, yn.toNumber = Ce, yn.toSafeInteger = function(n) {
|
|
return nt(We(n), -9007199254740991, 9007199254740991)
|
|
}, yn.toString = ze, yn.toUpper = function(n) {
|
|
return ze(n).toUpperCase()
|
|
}, yn.trim = function(n, t, r) {
|
|
return (n = ze(n)) ? r || t === Z ? n.replace(fn, "") : (t += "") ? (n = n.match(kn), t = t.match(kn), n.slice(O(n, t), k(n, t) + 1).join("")) : n : n
|
|
}, yn.trimEnd = function(n, t, r) {
|
|
return (n = ze(n)) ? r || t === Z ? n.replace(an, "") : (t += "") ? (n = n.match(kn), n.slice(0, k(n, t.match(kn)) + 1).join("")) : n : n
|
|
}, yn.trimStart = function(n, t, r) {
|
|
return (n = ze(n)) ? r || t === Z ? n.replace(cn, "") : (t += "") ? (n = n.match(kn), n.slice(O(n, t.match(kn))).join("")) : n : n
|
|
}, yn.truncate = function(n, t) {
|
|
var r = 30,
|
|
e = "...";
|
|
if (xe(t)) var u = "separator" in t ? t.separator : u,
|
|
r = "length" in t ? We(t.length) : r,
|
|
e = "omission" in t ? ze(t.omission) : e;
|
|
n = ze(n);
|
|
var o = n.length;
|
|
if (En.test(n)) var i = n.match(kn),
|
|
o = i.length;
|
|
if (r >= o) return n;
|
|
if (o = r - F(e), 1 > o) return e;
|
|
if (r = i ? i.slice(0, o).join("") : n.slice(0, o), u === Z) return r + e;
|
|
if (i && (o += r.length - o), Oe(u)) {
|
|
if (n.slice(o).search(u)) {
|
|
var f = r;
|
|
for (u.global || (u = eu(u.source, ze(hn.exec(u)) + "g")), u.lastIndex = 0; i = u.exec(f);) var c = i.index;
|
|
r = r.slice(0, c === Z ? o : c)
|
|
}
|
|
} else n.indexOf(u, o) != o && (u = r.lastIndexOf(u), u > -1 && (r = r.slice(0, u)));
|
|
return r + e
|
|
}, yn.unescape = function(n) {
|
|
return (n = ze(n)) && Y.test(n) ? n.replace(V, N) : n
|
|
}, yn.uniqueId = function(n) {
|
|
var t = ++au;
|
|
return ze(n) + t
|
|
}, yn.upperCase = ai, yn.upperFirst = ii, yn.each = ne, yn.eachRight = te, yn.first = Tr, Ye(yn, function() {
|
|
var n = {};
|
|
return at(yn, function(t, r) {
|
|
cu.call(yn.prototype, r) || (n[r] = t);
|
|
}), n
|
|
}(), {
|
|
chain: !1
|
|
}), yn.VERSION = "4.3.0", u("bind bindKey curry curryRight partial partialRight".split(" "), function(n) {
|
|
yn[n].placeholder = yn
|
|
}), u(["drop", "take"], function(n, t) {
|
|
An.prototype[n] = function(r) {
|
|
var e = this.__filtered__;
|
|
if (e && !t) return new An(this);
|
|
r = r === Z ? 1 : Wu(We(r), 0);
|
|
var u = this.clone();
|
|
return e ? u.__takeCount__ = Bu(r, u.__takeCount__) : u.__views__.push({
|
|
size: Bu(r, 4294967295),
|
|
type: n + (0 > u.__dir__ ? "Right" : "")
|
|
}), u
|
|
}, An.prototype[n + "Right"] = function(t) {
|
|
return this.reverse()[n](t).reverse()
|
|
}
|
|
}), u(["filter", "map", "takeWhile"], function(n, t) {
|
|
var r = t + 1,
|
|
e = 1 == r || 3 == r;
|
|
An.prototype[n] = function(n) {
|
|
var t = this.clone();
|
|
return t.__iteratees__.push({
|
|
iteratee: wr(n, 3),
|
|
type: r
|
|
}), t.__filtered__ = t.__filtered__ || e, t
|
|
}
|
|
}), u(["head", "last"], function(n, t) {
|
|
var r = "take" + (t ? "Right" : "");
|
|
An.prototype[n] = function() {
|
|
return this[r](1).value()[0]
|
|
}
|
|
}), u(["initial", "tail"], function(n, t) {
|
|
var r = "drop" + (t ? "" : "Right");
|
|
An.prototype[n] = function() {
|
|
return this.__filtered__ ? new An(this) : this[r](1)
|
|
}
|
|
}), An.prototype.compact = function() {
|
|
return this.filter(Ve)
|
|
}, An.prototype.find = function(n) {
|
|
return this.filter(n).head()
|
|
}, An.prototype.findLast = function(n) {
|
|
return this.reverse().find(n)
|
|
}, An.prototype.invokeMap = le(function(n, t) {
|
|
return "function" == typeof n ? new An(this) : this.map(function(r) {
|
|
return dt(r, n, t)
|
|
})
|
|
}), An.prototype.reject = function(n) {
|
|
return n = wr(n, 3), this.filter(function(t) {
|
|
return !n(t)
|
|
})
|
|
}, An.prototype.slice = function(n, t) {
|
|
n = We(n);
|
|
var r = this;
|
|
return r.__filtered__ && (n > 0 || 0 > t) ? new An(r) : (0 > n ? r = r.takeRight(-n) : n && (r = r.drop(n)), t !== Z && (t = We(t), r = 0 > t ? r.dropRight(-t) : r.take(t - n)), r)
|
|
}, An.prototype.takeRightWhile = function(n) {
|
|
return this.reverse().takeWhile(n).reverse()
|
|
}, An.prototype.toArray = function() {
|
|
return this.take(4294967295)
|
|
}, at(An.prototype, function(n, t) {
|
|
var r = /^(?:filter|find|map|reject)|While$/.test(t),
|
|
e = /^(?:head|last)$/.test(t),
|
|
u = yn[e ? "take" + ("last" == t ? "Right" : "") : t],
|
|
o = e || /^find/.test(t);
|
|
u && (yn.prototype[t] = function() {
|
|
var t = this.__wrapped__,
|
|
i = e ? [1] : arguments,
|
|
f = t instanceof An,
|
|
c = i[0],
|
|
a = f || No(t),
|
|
s = function(n) {
|
|
return n = u.apply(yn, l([n], i)), e && h ? n[0] : n
|
|
};
|
|
a && r && "function" == typeof c && 1 != c.length && (f = a = !1);
|
|
var h = this.__chain__,
|
|
p = !!this.__actions__.length,
|
|
c = o && !h,
|
|
f = f && !p;
|
|
return !o && a ? (t = f ? t : new An(this), t = n.apply(t, i), t.__actions__.push({
|
|
func: Qr,
|
|
args: [s],
|
|
thisArg: Z
|
|
}), new wn(t, h)) : c && f ? n.apply(this, i) : (t = this.thru(s), c ? e ? t.value()[0] : t.value() : t)
|
|
})
|
|
}), u("pop push shift sort splice unshift".split(" "), function(n) {
|
|
var t = ou[n],
|
|
r = /^(?:push|sort|unshift)$/.test(n) ? "tap" : "thru",
|
|
e = /^(?:pop|shift)$/.test(n);
|
|
yn.prototype[n] = function() {
|
|
var n = arguments;
|
|
return e && !this.__chain__ ? t.apply(this.value(), n) : this[r](function(r) {
|
|
return t.apply(r, n)
|
|
})
|
|
}
|
|
}), at(An.prototype, function(n, t) {
|
|
var r = yn[t];
|
|
if (r) {
|
|
var e = r.name + "";
|
|
(Gu[e] || (Gu[e] = [])).push({
|
|
name: t,
|
|
func: r
|
|
})
|
|
}
|
|
}), Gu[lr(Z, 2).name] = [{
|
|
name: "wrapper",
|
|
func: Z
|
|
}], An.prototype.clone = function() {
|
|
var n = new An(this.__wrapped__);
|
|
return n.__actions__ = Yt(this.__actions__), n.__dir__ = this.__dir__, n.__filtered__ = this.__filtered__, n.__iteratees__ = Yt(this.__iteratees__), n.__takeCount__ = this.__takeCount__, n.__views__ = Yt(this.__views__), n
|
|
}, An.prototype.reverse = function() {
|
|
if (this.__filtered__) {
|
|
var n = new An(this);
|
|
n.__dir__ = -1, n.__filtered__ = !0
|
|
} else n = this.clone(), n.__dir__ *= -1;
|
|
return n
|
|
}, An.prototype.value = function() {
|
|
var n, t = this.__wrapped__.value(),
|
|
r = this.__dir__,
|
|
e = No(t),
|
|
u = 0 > r,
|
|
o = e ? t.length : 0;
|
|
n = 0;
|
|
for (var i = o, f = this.__views__, c = -1, a = f.length; ++c < a;) {
|
|
var l = f[c],
|
|
s = l.size;
|
|
switch (l.type) {
|
|
case "drop":
|
|
n += s;
|
|
break;
|
|
case "dropRight":
|
|
i -= s;
|
|
break;
|
|
case "take":
|
|
i = Bu(i, n + s);
|
|
break;
|
|
case "takeRight":
|
|
n = Wu(n, i - s)
|
|
}
|
|
}
|
|
if (n = {
|
|
start: n,
|
|
end: i
|
|
}, i = n.start, f = n.end, n = f - i, u = u ? f : i - 1, i = this.__iteratees__, f = i.length, c = 0, a = Bu(n, this.__takeCount__), !e || 200 > o || o == n && a == n) return qt(t, this.__actions__);
|
|
e = [];
|
|
n: for (; n-- && a > c;) {
|
|
for (u += r, o = -1, l = t[u]; ++o < f;) {
|
|
var h = i[o],
|
|
s = h.type,
|
|
h = (0, h.iteratee)(l);
|
|
if (2 == s) l = h;
|
|
else if (!h) {
|
|
if (1 == s) continue n;
|
|
break n
|
|
}
|
|
}
|
|
e[c++] = l
|
|
}
|
|
return e
|
|
}, yn.prototype.at = Ao, yn.prototype.chain = function() {
|
|
return Hr(this)
|
|
}, yn.prototype.commit = function() {
|
|
return new wn(this.value(), this.__chain__)
|
|
}, yn.prototype.flatMap = function(n) {
|
|
return this.map(n).flatten()
|
|
}, yn.prototype.next = function() {
|
|
this.__values__ === Z && (this.__values__ = Re(this.value()));
|
|
var n = this.__index__ >= this.__values__.length,
|
|
t = n ? Z : this.__values__[this.__index__++];
|
|
return {
|
|
done: n,
|
|
value: t
|
|
}
|
|
}, yn.prototype.plant = function(n) {
|
|
for (var t, r = this; r instanceof mn;) {
|
|
var e = Zr(r);
|
|
e.__index__ = 0, e.__values__ = Z, t ? u.__wrapped__ = e : t = e;
|
|
var u = e,
|
|
r = r.__wrapped__
|
|
}
|
|
return u.__wrapped__ = n, t
|
|
}, yn.prototype.reverse = function() {
|
|
var n = this.__wrapped__;
|
|
return n instanceof An ? (this.__actions__.length && (n = new An(this)), n = n.reverse(), n.__actions__.push({
|
|
func: Qr,
|
|
args: [Vr],
|
|
thisArg: Z
|
|
}), new wn(n, this.__chain__)) : this.thru(Vr)
|
|
}, yn.prototype.toJSON = yn.prototype.valueOf = yn.prototype.value = function() {
|
|
return qt(this.__wrapped__, this.__actions__)
|
|
}, mu && (yn.prototype[mu] = Xr), yn
|
|
}
|
|
var Z, q = 1 / 0,
|
|
P = NaN,
|
|
T = /\b__p\+='';/g,
|
|
K = /\b(__p\+=)''\+/g,
|
|
G = /(__e\(.*?\)|\b__t\))\+'';/g,
|
|
V = /&(?:amp|lt|gt|quot|#39|#96);/g,
|
|
J = /[&<>"'`]/g,
|
|
Y = RegExp(V.source),
|
|
H = RegExp(J.source),
|
|
Q = /<%-([\s\S]+?)%>/g,
|
|
X = /<%([\s\S]+?)%>/g,
|
|
nn = /<%=([\s\S]+?)%>/g,
|
|
tn = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
|
|
rn = /^\w*$/,
|
|
en = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g,
|
|
un = /[\\^$.*+?()[\]{}|]/g,
|
|
on = RegExp(un.source),
|
|
fn = /^\s+|\s+$/g,
|
|
cn = /^\s+/,
|
|
an = /\s+$/,
|
|
ln = /\\(\\)?/g,
|
|
sn = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,
|
|
hn = /\w*$/,
|
|
pn = /^0x/i,
|
|
_n = /^[-+]0x[0-9a-f]+$/i,
|
|
gn = /^0b[01]+$/i,
|
|
vn = /^\[object .+?Constructor\]$/,
|
|
dn = /^0o[0-7]+$/i,
|
|
yn = /^(?:0|[1-9]\d*)$/,
|
|
bn = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g,
|
|
xn = /($^)/,
|
|
jn = /['\n\r\u2028\u2029\\]/g,
|
|
mn = "[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|\\ud83c[\\udffb-\\udfff])?(?:\\u200d(?:[^\\ud800-\\udfff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|\\ud83c[\\udffb-\\udfff])?)*",
|
|
wn = "(?:[\\u2700-\\u27bf]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])" + mn,
|
|
An = "(?:[^\\ud800-\\udfff][\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]?|[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff])",
|
|
On = RegExp("[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]", "g"),
|
|
kn = RegExp("\\ud83c[\\udffb-\\udfff](?=\\ud83c[\\udffb-\\udfff])|" + An + mn, "g"),
|
|
En = RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0\\ufe0e\\ufe0f]"),
|
|
In = /[a-zA-Z0-9]+/g,
|
|
Sn = RegExp(["[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde]|$)|(?:[A-Z\\xc0-\\xd6\\xd8-\\xde]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde](?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])|$)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?(?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+|[A-Z\\xc0-\\xd6\\xd8-\\xde]+|\\d+", wn].join("|"), "g"),
|
|
Rn = /[a-z][A-Z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,
|
|
Wn = "Array Buffer Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Map Math Object Reflect RegExp Set String Symbol TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap _ clearTimeout isFinite parseInt setTimeout".split(" "),
|
|
Bn = {};
|
|
Bn["[object Float32Array]"] = Bn["[object Float64Array]"] = Bn["[object Int8Array]"] = Bn["[object Int16Array]"] = Bn["[object Int32Array]"] = Bn["[object Uint8Array]"] = Bn["[object Uint8ClampedArray]"] = Bn["[object Uint16Array]"] = Bn["[object Uint32Array]"] = !0, Bn["[object Arguments]"] = Bn["[object Array]"] = Bn["[object ArrayBuffer]"] = Bn["[object Boolean]"] = Bn["[object Date]"] = Bn["[object Error]"] = Bn["[object Function]"] = Bn["[object Map]"] = Bn["[object Number]"] = Bn["[object Object]"] = Bn["[object RegExp]"] = Bn["[object Set]"] = Bn["[object String]"] = Bn["[object WeakMap]"] = !1;
|
|
var Cn = {};
|
|
Cn["[object Arguments]"] = Cn["[object Array]"] = Cn["[object ArrayBuffer]"] = Cn["[object Boolean]"] = Cn["[object Date]"] = Cn["[object Float32Array]"] = Cn["[object Float64Array]"] = Cn["[object Int8Array]"] = Cn["[object Int16Array]"] = Cn["[object Int32Array]"] = Cn["[object Map]"] = Cn["[object Number]"] = Cn["[object Object]"] = Cn["[object RegExp]"] = Cn["[object Set]"] = Cn["[object String]"] = Cn["[object Symbol]"] = Cn["[object Uint8Array]"] = Cn["[object Uint8ClampedArray]"] = Cn["[object Uint16Array]"] = Cn["[object Uint32Array]"] = !0, Cn["[object Error]"] = Cn["[object Function]"] = Cn["[object WeakMap]"] = !1;
|
|
var Un = {
|
|
"À": "A",
|
|
"Á": "A",
|
|
"Â": "A",
|
|
"Ã": "A",
|
|
"Ä": "A",
|
|
"Å": "A",
|
|
"à": "a",
|
|
"á": "a",
|
|
"â": "a",
|
|
"ã": "a",
|
|
"ä": "a",
|
|
"å": "a",
|
|
"Ç": "C",
|
|
"ç": "c",
|
|
"Ð": "D",
|
|
"ð": "d",
|
|
"È": "E",
|
|
"É": "E",
|
|
"Ê": "E",
|
|
"Ë": "E",
|
|
"è": "e",
|
|
"é": "e",
|
|
"ê": "e",
|
|
"ë": "e",
|
|
"Ì": "I",
|
|
"Í": "I",
|
|
"Î": "I",
|
|
"Ï": "I",
|
|
"ì": "i",
|
|
"í": "i",
|
|
"î": "i",
|
|
"ï": "i",
|
|
"Ñ": "N",
|
|
"ñ": "n",
|
|
"Ò": "O",
|
|
"Ó": "O",
|
|
"Ô": "O",
|
|
"Õ": "O",
|
|
"Ö": "O",
|
|
"Ø": "O",
|
|
"ò": "o",
|
|
"ó": "o",
|
|
"ô": "o",
|
|
"õ": "o",
|
|
"ö": "o",
|
|
"ø": "o",
|
|
"Ù": "U",
|
|
"Ú": "U",
|
|
"Û": "U",
|
|
"Ü": "U",
|
|
"ù": "u",
|
|
"ú": "u",
|
|
"û": "u",
|
|
"ü": "u",
|
|
"Ý": "Y",
|
|
"ý": "y",
|
|
"ÿ": "y",
|
|
"Æ": "Ae",
|
|
"æ": "ae",
|
|
"Þ": "Th",
|
|
"þ": "th",
|
|
"ß": "ss"
|
|
},
|
|
zn = {
|
|
"&": "&",
|
|
"<": "<",
|
|
">": ">",
|
|
'"': """,
|
|
"'": "'",
|
|
"`": "`"
|
|
},
|
|
Mn = {
|
|
"&": "&",
|
|
"<": "<",
|
|
">": ">",
|
|
""": '"',
|
|
"'": "'",
|
|
"`": "`"
|
|
},
|
|
Ln = {
|
|
"function": !0,
|
|
object: !0
|
|
},
|
|
$n = {
|
|
"\\": "\\",
|
|
"'": "'",
|
|
"\n": "n",
|
|
"\r": "r",
|
|
"\u2028": "u2028",
|
|
"\u2029": "u2029"
|
|
},
|
|
Fn = parseFloat,
|
|
Nn = parseInt,
|
|
Dn = Ln[typeof exports] && exports && !exports.nodeType ? exports : null,
|
|
Zn = Ln[typeof module] && module && !module.nodeType ? module : null,
|
|
qn = E(Dn && Zn && "object" == typeof global && global),
|
|
Pn = E(Ln[typeof self] && self),
|
|
Tn = E(Ln[typeof window] && window),
|
|
Kn = Zn && Zn.exports === Dn ? Dn : null,
|
|
Gn = E(Ln[typeof this] && this),
|
|
Vn = qn || Tn !== (Gn && Gn.window) && Tn || Pn || Gn || Function("return this")(),
|
|
Jn = D();
|
|
(Tn || Pn || {})._ = Jn, "function" == typeof define && "object" == typeof define.amd && define.amd ? define(function() {
|
|
return Jn
|
|
}) : Dn && Zn ? (Kn && ((Zn.exports = Jn)._ = Jn), Dn._ = Jn) : Vn._ = Jn
|
|
}.call(this);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.Util = Bahmni.Common.Util || {}, angular.module("bahmni.common.util", []).provider("$bahmniCookieStore", [function() {
|
|
var self = this;
|
|
self.defaultOptions = {};
|
|
var fixedEncodeURIComponent = function(str) {
|
|
return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
|
|
return "%" + c.charCodeAt(0).toString(16)
|
|
})
|
|
};
|
|
self.setDefaultOptions = function(options) {
|
|
self.defaultOptions = options
|
|
}, self.$get = function() {
|
|
return {
|
|
get: function(name) {
|
|
var jsonCookie = $.cookie(name);
|
|
return jsonCookie ? angular.fromJson(decodeURIComponent(jsonCookie)) : null
|
|
},
|
|
put: function(name, value, options) {
|
|
options = $.extend({}, self.defaultOptions, options), $.cookie.raw = !0, $.cookie(name, fixedEncodeURIComponent(angular.toJson(value)), options)
|
|
},
|
|
remove: function(name, options) {
|
|
options = $.extend({}, self.defaultOptions, options), $.removeCookie(name, options)
|
|
}
|
|
}
|
|
}
|
|
}]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.Models = Bahmni.Common.Models || {}, angular.module("bahmni.common.models", []), angular.module("bahmni.common.models").factory("age", [function() {
|
|
var dateUtil = Bahmni.Common.Util.DateUtil,
|
|
fromBirthDate = function(birthDate) {
|
|
var today = dateUtil.now(),
|
|
period = dateUtil.diffInYearsMonthsDays(birthDate, today);
|
|
return create(period.years, period.months, period.days)
|
|
},
|
|
create = function(years, months, days) {
|
|
var isEmpty = function() {
|
|
return !(this.years || this.months || this.days)
|
|
};
|
|
return {
|
|
years: years,
|
|
months: months,
|
|
days: days,
|
|
isEmpty: isEmpty
|
|
}
|
|
},
|
|
calculateBirthDate = function(age) {
|
|
var birthDate = dateUtil.now();
|
|
return birthDate = dateUtil.subtractYears(birthDate, age.years), birthDate = dateUtil.subtractMonths(birthDate, age.months), birthDate = dateUtil.subtractDays(birthDate, age.days)
|
|
};
|
|
return {
|
|
fromBirthDate: fromBirthDate,
|
|
create: create,
|
|
calculateBirthDate: calculateBirthDate
|
|
}
|
|
}]), Bahmni.Common.AuditLogEventDetails = {
|
|
USER_LOGIN_SUCCESS: {
|
|
eventType: "USER_LOGIN_SUCCESS",
|
|
message: "USER_LOGIN_SUCCESS_MESSAGE"
|
|
},
|
|
USER_LOGIN_FAILED: {
|
|
eventType: "USER_LOGIN_FAILED",
|
|
message: "USER_LOGIN_FAILED_MESSAGE"
|
|
},
|
|
USER_LOGOUT_SUCCESS: {
|
|
eventType: "USER_LOGOUT_SUCCESS",
|
|
message: "USER_LOGOUT_SUCCESS_MESSAGE"
|
|
},
|
|
OPEN_VISIT: {
|
|
eventType: "OPEN_VISIT",
|
|
message: "OPEN_VISIT_MESSAGE"
|
|
},
|
|
EDIT_VISIT: {
|
|
eventType: "EDIT_VISIT",
|
|
message: "EDIT_VISIT_MESSAGE"
|
|
},
|
|
CLOSE_VISIT: {
|
|
eventType: "CLOSE_VISIT",
|
|
message: "CLOSE_VISIT_MESSAGE"
|
|
},
|
|
CLOSE_VISIT_FAILED: {
|
|
eventType: "CLOSE_VISIT_FAILED",
|
|
message: "CLOSE_VISIT_FAILED_MESSAGE"
|
|
},
|
|
EDIT_ENCOUNTER: {
|
|
eventType: "EDIT_ENCOUNTER",
|
|
message: "EDIT_ENCOUNTER_MESSAGE"
|
|
},
|
|
VIEWED_REGISTRATION_PATIENT_SEARCH: {
|
|
eventType: "VIEWED_REGISTRATION_PATIENT_SEARCH",
|
|
message: "VIEWED_REGISTRATION_PATIENT_SEARCH_MESSAGE"
|
|
},
|
|
VIEWED_NEW_PATIENT_PAGE: {
|
|
eventType: "VIEWED_NEW_PATIENT_PAGE",
|
|
message: "VIEWED_NEW_PATIENT_PAGE_MESSAGE"
|
|
},
|
|
REGISTER_NEW_PATIENT: {
|
|
eventType: "REGISTER_NEW_PATIENT",
|
|
message: "REGISTER_NEW_PATIENT_MESSAGE"
|
|
},
|
|
EDIT_PATIENT_DETAILS: {
|
|
eventType: "EDIT_PATIENT_DETAILS",
|
|
message: "EDIT_PATIENT_DETAILS_MESSAGE"
|
|
},
|
|
ACCESSED_REGISTRATION_SECOND_PAGE: {
|
|
eventType: "ACCESSED_REGISTRATION_SECOND_PAGE",
|
|
message: "ACCESSED_REGISTRATION_SECOND_PAGE_MESSAGE"
|
|
},
|
|
VIEWED_PATIENT_DETAILS: {
|
|
eventType: "VIEWED_PATIENT_DETAILS",
|
|
message: "VIEWED_PATIENT_DETAILS_MESSAGE"
|
|
},
|
|
PRINT_PATIENT_STICKER: {
|
|
eventType: "PRINT_PATIENT_STICKER",
|
|
message: "PRINT_PATIENT_STICKER_MESSAGE"
|
|
},
|
|
VIEWED_CLINICAL_PATIENT_SEARCH: {
|
|
eventType: "VIEWED_CLINICAL_PATIENT_SEARCH",
|
|
message: "VIEWED_PATIENT_SEARCH_MESSAGE"
|
|
},
|
|
VIEWED_CLINICAL_DASHBOARD: {
|
|
eventType: "VIEWED_CLINICAL_DASHBOARD",
|
|
message: "VIEWED_CLINICAL_DASHBOARD_MESSAGE"
|
|
},
|
|
VIEWED_OBSERVATIONS_TAB: {
|
|
eventType: "VIEWED_OBSERVATIONS_TAB",
|
|
message: "VIEWED_OBSERVATIONS_TAB_MESSAGE"
|
|
},
|
|
VIEWED_DIAGNOSIS_TAB: {
|
|
eventType: "VIEWED_DIAGNOSIS_TAB",
|
|
message: "VIEWED_DIAGNOSIS_TAB_MESSAGE"
|
|
},
|
|
VIEWED_TREATMENT_TAB: {
|
|
eventType: "VIEWED_TREATMENT_TAB",
|
|
message: "VIEWED_TREATMENT_TAB_MESSAGE"
|
|
},
|
|
VIEWED_DISPOSITION_TAB: {
|
|
eventType: "VIEWED_DISPOSITION_TAB",
|
|
message: "VIEWED_DISPOSITION_TAB_MESSAGE"
|
|
},
|
|
VIEWED_DASHBOARD_SUMMARY: {
|
|
eventType: "VIEWED_DASHBOARD_SUMMARY",
|
|
message: "VIEWED_DASHBOARD_SUMMARY_MESSAGE"
|
|
},
|
|
VIEWED_ORDERS_TAB: {
|
|
eventType: "VIEWED_ORDERS_TAB",
|
|
message: "VIEWED_ORDERS_TAB_MESSAGE"
|
|
},
|
|
VIEWED_BACTERIOLOGY_TAB: {
|
|
eventType: "VIEWED_BACTERIOLOGY_TAB",
|
|
message: "VIEWED_BACTERIOLOGY_TAB_MESSAGE"
|
|
},
|
|
VIEWED_INVESTIGATION_TAB: {
|
|
eventType: "VIEWED_INVESTIGATION_TAB",
|
|
message: "VIEWED_INVESTIGATION_TAB_MESSAGE"
|
|
},
|
|
VIEWED_SUMMARY_PRINT: {
|
|
eventType: "VIEWED_SUMMARY_PRINT",
|
|
message: "VIEWED_SUMMARY_PRINT_MESSAGE"
|
|
},
|
|
VIEWED_VISIT_DASHBOARD: {
|
|
eventType: "VIEWED_VISIT_DASHBOARD",
|
|
message: "VIEWED_VISIT_DASHBOARD_MESSAGE"
|
|
},
|
|
VIEWED_VISIT_PRINT: {
|
|
eventType: "VIEWED_VISIT_PRINT",
|
|
message: "VIEWED_VISIT_PRINT_MESSAGE"
|
|
},
|
|
VIEWED_DASHBOARD_OBSERVATION: {
|
|
eventType: "VIEWED_DASHBOARD_OBSERVATION",
|
|
message: "VIEWED_DASHBOARD_OBSERVATION_MESSAGE"
|
|
},
|
|
VIEWED_PATIENTPROGRAM: {
|
|
eventType: "VIEWED_PATIENTPROGRAM",
|
|
message: "VIEWED_PATIENTPROGRAM_MESSAGE"
|
|
},
|
|
RUN_REPORT: {
|
|
eventType: "RUN_REPORT",
|
|
message: "RUN_REPORT_MESSAGE"
|
|
}
|
|
}, angular.module("bahmni.common.routeErrorHandler", ["ui.router"]).run(["$rootScope", function($rootScope) {
|
|
$rootScope.$on("$stateChangeError", function(event) {
|
|
event.preventDefault()
|
|
})
|
|
}]), Bahmni.Common.Util.DateUtil = {
|
|
diffInDays: function(dateFrom, dateTo) {
|
|
return Math.floor((this.parse(dateTo) - this.parse(dateFrom)) / 864e5)
|
|
},
|
|
diffInMinutes: function(dateFrom, dateTo) {
|
|
return moment(dateTo).diff(moment(dateFrom), "minutes")
|
|
},
|
|
diffInSeconds: function(dateFrom, dateTo) {
|
|
return moment(dateFrom).diff(moment(dateTo), "seconds")
|
|
},
|
|
isInvalid: function(date) {
|
|
return "Invalid Date" == date
|
|
},
|
|
diffInDaysRegardlessOfTime: function(dateFrom, dateTo) {
|
|
var from = new Date(dateFrom),
|
|
to = new Date(dateTo);
|
|
return from.setHours(0, 0, 0, 0), to.setHours(0, 0, 0, 0), Math.floor((to - from) / 864e5)
|
|
},
|
|
addSeconds: function(date, seconds) {
|
|
return moment(date).add(seconds, "seconds").toDate()
|
|
},
|
|
addMinutes: function(date, minutes) {
|
|
return this.addSeconds(date, 60 * minutes)
|
|
},
|
|
addDays: function(date, days) {
|
|
return moment(date).add(days, "day").toDate()
|
|
},
|
|
addMonths: function(date, months) {
|
|
return moment(date).add(months, "month").toDate()
|
|
},
|
|
addYears: function(date, years) {
|
|
return moment(date).add(years, "year").toDate()
|
|
},
|
|
subtractSeconds: function(date, seconds) {
|
|
return moment(date).subtract(seconds, "seconds").toDate()
|
|
},
|
|
subtractDays: function(date, days) {
|
|
return this.addDays(date, -1 * days)
|
|
},
|
|
subtractMonths: function(date, months) {
|
|
return this.addMonths(date, -1 * months)
|
|
},
|
|
subtractYears: function(date, years) {
|
|
return this.addYears(date, -1 * years)
|
|
},
|
|
createDays: function(startDate, endDate) {
|
|
for (var startDate = this.getDate(startDate), endDate = this.getDate(endDate), numberOfDays = this.diffInDays(startDate, endDate), days = [], i = 0; i <= numberOfDays; i++) days.push({
|
|
dayNumber: i + 1,
|
|
date: this.addDays(startDate, i)
|
|
});
|
|
return days
|
|
},
|
|
getDayNumber: function(referenceDate, date) {
|
|
return this.diffInDays(this.getDate(referenceDate), this.getDate(date)) + 1
|
|
},
|
|
getDateWithoutTime: function(datetime) {
|
|
return datetime ? moment(datetime).format("YYYY-MM-DD") : null
|
|
},
|
|
getDateWitTime: function(datetime) {
|
|
return datetime ? moment(datetime).format("YYYY-MM-DD HH:mm:ss") : null
|
|
},
|
|
getDateInMonthsAndYears: function(date, format) {
|
|
var format = format || "MMM YY",
|
|
dateRepresentation = isNaN(Number(date)) ? date : Number(date);
|
|
return moment(dateRepresentation).isValid() ? dateRepresentation ? moment(dateRepresentation).format(format) : null : date
|
|
},
|
|
formatDateWithTime: function(datetime) {
|
|
var dateRepresentation = isNaN(Number(datetime)) ? datetime : Number(datetime);
|
|
return moment(dateRepresentation).isValid() ? dateRepresentation ? moment(dateRepresentation).format("DD MMM YY h:mm a") : null : datetime
|
|
},
|
|
formatDateWithoutTime: function(date) {
|
|
var dateRepresentation = isNaN(Number(date)) ? date : Number(date);
|
|
return moment(dateRepresentation).isValid() ? dateRepresentation ? moment(dateRepresentation).format("DD MMM YY") : null : date
|
|
},
|
|
formatDateInStrictMode: function(date) {
|
|
var dateRepresentation = isNaN(Number(date)) ? date : Number(date);
|
|
return moment(dateRepresentation, "YYYY-MM-DD", !0).isValid() ? moment(dateRepresentation).format("DD MMM YY") : moment(dateRepresentation, "YYYY-MM-DDTHH:mm:ss.SSSZZ", !0).isValid() ? moment(dateRepresentation).format("DD MMM YY") : date
|
|
},
|
|
formatTime: function(date) {
|
|
var dateRepresentation = isNaN(Number(date)) ? date : Number(date);
|
|
return moment(dateRepresentation).isValid() ? dateRepresentation ? moment(dateRepresentation).format("h:mm a") : null : date
|
|
},
|
|
getDate: function(dateTime) {
|
|
return moment(this.parse(dateTime)).startOf("day").toDate()
|
|
},
|
|
parse: function(dateString) {
|
|
return dateString ? moment(dateString).toDate() : null
|
|
},
|
|
parseDatetime: function(dateTimeString) {
|
|
return dateTimeString ? moment(dateTimeString) : null
|
|
},
|
|
now: function() {
|
|
return new Date
|
|
},
|
|
today: function() {
|
|
return this.getDate(this.now())
|
|
},
|
|
endOfToday: function() {
|
|
return moment(this.parse(this.now())).endOf("day").toDate()
|
|
},
|
|
getDateWithoutHours: function(dateString) {
|
|
return moment(dateString).toDate().setHours(0, 0, 0, 0)
|
|
},
|
|
getDateTimeWithoutSeconds: function(dateString) {
|
|
return moment(dateString).toDate().setSeconds(0, 0)
|
|
},
|
|
isSameDateTime: function(date1, date2) {
|
|
if (null == date1 || null == date2) return !1;
|
|
var dateOne = this.parse(date1),
|
|
dateTwo = this.parse(date2);
|
|
return dateOne.getTime() == dateTwo.getTime()
|
|
},
|
|
isBeforeDate: function(date1, date2) {
|
|
return moment(date1).isBefore(moment(date2))
|
|
},
|
|
isSameDate: function(date1, date2) {
|
|
if (null == date1 || null == date2) return !1;
|
|
var dateOne = this.parse(date1),
|
|
dateTwo = this.parse(date2);
|
|
return dateOne.getFullYear() === dateTwo.getFullYear() && dateOne.getMonth() === dateTwo.getMonth() && dateOne.getDate() === dateTwo.getDate()
|
|
},
|
|
diffInYearsMonthsDays: function(dateFrom, dateTo) {
|
|
dateFrom = this.parse(dateFrom), dateTo = this.parse(dateTo);
|
|
var from = {
|
|
d: dateFrom.getDate(),
|
|
m: dateFrom.getMonth(),
|
|
y: dateFrom.getFullYear()
|
|
},
|
|
to = {
|
|
d: dateTo.getDate(),
|
|
m: dateTo.getMonth(),
|
|
y: dateTo.getFullYear()
|
|
},
|
|
age = {
|
|
d: 0,
|
|
m: 0,
|
|
y: 0
|
|
},
|
|
daysFebruary = to.y % 4 != 0 || to.y % 100 == 0 && to.y % 400 != 0 ? 28 : 29,
|
|
daysInMonths = [31, daysFebruary, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
return age.y = to.y - from.y, age.m = to.m - from.m, from.m > to.m && (age.y = age.y - 1, age.m = to.m - from.m + 12), age.d = to.d - from.d, from.d > to.d && (age.m = age.m - 1, from.m == to.m && (age.y = age.y - 1, age.m = age.m + 12), age.d = to.d - from.d + daysInMonths[parseInt(from.m)]), {
|
|
days: age.d,
|
|
months: age.m,
|
|
years: age.y
|
|
}
|
|
},
|
|
convertToUnits: function(minutes) {
|
|
var allUnits = {
|
|
Years: 525600,
|
|
Months: 43200,
|
|
Weeks: 10080,
|
|
Days: 1440,
|
|
Hours: 60,
|
|
Minutes: 1
|
|
},
|
|
durationRepresentation = function(value, unitName, unitValueInMinutes) {
|
|
return {
|
|
value: value,
|
|
unitName: unitName,
|
|
unitValueInMinutes: unitValueInMinutes,
|
|
allUnits: allUnits
|
|
}
|
|
};
|
|
for (var unitName in allUnits) {
|
|
var unitValueInMinutes = allUnits[unitName];
|
|
if ((minutes || 0 !== minutes) && minutes >= unitValueInMinutes && minutes % unitValueInMinutes === 0) return durationRepresentation(minutes / unitValueInMinutes, unitName, unitValueInMinutes)
|
|
}
|
|
return durationRepresentation(void 0, void 0, void 0)
|
|
},
|
|
getEndDateFromDuration: function(dateFrom, value, unit) {
|
|
dateFrom = this.parse(dateFrom);
|
|
var from = {
|
|
h: dateFrom.getHours(),
|
|
d: dateFrom.getDate(),
|
|
m: dateFrom.getMonth(),
|
|
y: dateFrom.getFullYear()
|
|
},
|
|
to = new Date(from.y, from.m, from.d, from.h);
|
|
return "Months" === unit ? to.setMonth(from.m + value) : "Weeks" === unit ? to.setDate(from.d + 7 * value) : "Days" === unit ? to.setDate(from.d + value) : "Hours" === unit && to.setHours(from.h + value), to
|
|
},
|
|
parseLongDateToServerFormat: function(longDate) {
|
|
return longDate ? moment(longDate).format("YYYY-MM-DDTHH:mm:ss.SSS") : null
|
|
},
|
|
parseServerDateToDate: function(longDate) {
|
|
return longDate ? moment(longDate, "YYYY-MM-DDTHH:mm:ss.SSSZZ").toDate() : null
|
|
},
|
|
getDateTimeInSpecifiedFormat: function(date, format) {
|
|
return date ? moment(date).format(format) : null
|
|
},
|
|
getISOString: function(date) {
|
|
return date ? moment(date).toDate().toISOString() : null
|
|
},
|
|
isBeforeTime: function(time, otherTime) {
|
|
return moment(time, "hh:mm a").format("YYYY-MM-DD")
|
|
}
|
|
}, Bahmni.Common.Util.AgeUtil = function() {
|
|
var differenceInMonths = function(date, anotherDate) {
|
|
var age = fromBirthDateTillReferenceDate(date, anotherDate);
|
|
return parseFloat((12 * age.years + age.months + age.days / 30).toFixed(3))
|
|
},
|
|
fromBirthDateTillReferenceDate = function(birthDate, referenceDate) {
|
|
var DateUtil = Bahmni.Common.Util.DateUtil;
|
|
referenceDate = referenceDate || DateUtil.now();
|
|
var period = DateUtil.diffInYearsMonthsDays(birthDate, referenceDate);
|
|
return {
|
|
years: period.years,
|
|
months: period.months,
|
|
days: period.days
|
|
}
|
|
},
|
|
monthsToAgeString = function(months) {
|
|
var age = monthsToAge(months),
|
|
ageString = "";
|
|
return age.years && (ageString += age.years + "y "), age.months && (ageString += age.months + "m "), age.days && (ageString += age.days + "d"), ageString
|
|
},
|
|
monthsToAge = function(months) {
|
|
var years = Math.floor(months / 12),
|
|
remainingMonths = Math.floor(months % 12),
|
|
days = Math.round(30 * (months - Math.floor(months)));
|
|
return {
|
|
years: years,
|
|
months: remainingMonths,
|
|
days: days
|
|
}
|
|
};
|
|
return {
|
|
monthsToAgeString: monthsToAgeString,
|
|
differenceInMonths: differenceInMonths
|
|
}
|
|
}(), Bahmni.Common.Util.ArrayUtil = {
|
|
chunk: function(array, chunkSize) {
|
|
for (var chunks = [], i = 0; i < array.length; i += chunkSize) chunks.push(array.slice(i, i + chunkSize));
|
|
return chunks
|
|
},
|
|
groupByPreservingOrder: function(records, groupingFunction, keyName, valueName) {
|
|
var groups = [];
|
|
return records.forEach(function(record) {
|
|
var recordKey = groupingFunction(record),
|
|
existingGroup = _.find(groups, function(group) {
|
|
return group[keyName] === recordKey
|
|
});
|
|
if (existingGroup) existingGroup[valueName].push(record);
|
|
else {
|
|
var newGroup = {};
|
|
newGroup[keyName] = recordKey, newGroup[valueName] = [record], groups.push(newGroup)
|
|
}
|
|
}), groups
|
|
}
|
|
}, angular.module("httpErrorInterceptor", []).config(["$httpProvider", function($httpProvider) {
|
|
var interceptor = ["$rootScope", "$q", function($rootScope, $q) {
|
|
function stringAfter(value, searchString) {
|
|
var indexOfFirstColon = value.indexOf(searchString);
|
|
return value.substr(indexOfFirstColon + 1).trim()
|
|
}
|
|
|
|
function getServerError(message) {
|
|
return stringAfter(message, ":")
|
|
}
|
|
|
|
function success(response) {
|
|
return response
|
|
}
|
|
|
|
function shouldRedirectToLogin(response) {
|
|
var errorMessage = response.data.error ? response.data.error.message : response.data;
|
|
if (errorMessage.search("HTTP Status 403 - Session timed out") > 0) return !0
|
|
}
|
|
|
|
function error(response) {
|
|
var data = response.data,
|
|
unexpectedError = "There was an unexpected issue on the server. Please try again";
|
|
if (500 === response.status) {
|
|
var errorMessage = data.error && data.error.message ? getServerError(data.error.message) : unexpectedError;
|
|
showError(errorMessage)
|
|
} else if (409 === response.status) {
|
|
var errorMessage = data.error && data.error.message ? getServerError(data.error.message) : "Duplicate entry error";
|
|
showError(errorMessage)
|
|
} else if (0 === response.status) showError("Could not connect to the server. Please check your connection and try again");
|
|
else if (405 === response.status) showError(unexpectedError);
|
|
else if (400 === response.status) {
|
|
var errorMessage = data.error && data.error.message ? data.error.message : data.localizedMessage || "Could not connect to the server. Please check your connection and try again";
|
|
showError(errorMessage)
|
|
} else if (403 === response.status) {
|
|
var errorMessage = data.error && data.error.message ? data.error.message : unexpectedError;
|
|
shouldRedirectToLogin(response) ? $rootScope.$broadcast("event:auth-loginRequired") : showError(errorMessage)
|
|
} else 404 === response.status && (_.includes(response.config.url, "implementation_config") || _.includes(response.config.url, "locale_") || _.includes(response.config.url, "offlineMetadata") || showError("The requested information does not exist"));
|
|
return $q.reject(response)
|
|
}
|
|
var serverErrorMessages = Bahmni.Common.Constants.serverErrorMessages,
|
|
showError = function(errorMessage) {
|
|
var result = _.find(serverErrorMessages, function(listItem) {
|
|
return listItem.serverMessage === errorMessage
|
|
});
|
|
_.isEmpty(result) && $rootScope.$broadcast("event:serverError", errorMessage)
|
|
};
|
|
return {
|
|
response: success,
|
|
responseError: error
|
|
}
|
|
}];
|
|
$httpProvider.interceptors.push(interceptor)
|
|
}]), Modernizr.addTest("ios", function() {
|
|
return !!navigator.userAgent.match(/(iPad|iPhone|iPod)/i)
|
|
}), Modernizr.addTest("windowOS", function() {
|
|
return navigator.appVersion.indexOf("Win") != -1
|
|
}), $(function() {
|
|
Modernizr.ios && $(document).on("click", "label[for]", function() {
|
|
var $inputElement = $("input#" + $(this).attr("for")),
|
|
elementType = $inputElement.attr("type");
|
|
"radio" === elementType ? $inputElement.prop("checked", !0) : "checkbox" === elementType ? $inputElement.prop("checked", !$inputElement.prop("checked")) : $inputElement.focus()
|
|
})
|
|
}), String.prototype.format = function() {
|
|
for (var content = this, i = 0; i < arguments.length; i++) {
|
|
var replacement = "{" + i + "}";
|
|
content = content.replace(replacement, arguments[i])
|
|
}
|
|
return content
|
|
}, String.prototype.toValidId = function() {
|
|
var content = this;
|
|
return content.replace(/\s/g, "-")
|
|
}, angular.module("bahmni.common.util").service("offlineStatusService", ["$rootScope", "$interval", "appService", function($rootScope, $interval, appService) {
|
|
this.checkOfflineStatus = function() {
|
|
"up" === Offline.state && Offline.check()
|
|
}, this.setOfflineOptions = function() {
|
|
var networkConnectivity = appService.getAppDescriptor().getConfigValue("networkConnectivity"),
|
|
showNetworkStatusIndicator = null != networkConnectivity ? networkConnectivity.showNetworkStatusMessage : null,
|
|
intervalFrequency = null != networkConnectivity ? networkConnectivity.networkStatusCheckInterval : null;
|
|
intervalFrequency = intervalFrequency ? intervalFrequency : 5e3, Offline.options = {
|
|
game: !0,
|
|
checkOnLoad: !0,
|
|
checks: {
|
|
xhr: {
|
|
url: Bahmni.Common.Constants.faviconUrl
|
|
}
|
|
}
|
|
}, this.checkOfflineStatus(), void 0 === $rootScope.offlineStatusCheckIntervalPromise && ($rootScope.offlineStatusCheckIntervalPromise = $interval(this.checkOfflineStatus, intervalFrequency));
|
|
var clearCheckOfflineStatusInterval = function(offlineStatusCheckIntervalPromise) {
|
|
$interval.cancel(offlineStatusCheckIntervalPromise)
|
|
};
|
|
$rootScope.$on("$destroy", function() {
|
|
clearCheckOfflineStatusInterval($rootScope.offlineStatusCheckIntervalPromise)
|
|
}), showNetworkStatusIndicator === !1 && $(".offline-ui").css("display", "none")
|
|
}
|
|
}]), Bahmni.Common.Util.DynamicResourceLoader = function() {
|
|
return {
|
|
includeJs: function(script) {
|
|
var element = document.createElement("script");
|
|
element.setAttribute("src", script), document.body.appendChild(element)
|
|
},
|
|
includeCss: function(url) {
|
|
var element = document.createElement("link");
|
|
element.setAttribute("href", url), element.setAttribute("rel", "stylesheet"), element.setAttribute("type", "text/css"), document.head.appendChild(element)
|
|
}
|
|
}
|
|
}();
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Auth = Bahmni.Auth || {}, angular.module("authentication", ["ui.router"]), Bahmni.Auth.User = function(user) {
|
|
angular.extend(this, user), this.userProperties = user.userProperties || {}, this.favouriteObsTemplates = this.userProperties.favouriteObsTemplates ? this.userProperties.favouriteObsTemplates.split("###") : [], this.favouriteWards = this.userProperties.favouriteWards ? this.userProperties.favouriteWards.split("###") : [], this.recentlyViewedPatients = this.userProperties.recentlyViewedPatients ? JSON.parse(this.userProperties.recentlyViewedPatients) : [], this.toContract = function() {
|
|
var user = angular.copy(this);
|
|
return user.userProperties.favouriteObsTemplates = this.favouriteObsTemplates.join("###"), user.userProperties.favouriteWards = this.favouriteWards.join("###"), user.userProperties.recentlyViewedPatients = JSON.stringify(this.recentlyViewedPatients), delete user.favouriteObsTemplates, delete user.favouriteWards, delete user.recentlyViewedPatients, user
|
|
}, this.addDefaultLocale = function(locale) {
|
|
this.userProperties.defaultLocale = locale
|
|
}, this.addToRecentlyViewed = function(patient, maxPatients) {
|
|
_.some(this.recentlyViewedPatients, {
|
|
uuid: patient.uuid
|
|
}) || (this.recentlyViewedPatients.unshift({
|
|
uuid: patient.uuid,
|
|
name: patient.name,
|
|
identifier: patient.identifier
|
|
}), _.size(this.recentlyViewedPatients) >= maxPatients && (this.recentlyViewedPatients = _.take(this.recentlyViewedPatients, maxPatients)))
|
|
}, this.isFavouriteObsTemplate = function(conceptName) {
|
|
return _.includes(this.favouriteObsTemplates, conceptName)
|
|
}, this.toggleFavoriteObsTemplate = function(conceptName) {
|
|
this.isFavouriteObsTemplate(conceptName) ? this.favouriteObsTemplates = _.without(this.favouriteObsTemplates, conceptName) : this.favouriteObsTemplates.push(conceptName)
|
|
}, this.isFavouriteWard = function(wardName) {
|
|
return _.includes(this.favouriteWards, wardName)
|
|
}, this.toggleFavoriteWard = function(wardName) {
|
|
this.isFavouriteWard(wardName) ? this.favouriteWards = _.without(this.favouriteWards, wardName) : this.favouriteWards.push(wardName)
|
|
}
|
|
}, angular.module("authentication").service("userService", ["$rootScope", "$http", "$q", function($rootScope, $http, $q) {
|
|
var getUserFromServer = function(userName) {
|
|
return $http.get(Bahmni.Common.Constants.userUrl, {
|
|
method: "GET",
|
|
params: {
|
|
username: userName,
|
|
v: "custom:(username,uuid,person:(uuid,),privileges:(name,retired),userProperties)"
|
|
},
|
|
cache: !1
|
|
})
|
|
};
|
|
this.getUser = function(userName) {
|
|
var deferrable = $q.defer();
|
|
return getUserFromServer(userName).success(function(data) {
|
|
deferrable.resolve(data)
|
|
}).error(function() {
|
|
deferrable.reject("Unable to get user data")
|
|
}), deferrable.promise
|
|
}, this.savePreferences = function() {
|
|
var deferrable = $q.defer(),
|
|
user = $rootScope.currentUser.toContract();
|
|
return $http.post(Bahmni.Common.Constants.userUrl + "/" + user.uuid, {
|
|
uuid: user.uuid,
|
|
userProperties: user.userProperties
|
|
}, {
|
|
withCredentials: !0
|
|
}).then(function(response) {
|
|
$rootScope.currentUser.userProperties = response.data.userProperties, deferrable.resolve()
|
|
}), deferrable.promise
|
|
};
|
|
var getProviderFromServer = function(uuid) {
|
|
return $http.get(Bahmni.Common.Constants.providerUrl, {
|
|
method: "GET",
|
|
params: {
|
|
user: uuid
|
|
},
|
|
cache: !1
|
|
})
|
|
};
|
|
this.getProviderForUser = function(uuid) {
|
|
var deferrable = $q.defer();
|
|
return getProviderFromServer(uuid).success(function(data) {
|
|
if (data.results.length > 0) {
|
|
var providerName = data.results[0].display.split("-")[1];
|
|
data.results[0].name = providerName ? providerName.trim() : providerName, deferrable.resolve(data)
|
|
} else deferrable.reject("UNABLE_TO_GET_PROVIDER_DATA")
|
|
}).error(function() {
|
|
deferrable.reject("UNABLE_TO_GET_PROVIDER_DATA")
|
|
}), deferrable.promise
|
|
}, this.getPasswordPolicies = function() {
|
|
return $http.get(Bahmni.Common.Constants.passwordPolicyUrl, {
|
|
method: "GET",
|
|
withCredentials: !0
|
|
})
|
|
}
|
|
}]), angular.module("authentication").config(["$httpProvider", function($httpProvider) {
|
|
var interceptor = ["$rootScope", "$q", function($rootScope, $q) {
|
|
function success(response) {
|
|
return response
|
|
}
|
|
|
|
function error(response) {
|
|
return 401 === response.status && $rootScope.$broadcast("event:auth-loginRequired"), $q.reject(response)
|
|
}
|
|
return {
|
|
response: success,
|
|
responseError: error
|
|
}
|
|
}];
|
|
$httpProvider.interceptors.push(interceptor)
|
|
}]).run(["$rootScope", "$window", "$timeout", function($rootScope, $window, $timeout) {
|
|
$rootScope.$on("event:auth-loginRequired", function() {
|
|
$timeout(function() {
|
|
$window.location = "../home/index.html#/login"
|
|
})
|
|
})
|
|
}]).service("sessionService", ["$rootScope", "$http", "$q", "$bahmniCookieStore", "userService", function($rootScope, $http, $q, $bahmniCookieStore, userService) {
|
|
var sessionResourcePath = Bahmni.Common.Constants.RESTWS_V1 + "/session?v=custom:(uuid)",
|
|
getAuthFromServer = function(username, password, otp) {
|
|
var btoa = otp ? username + ":" + password + ":" + otp : username + ":" + password;
|
|
return $http.get(sessionResourcePath, {
|
|
headers: {
|
|
Authorization: "Basic " + window.btoa(btoa)
|
|
},
|
|
cache: !1
|
|
})
|
|
};
|
|
this.resendOTP = function(username, password) {
|
|
var btoa = username + ":" + password;
|
|
return $http.get(sessionResourcePath + "&resendOTP=true", {
|
|
headers: {
|
|
Authorization: "Basic " + window.btoa(btoa)
|
|
},
|
|
cache: !1
|
|
})
|
|
};
|
|
var createSession = function(username, password, otp) {
|
|
var deferrable = $q.defer();
|
|
return destroySessionFromServer().success(function() {
|
|
getAuthFromServer(username, password, otp).then(function(response) {
|
|
204 == response.status && deferrable.resolve({
|
|
firstFactAuthorization: !0
|
|
}), deferrable.resolve(response.data)
|
|
}, function(response) {
|
|
401 == response.status ? deferrable.reject("LOGIN_LABEL_WRONG_OTP_MESSAGE_KEY") : 410 == response.status ? deferrable.reject("LOGIN_LABEL_OTP_EXPIRED") : 429 == response.status && deferrable.reject("LOGIN_LABEL_MAX_FAILED_ATTEMPTS"), deferrable.reject("LOGIN_LABEL_LOGIN_ERROR_MESSAGE_KEY")
|
|
})
|
|
}).error(function() {
|
|
deferrable.reject("LOGIN_LABEL_LOGIN_ERROR_MESSAGE_KEY")
|
|
}), deferrable.promise
|
|
},
|
|
hasAnyActiveProvider = function(providers) {
|
|
return _.filter(providers, function(provider) {
|
|
return void 0 == provider.retired || "false" == provider.retired
|
|
}).length > 0
|
|
},
|
|
self = this,
|
|
destroySessionFromServer = function() {
|
|
return $http["delete"](sessionResourcePath)
|
|
},
|
|
sessionCleanup = function() {
|
|
delete $.cookie(Bahmni.Common.Constants.currentUser, null, {
|
|
path: "/"
|
|
}), delete $.cookie(Bahmni.Common.Constants.currentUser, null, {
|
|
path: "/"
|
|
}), delete $.cookie(Bahmni.Common.Constants.retrospectiveEntryEncounterDateCookieName, null, {
|
|
path: "/"
|
|
}), delete $.cookie(Bahmni.Common.Constants.grantProviderAccessDataCookieName, null, {
|
|
path: "/"
|
|
}), $rootScope.currentUser = void 0
|
|
};
|
|
this.destroy = function() {
|
|
var deferrable = $q.defer();
|
|
return destroySessionFromServer().then(function() {
|
|
sessionCleanup(), deferrable.resolve()
|
|
}), deferrable.promise
|
|
}, this.loginUser = function(username, password, location, otp) {
|
|
var deferrable = $q.defer();
|
|
return createSession(username, password, otp).then(function(data) {
|
|
data.authenticated ? ($bahmniCookieStore.put(Bahmni.Common.Constants.currentUser, username, {
|
|
path: "/",
|
|
expires: 7
|
|
}), void 0 != location && ($bahmniCookieStore.remove(Bahmni.Common.Constants.locationCookieName), $bahmniCookieStore.put(Bahmni.Common.Constants.locationCookieName, {
|
|
name: location.display,
|
|
uuid: location.uuid
|
|
}, {
|
|
path: "/",
|
|
expires: 7
|
|
})), deferrable.resolve(data)) : data.firstFactAuthorization ? deferrable.resolve(data) : deferrable.reject("LOGIN_LABEL_LOGIN_ERROR_MESSAGE_KEY")
|
|
}, function(errorInfo) {
|
|
deferrable.reject(errorInfo)
|
|
}), deferrable.promise
|
|
}, this.get = function() {
|
|
return $http.get(sessionResourcePath, {
|
|
cache: !1
|
|
})
|
|
}, this.loadCredentials = function() {
|
|
var deferrable = $q.defer(),
|
|
currentUser = $bahmniCookieStore.get(Bahmni.Common.Constants.currentUser);
|
|
return currentUser ? (userService.getUser(currentUser).then(function(data) {
|
|
userService.getProviderForUser(data.results[0].uuid).then(function(providers) {
|
|
!_.isEmpty(providers.results) && hasAnyActiveProvider(providers.results) ? ($rootScope.currentUser = new Bahmni.Auth.User(data.results[0]), $rootScope.currentUser.currentLocation = $bahmniCookieStore.get(Bahmni.Common.Constants.locationCookieName).name, $rootScope.$broadcast("event:user-credentialsLoaded", data.results[0]), deferrable.resolve(data.results[0])) : (self.destroy(), deferrable.reject("YOU_HAVE_NOT_BEEN_SETUP_PROVIDER"))
|
|
}, function() {
|
|
self.destroy(), deferrable.reject("COULD_NOT_GET_PROVIDER")
|
|
})
|
|
}, function() {
|
|
self.destroy(), deferrable.reject("Could not get roles for the current user.")
|
|
}), deferrable.promise) : (this.destroy()["finally"](function() {
|
|
$rootScope.$broadcast("event:auth-loginRequired"), deferrable.reject("No User in session. Please login again.")
|
|
}), deferrable.promise)
|
|
}, this.getLoginLocationUuid = function() {
|
|
return $bahmniCookieStore.get(Bahmni.Common.Constants.locationCookieName) ? $bahmniCookieStore.get(Bahmni.Common.Constants.locationCookieName).uuid : null
|
|
}, this.changePassword = function(currentUserUuid, oldPassword, newPassword) {
|
|
return $http({
|
|
method: "POST",
|
|
url: Bahmni.Common.Constants.passwordUrl,
|
|
data: {
|
|
oldPassword: oldPassword,
|
|
newPassword: newPassword
|
|
},
|
|
headers: {
|
|
"Content-Type": "application/json"
|
|
}
|
|
})
|
|
}, this.loadProviders = function(userInfo) {
|
|
return $http.get(Bahmni.Common.Constants.providerUrl, {
|
|
method: "GET",
|
|
params: {
|
|
user: userInfo.uuid
|
|
},
|
|
cache: !1
|
|
}).success(function(data) {
|
|
var providerUuid = data.results.length > 0 ? data.results[0].uuid : void 0;
|
|
$rootScope.currentProvider = {
|
|
uuid: providerUuid
|
|
}
|
|
})
|
|
}
|
|
}]).factory("authenticator", ["$rootScope", "$q", "$window", "sessionService", function($rootScope, $q, $window, sessionService) {
|
|
var authenticateUser = function() {
|
|
var defer = $q.defer(),
|
|
sessionDetails = sessionService.get();
|
|
return sessionDetails.then(function(response) {
|
|
response.data.authenticated ? defer.resolve() : (defer.reject("User not authenticated"), $rootScope.$broadcast("event:auth-loginRequired"))
|
|
}), defer.promise
|
|
};
|
|
return {
|
|
authenticateUser: authenticateUser
|
|
}
|
|
}]).directive("logOut", ["sessionService", "$window", "configurationService", "auditLogService", function(sessionService, $window, configurationService, auditLogService) {
|
|
return {
|
|
link: function(scope, element) {
|
|
element.bind("click", function() {
|
|
scope.$apply(function() {
|
|
auditLogService.log(void 0, "USER_LOGOUT_SUCCESS", void 0, "MODULE_LABEL_LOGOUT_KEY").then(function() {
|
|
sessionService.destroy().then(function() {
|
|
$window.location = "../home/index.html#/login"
|
|
})
|
|
})
|
|
})
|
|
})
|
|
}
|
|
}
|
|
}]).directive("btnUserInfo", [function() {
|
|
return {
|
|
restrict: "CA",
|
|
link: function(scope, elem) {
|
|
elem.bind("click", function(event) {
|
|
$(this).next().toggleClass("active"), event.stopPropagation()
|
|
}), $(document).find("body").bind("click", function() {
|
|
$(elem).next().removeClass("active")
|
|
})
|
|
}
|
|
}
|
|
}]), angular.module("bahmni.common.appFramework", ["authentication"]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.AppFramework = Bahmni.Common.AppFramework || {}, angular.module("bahmni.common.appFramework").config(["$compileProvider", function($compileProvider) {
|
|
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|chrome-extension|file):/)
|
|
}]).service("appService", ["$http", "$q", "sessionService", "$rootScope", "mergeService", "loadConfigService", "messagingService", "$translate", function($http, $q, sessionService, $rootScope, mergeService, loadConfigService, messagingService, $translate) {
|
|
var currentUser = null,
|
|
baseUrl = Bahmni.Common.Constants.baseUrl,
|
|
customUrl = Bahmni.Common.Constants.customUrl,
|
|
appDescriptor = null,
|
|
loadConfig = function(url) {
|
|
return loadConfigService.loadConfig(url, appDescriptor.contextPath)
|
|
},
|
|
loadTemplate = function(appDescriptor) {
|
|
var deferrable = $q.defer();
|
|
return loadConfig(baseUrl + appDescriptor.contextPath + "/appTemplate.json").then(function(result) {
|
|
_.keys(result.data).length > 0 && appDescriptor.setTemplate(result.data), deferrable.resolve(appDescriptor)
|
|
}, function(error) {
|
|
404 !== error.status ? deferrable.reject(error) : deferrable.resolve(appDescriptor)
|
|
}), deferrable.promise
|
|
},
|
|
setDefinition = function(baseResultData, customResultData) {
|
|
customResultData && (_.keys(baseResultData).length > 0 || _.keys(customResultData.length > 0)) ? appDescriptor.setDefinition(baseResultData, customResultData) : _.keys(baseResultData).length > 0 && appDescriptor.setDefinition(baseResultData)
|
|
},
|
|
loadDefinition = function(appDescriptor) {
|
|
var deferrable = $q.defer();
|
|
return loadConfig(baseUrl + appDescriptor.contextPath + "/app.json").then(function(baseResult) {
|
|
baseResult.data.shouldOverRideConfig ? loadConfig(customUrl + appDescriptor.contextPath + "/app.json").then(function(customResult) {
|
|
setDefinition(baseResult.data, customResult.data), deferrable.resolve(appDescriptor)
|
|
}, function() {
|
|
setDefinition(baseResult.data), deferrable.resolve(appDescriptor)
|
|
}) : (setDefinition(baseResult.data), deferrable.resolve(appDescriptor))
|
|
}, function(error) {
|
|
404 !== error.status ? deferrable.reject(error) : deferrable.resolve(appDescriptor)
|
|
}), deferrable.promise
|
|
},
|
|
setExtensions = function(baseResultData, customResultData) {
|
|
customResultData ? appDescriptor.setExtensions(baseResultData, customResultData) : appDescriptor.setExtensions(baseResultData)
|
|
},
|
|
loadExtensions = function(appDescriptor, extensionFileName) {
|
|
var deferrable = $q.defer();
|
|
return loadConfig(baseUrl + appDescriptor.extensionPath + extensionFileName).then(function(baseResult) {
|
|
baseResult.data.shouldOverRideConfig ? loadConfig(customUrl + appDescriptor.extensionPath + extensionFileName).then(function(customResult) {
|
|
setExtensions(baseResult.data, customResult.data), deferrable.resolve(appDescriptor)
|
|
}, function() {
|
|
setExtensions(baseResult.data), deferrable.resolve(appDescriptor)
|
|
}) : (setExtensions(baseResult.data), deferrable.resolve(appDescriptor))
|
|
}, function(error) {
|
|
404 !== error.status ? deferrable.reject(error) : deferrable.resolve(appDescriptor)
|
|
}), deferrable.promise
|
|
},
|
|
setDefaultPageConfig = function(pageName, baseResultData, customResultData) {
|
|
customResultData && (_.keys(customResultData).length > 0 || _.keys(baseResultData).length > 0) ? appDescriptor.addConfigForPage(pageName, baseResultData, customResultData) : _.keys(baseResultData).length > 0 && appDescriptor.addConfigForPage(pageName, baseResultData)
|
|
},
|
|
hasPrivilegeOf = function(privilegeName) {
|
|
return _.some(currentUser.privileges, {
|
|
name: privilegeName
|
|
})
|
|
},
|
|
loadPageConfig = function(pageName, appDescriptor) {
|
|
var deferrable = $q.defer();
|
|
return loadConfig(baseUrl + appDescriptor.contextPath + "/" + pageName + ".json").then(function(baseResult) {
|
|
baseResult.data.shouldOverRideConfig ? loadConfig(customUrl + appDescriptor.contextPath + "/" + pageName + ".json").then(function(customResult) {
|
|
setDefaultPageConfig(pageName, baseResult.data, customResult.data), deferrable.resolve(appDescriptor)
|
|
}, function() {
|
|
setDefaultPageConfig(pageName, baseResult.data), deferrable.resolve(appDescriptor)
|
|
}) : (setDefaultPageConfig(pageName, baseResult.data), deferrable.resolve(appDescriptor))
|
|
}, function(error) {
|
|
404 !== error.status ? (messagingService.showMessage("error", "Incorrect Configuration: " + error.message), deferrable.reject(error)) : deferrable.resolve(appDescriptor)
|
|
}), deferrable.promise
|
|
};
|
|
this.getAppDescriptor = function() {
|
|
return appDescriptor
|
|
}, this.configBaseUrl = function() {
|
|
return baseUrl
|
|
}, this.loadCsvFileFromConfig = function(name) {
|
|
return loadConfig(baseUrl + appDescriptor.contextPath + "/" + name)
|
|
}, this.loadConfig = function(name, shouldMerge) {
|
|
return loadConfig(baseUrl + appDescriptor.contextPath + "/" + name).then(function(baseResponse) {
|
|
return baseResponse.data.shouldOverRideConfig ? loadConfig(customUrl + appDescriptor.contextPath + "/" + name).then(function(customResponse) {
|
|
return shouldMerge || void 0 === shouldMerge ? mergeService.merge(baseResponse.data, customResponse.data) : [baseResponse.data, customResponse.data]
|
|
}, function() {
|
|
return baseResponse.data
|
|
}) : baseResponse.data
|
|
})
|
|
}, this.loadMandatoryConfig = function(path) {
|
|
return $http.get(path)
|
|
}, this.getAppName = function() {
|
|
return this.appName
|
|
}, this.checkPrivilege = function(privilegeName) {
|
|
return hasPrivilegeOf(privilegeName) ? $q.when(!0) : (messagingService.showMessage("error", $translate.instant(Bahmni.Common.Constants.privilegeRequiredErrorMessage) + " [Privileges required: " + privilegeName + "]"), $q.reject())
|
|
}, this.initApp = function(appName, options, extensionFileSuffix, configPages) {
|
|
this.appName = appName;
|
|
var appLoader = $q.defer(),
|
|
extensionFileName = extensionFileSuffix && "default" !== extensionFileSuffix.toLowerCase() ? "/extension-" + extensionFileSuffix + ".json" : "/extension.json",
|
|
promises = [],
|
|
opts = options || {
|
|
app: !0,
|
|
extension: !0
|
|
},
|
|
inheritAppContext = !opts.inherit || opts.inherit;
|
|
appDescriptor = new Bahmni.Common.AppFramework.AppDescriptor(appName, inheritAppContext, function() {
|
|
return currentUser
|
|
}, mergeService);
|
|
var loadCredentialsPromise = sessionService.loadCredentials(),
|
|
loadProviderPromise = loadCredentialsPromise.then(sessionService.loadProviders);
|
|
return promises.push(loadCredentialsPromise), promises.push(loadProviderPromise), opts.extension && promises.push(loadExtensions(appDescriptor, extensionFileName)), opts.template && promises.push(loadTemplate(appDescriptor)), opts.app && promises.push(loadDefinition(appDescriptor)), _.isEmpty(configPages) || configPages.forEach(function(configPage) {
|
|
promises.push(loadPageConfig(configPage, appDescriptor))
|
|
}), $q.all(promises).then(function(results) {
|
|
currentUser = results[0], appLoader.resolve(appDescriptor), $rootScope.$broadcast("event:appExtensions-loaded")
|
|
}, function(errors) {
|
|
appLoader.reject(errors)
|
|
}), appLoader.promise
|
|
}
|
|
}]), angular.module("bahmni.common.appFramework").service("mergeService", [function() {
|
|
this.merge = function(base, custom) {
|
|
var mergeResult = $.extend(!0, {}, base, custom);
|
|
return deleteNullValuedKeys(mergeResult)
|
|
};
|
|
var deleteNullValuedKeys = function(currentObject) {
|
|
return _.forOwn(currentObject, function(value, key) {
|
|
(_.isUndefined(value) || _.isNull(value) || _.isNaN(value) || _.isObject(value) && _.isNull(deleteNullValuedKeys(value))) && delete currentObject[key]
|
|
}), currentObject
|
|
}
|
|
}]), angular.module("bahmni.common.appFramework").directive("appExtensionList", ["appService", function(appService) {
|
|
var appDescriptor = appService.getAppDescriptor();
|
|
return {
|
|
restrict: "EA",
|
|
template: '<ul><li ng-repeat="appExtn in appExtensions"><a href="{{formatUrl(appExtn.url, extnParams)}}" class="{{appExtn.icon}}" onclick="return false;" title="{{appExtn.label}}" ng-click="extnLinkClick(appExtn, extnParams)"> <span ng-show="showLabel">{{appExtn.label}}</span></a></li></ul>',
|
|
scope: {
|
|
extnPointId: "@",
|
|
showLabel: "@",
|
|
onExtensionClick: "&",
|
|
contextModel: "&"
|
|
},
|
|
compile: function(cElement, cAttrs) {
|
|
var extnList = appDescriptor.getExtensions(cAttrs.extnPointId);
|
|
return function(scope) {
|
|
scope.appExtensions = extnList;
|
|
var model = scope.contextModel();
|
|
scope.extnParams = model || {}
|
|
}
|
|
},
|
|
controller: function($scope, $location) {
|
|
$scope.formatUrl = appDescriptor.formatUrl, $scope.extnLinkClick = function(extn, params) {
|
|
var proceedWithDefault = !0,
|
|
clickHandler = $scope.onExtensionClick(),
|
|
target = appDescriptor.formatUrl(extn.url, params);
|
|
if (clickHandler) {
|
|
var event = {
|
|
src: extn,
|
|
target: target,
|
|
params: params,
|
|
preventDefault: function() {
|
|
proceedWithDefault = !1
|
|
}
|
|
};
|
|
clickHandler(event)
|
|
}
|
|
proceedWithDefault && $location.url(target)
|
|
}
|
|
}
|
|
}
|
|
}]), Bahmni.Common.AppFramework.AppDescriptor = function(context, inheritContext, retrieveUserCallback, mergeService) {
|
|
this.id = null, this.instanceOf = null, this.description = null, this.contextModel = null, this.baseExtensionPoints = [], this.customExtensionPoints = [], this.baseExtensions = {}, this.customExtensions = {}, this.customConfigs = {}, this.baseConfigs = {}, this.extensionPath = context, this.contextPath = inheritContext ? context.split("/")[0] : context;
|
|
var self = this,
|
|
setExtensionPointsFromExtensions = function(currentExtensions, currentExtensionPoints) {
|
|
_.values(currentExtensions).forEach(function(extn) {
|
|
if (extn) {
|
|
var existing = self[currentExtensionPoints].filter(function(ep) {
|
|
return ep.id === extn.extensionPointId
|
|
});
|
|
0 === existing.length && self[currentExtensionPoints].push({
|
|
id: extn.extensionPointId,
|
|
description: extn.description
|
|
})
|
|
}
|
|
})
|
|
};
|
|
this.setExtensions = function(baseExtensions, customExtensions) {
|
|
customExtensions && (setExtensionPointsFromExtensions(customExtensions, "customExtensionPoints"), self.customExtensions = customExtensions), self.baseExtensions = baseExtensions, setExtensionPointsFromExtensions(baseExtensions, "baseExtensionPoints")
|
|
}, this.setTemplate = function(template) {
|
|
self.instanceOf = template.id, self.description = self.description || template.description, self.contextModel = self.contextModel || template.contextModel, template.configOptions && _.values(template.configOptions).forEach(function(opt) {
|
|
var existing = self.configs.filter(function(cfg) {
|
|
return cfg.name === opt.name
|
|
});
|
|
existing.length > 0 ? existing[0].description = opt.description : self.configs.push({
|
|
name: opt.name,
|
|
description: opt.description,
|
|
value: opt.defaultValue
|
|
})
|
|
})
|
|
};
|
|
var setConfig = function(instance, currentConfig) {
|
|
for (var configName in instance.config) {
|
|
var existingConfig = getConfig(self[currentConfig], configName);
|
|
existingConfig ? existingConfig.value = instance.config[configName] : self[currentConfig][configName] = {
|
|
name: configName,
|
|
value: instance.config[configName]
|
|
}
|
|
}
|
|
},
|
|
setDefinitionExtensionPoints = function(extensionPoints, currentExtensionPoints) {
|
|
extensionPoints && extensionPoints.forEach(function(iep) {
|
|
if (iep) {
|
|
var existing = self[currentExtensionPoints].filter(function(ep) {
|
|
return ep.id === iep.id
|
|
});
|
|
0 === existing.length && self[currentExtensionPoints].push(iep)
|
|
}
|
|
})
|
|
};
|
|
this.setDefinition = function(baseInstance, customInstance) {
|
|
self.instanceOf = customInstance && customInstance.instanceOf ? customInstance.instanceOf : baseInstance.instanceOf, self.id = customInstance && customInstance.id ? customInstance.id : baseInstance.id, self.description = customInstance && customInstance.description ? customInstance.description : baseInstance.description, self.contextModel = customInstance && customInstance.contextModel ? customInstance.contextModel : baseInstance.contextModel, setDefinitionExtensionPoints(baseInstance.extensionPoints, "baseExtensionPoints"), setConfig(baseInstance, "baseConfigs"), customInstance && (setDefinitionExtensionPoints(customInstance.extensionPoints, "customExtensionPoints"), setConfig(customInstance, "customConfigs"))
|
|
};
|
|
var getExtensions = function(extPointId, type, extensions) {
|
|
var currentUser = retrieveUserCallback(),
|
|
currentExtensions = _.values(extensions);
|
|
if (currentUser && currentExtensions) {
|
|
var extnType = type || "all",
|
|
userPrivileges = currentUser.privileges.map(function(priv) {
|
|
return priv.retired ? "" : priv.name
|
|
}),
|
|
appsExtns = currentExtensions.filter(function(extn) {
|
|
return ("all" === extnType || extn.type === extnType) && extn.extensionPointId === extPointId && (!extn.requiredPrivilege || userPrivileges.indexOf(extn.requiredPrivilege) >= 0)
|
|
});
|
|
return appsExtns.sort(function(extn1, extn2) {
|
|
return extn1.order - extn2.order
|
|
}), appsExtns
|
|
}
|
|
};
|
|
this.getExtensions = function(extPointId, type, shouldMerge) {
|
|
if (shouldMerge || void 0 === shouldMerge) {
|
|
var mergedExtensions = mergeService.merge(self.baseExtensions, self.customExtensions);
|
|
return getExtensions(extPointId, type, mergedExtensions)
|
|
}
|
|
return [getExtensions(extPointId, type, self.baseExtensions), getExtensions(extPointId, type, self.customExtensions)]
|
|
}, this.getExtensionById = function(id, shouldMerge) {
|
|
if (shouldMerge || void 0 === shouldMerge) {
|
|
var mergedExtensions = _.values(mergeService.merge(self.baseExtensions, self.customExtensions));
|
|
return mergedExtensions.filter(function(extn) {
|
|
return extn.id === id
|
|
})[0]
|
|
}
|
|
return [self.baseExtensions.filter(function(extn) {
|
|
return extn.id === id
|
|
})[0], self.customExtensions.filter(function(extn) {
|
|
return extn.id === id
|
|
})[0]]
|
|
};
|
|
var getConfig = function(config, configName) {
|
|
var cfgList = _.values(config).filter(function(cfg) {
|
|
return cfg.name === configName
|
|
});
|
|
return cfgList.length > 0 ? cfgList[0] : null
|
|
};
|
|
this.getConfig = function(configName, shouldMerge) {
|
|
return shouldMerge || void 0 === shouldMerge ? getConfig(mergeService.merge(self.baseConfigs, self.customConfigs), configName) : [getConfig(self.baseConfigs, configName), getConfig(self.customConfigs, configName)]
|
|
}, this.getConfigValue = function(configName, shouldMerge) {
|
|
var config = this.getConfig(configName, shouldMerge);
|
|
return shouldMerge || void 0 === shouldMerge ? config ? config.value : null : config
|
|
}, this.formatUrl = function(url, options, useQueryParams) {
|
|
var pattern = /{{([^}]*)}}/g,
|
|
matches = url.match(pattern),
|
|
replacedString = url,
|
|
checkQueryParams = useQueryParams || !1,
|
|
queryParameters = this.parseQueryParams();
|
|
return matches && matches.forEach(function(el) {
|
|
var key = el.replace("{{", "").replace("}}", ""),
|
|
value = options[key];
|
|
value || checkQueryParams !== !0 || (value = queryParameters[key] || null), replacedString = replacedString.replace(el, value)
|
|
}), replacedString.trim()
|
|
}, this.parseQueryParams = function(locationSearchString) {
|
|
var urlParams, match, pl = /\+/g,
|
|
search = /([^&=]+)=?([^&]*)/g,
|
|
decode = function(s) {
|
|
return decodeURIComponent(s.replace(pl, " "))
|
|
},
|
|
queryString = locationSearchString || window.location.search.substring(1);
|
|
for (urlParams = {}; match = search.exec(queryString);) urlParams[decode(match[1])] = decode(match[2]);
|
|
return urlParams
|
|
}, this.addConfigForPage = function(pageName, baseConfig, customConfig) {
|
|
self.basePageConfigs = self.basePageConfigs || {}, self.basePageConfigs[pageName] = baseConfig, self.customPageConfigs = self.customPageConfigs || {}, self.customPageConfigs[pageName] = customConfig
|
|
}, this.getConfigForPage = function(pageName, shouldMerge) {
|
|
return shouldMerge || void 0 === shouldMerge ? mergeService.merge(self.basePageConfigs[pageName], self.customPageConfigs[pageName]) : [_.values(self.basePageConfigs[pageName]), _.values(self.customPageConfigs[pageName])]
|
|
}
|
|
}, angular.module("bahmni.common.config", []), angular.module("bahmni.common.config").service("configurations", ["configurationService", function(configurationService) {
|
|
this.configs = {}, this.load = function(configNames) {
|
|
var self = this;
|
|
return configurationService.getConfigurations(_.difference(configNames, Object.keys(this.configs))).then(function(configurations) {
|
|
angular.extend(self.configs, configurations)
|
|
})
|
|
}, this.dosageInstructionConfig = function() {
|
|
return this.configs.dosageInstructionConfig || []
|
|
}, this.stoppedOrderReasonConfig = function() {
|
|
return this.configs.stoppedOrderReasonConfig || []
|
|
}, this.dosageFrequencyConfig = function() {
|
|
return this.configs.dosageFrequencyConfig || []
|
|
}, this.allTestsAndPanelsConcept = function() {
|
|
return this.configs.allTestsAndPanelsConcept.results[0] || []
|
|
}, this.impressionConcept = function() {
|
|
return this.configs.radiologyImpressionConfig.results[0] || []
|
|
}, this.labOrderNotesConcept = function() {
|
|
return this.configs.labOrderNotesConfig.results[0] || []
|
|
}, this.consultationNoteConcept = function() {
|
|
return this.configs.consultationNoteConfig.results[0] || []
|
|
}, this.patientConfig = function() {
|
|
return this.configs.patientConfig || {}
|
|
}, this.encounterConfig = function() {
|
|
return angular.extend(new EncounterConfig, this.configs.encounterConfig || [])
|
|
}, this.patientAttributesConfig = function() {
|
|
return this.configs.patientAttributesConfig.results
|
|
}, this.identifierTypesConfig = function() {
|
|
return this.configs.identifierTypesConfig
|
|
}, this.genderMap = function() {
|
|
return this.configs.genderMap
|
|
}, this.addressLevels = function() {
|
|
return this.configs.addressLevels
|
|
}, this.relationshipTypes = function() {
|
|
return this.configs.relationshipTypeConfig.results || []
|
|
}, this.relationshipTypeMap = function() {
|
|
return this.configs.relationshipTypeMap || {}
|
|
}, this.loginLocationToVisitTypeMapping = function() {
|
|
return this.configs.loginLocationToVisitTypeMapping || {}
|
|
}, this.defaultEncounterType = function() {
|
|
return this.configs.defaultEncounterType
|
|
}
|
|
}]), angular.module("bahmni.common.config").directive("showIfPrivilege", ["$rootScope", function($rootScope) {
|
|
return {
|
|
scope: {
|
|
showIfPrivilege: "@"
|
|
},
|
|
link: function(scope, element) {
|
|
var privileges = scope.showIfPrivilege.split(","),
|
|
requiredPrivilege = !1;
|
|
if ($rootScope.currentUser) {
|
|
var allTypesPrivileges = _.map($rootScope.currentUser.privileges, _.property("name")),
|
|
intersect = _.intersectionWith(allTypesPrivileges, privileges, _.isEqual);
|
|
requiredPrivilege = intersect.length > 0
|
|
}
|
|
requiredPrivilege || element.hide()
|
|
}
|
|
}
|
|
}]), angular.module("bahmni.common.patient", []), Bahmni.PatientMapper = function(patientConfig, $rootScope, $translate) {
|
|
this.patientConfig = patientConfig, this.map = function(openmrsPatient) {
|
|
var patient = this.mapBasic(openmrsPatient);
|
|
return this.mapAttributes(patient, openmrsPatient.person.attributes), patient
|
|
}, this.mapBasic = function(openmrsPatient) {
|
|
var patient = {};
|
|
if (patient.uuid = openmrsPatient.uuid, patient.givenName = openmrsPatient.person.preferredName.givenName, patient.familyName = null === openmrsPatient.person.preferredName.familyName ? "" : openmrsPatient.person.preferredName.familyName, patient.name = patient.givenName + " " + patient.familyName, patient.age = openmrsPatient.person.age, patient.ageText = calculateAge(Bahmni.Common.Util.DateUtil.parseServerDateToDate(openmrsPatient.person.birthdate)), patient.gender = openmrsPatient.person.gender, patient.genderText = mapGenderText(patient.gender), patient.address = mapAddress(openmrsPatient.person.preferredAddress), patient.birthdateEstimated = openmrsPatient.person.birthdateEstimated, patient.birthtime = Bahmni.Common.Util.DateUtil.parseServerDateToDate(openmrsPatient.person.birthtime), patient.bloodGroupText = getPatientBloodGroupText(openmrsPatient), openmrsPatient.identifiers) {
|
|
var primaryIdentifier = openmrsPatient.identifiers[0].primaryIdentifier;
|
|
patient.identifier = primaryIdentifier ? primaryIdentifier : openmrsPatient.identifiers[0].identifier
|
|
}
|
|
return openmrsPatient.person.birthdate && (patient.birthdate = parseDate(openmrsPatient.person.birthdate)), openmrsPatient.person.personDateCreated && (patient.registrationDate = parseDate(openmrsPatient.person.personDateCreated)), patient.image = Bahmni.Common.Constants.patientImageUrlByPatientUuid + openmrsPatient.uuid, patient
|
|
}, this.getPatientConfigByUuid = function(patientConfig, attributeUuid) {
|
|
return this.patientConfig.personAttributeTypes ? patientConfig.personAttributeTypes.filter(function(item) {
|
|
return item.uuid === attributeUuid
|
|
})[0] : {}
|
|
}, this.mapAttributes = function(patient, attributes) {
|
|
var self = this;
|
|
this.patientConfig && attributes.forEach(function(attribute) {
|
|
var x = self.getPatientConfigByUuid(patientConfig, attribute.attributeType.uuid);
|
|
patient[x.name] = {
|
|
label: x.description,
|
|
value: attribute.value,
|
|
isDateField: checkIfDateField(x)
|
|
}
|
|
})
|
|
};
|
|
var calculateAge = function(birthDate) {
|
|
var DateUtil = Bahmni.Common.Util.DateUtil,
|
|
age = DateUtil.diffInYearsMonthsDays(birthDate, DateUtil.now()),
|
|
ageInString = "";
|
|
return age.years && (ageInString += age.years + " <span> " + $translate.instant("CLINICAL_YEARS_TRANSLATION_KEY") + " </span>"), age.months && (ageInString += age.months + "<span> " + $translate.instant("CLINICAL_MONTHS_TRANSLATION_KEY") + " </span>"), age.days && (ageInString += age.days + "<span> " + $translate.instant("CLINICAL_DAYS_TRANSLATION_KEY") + " </span>"), ageInString
|
|
},
|
|
mapAddress = function(preferredAddress) {
|
|
return preferredAddress ? {
|
|
address1: preferredAddress.address1,
|
|
address2: preferredAddress.address2,
|
|
address3: preferredAddress.address3,
|
|
cityVillage: preferredAddress.cityVillage,
|
|
countyDistrict: null === preferredAddress.countyDistrict ? "" : preferredAddress.countyDistrict,
|
|
stateProvince: preferredAddress.stateProvince
|
|
} : {}
|
|
},
|
|
parseDate = function(dateStr) {
|
|
return dateStr ? Bahmni.Common.Util.DateUtil.parse(dateStr.substr(0, 10)) : dateStr
|
|
},
|
|
mapGenderText = function(genderChar) {
|
|
return null == genderChar ? null : "<span>" + $rootScope.genderMap[angular.uppercase(genderChar)] + "</span>"
|
|
},
|
|
getPatientBloodGroupText = function(openmrsPatient) {
|
|
if (openmrsPatient.person.bloodGroup) return "<span>" + openmrsPatient.person.bloodGroup + "</span>";
|
|
if (openmrsPatient.person.attributes && openmrsPatient.person.attributes.length > 0) {
|
|
var bloodGroup;
|
|
if (_.forEach(openmrsPatient.person.attributes, function(attribute) {
|
|
"bloodGroup" == attribute.attributeType.display && (bloodGroup = attribute.display)
|
|
}), bloodGroup) return "<span>" + bloodGroup + "</span>"
|
|
}
|
|
},
|
|
checkIfDateField = function(x) {
|
|
return x.format === Bahmni.Common.Constants.patientAttributeDateFieldFormat
|
|
}
|
|
}, Bahmni.PatientContextMapper = function() {
|
|
this.map = function(patient) {
|
|
var patientContext = {};
|
|
patientContext.uuid = patient.uuid, patientContext.givenName = patient.person.names[0].givenName;
|
|
var familyName = patient.person.names[0].familyName;
|
|
if (patientContext.familyName = familyName ? familyName : "", patientContext.middleName = patient.person.names[0].middleName, patientContext.gender = patient.person.gender, patient.identifiers) {
|
|
var primaryIdentifier = patient.identifiers[0].primaryIdentifier;
|
|
patientContext.identifier = primaryIdentifier ? primaryIdentifier : patient.identifiers[0].identifier
|
|
}
|
|
return patient.person.birthdate && (patientContext.birthdate = parseDate(patient.person.birthdate)), patientContext
|
|
};
|
|
var parseDate = function(dateStr) {
|
|
return dateStr ? Bahmni.Common.Util.DateUtil.parse(dateStr.substr(0, 10)) : dateStr
|
|
}
|
|
}, angular.module("bahmni.common.patient").filter("gender", ["$rootScope", function($rootScope) {
|
|
return function(genderChar) {
|
|
return null == genderChar ? "Unknown" : $rootScope.genderMap[angular.uppercase(genderChar)]
|
|
}
|
|
}]), angular.module("bahmni.common.patient").filter("age", function() {
|
|
return function(age) {
|
|
return age.years ? age.years + " y" : age.months ? age.months + " m" : age.days + " d"
|
|
}
|
|
}), angular.module("bahmni.common.patient").filter("dateToAge", ["$filter", function($filter) {
|
|
return function(birthDate, referenceDate) {
|
|
var DateUtil = Bahmni.Common.Util.DateUtil;
|
|
referenceDate = referenceDate || DateUtil.now();
|
|
var age = DateUtil.diffInYearsMonthsDays(birthDate, referenceDate);
|
|
return $filter("age")(age)
|
|
}
|
|
}]), angular.module("bahmni.common.patient").filter("birthDateToAgeText", ["$filter", "$translate", function($filter, $translate) {
|
|
return function(birthDate) {
|
|
var DateUtil = Bahmni.Common.Util.DateUtil;
|
|
if (birthDate) {
|
|
var age = DateUtil.diffInYearsMonthsDays(birthDate, DateUtil.now()),
|
|
ageInString = "";
|
|
return age.years && (ageInString += age.years + " " + $translate.instant("CLINICAL_YEARS_TRANSLATION_KEY") + " "), age.months && (ageInString += age.months + " " + $translate.instant("CLINICAL_MONTHS_TRANSLATION_KEY") + " "), age.days && (ageInString += age.days + " " + $translate.instant("CLINICAL_DAYS_TRANSLATION_KEY") + " "), ageInString
|
|
}
|
|
return ""
|
|
}
|
|
}]), angular.module("bahmni.common.patient").directive("patientSummary", function() {
|
|
var link = function($scope) {
|
|
$scope.showPatientDetails = !1, $scope.togglePatientDetails = function() {
|
|
$scope.showPatientDetails = !$scope.showPatientDetails
|
|
}, $scope.onImageClick = function() {
|
|
$scope.onImageClickHandler && $scope.onImageClickHandler()
|
|
}
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
templateUrl: "../common/patient/header/views/patientSummary.html",
|
|
link: link,
|
|
required: "patient",
|
|
scope: {
|
|
patient: "=",
|
|
bedDetails: "=",
|
|
onImageClickHandler: "&"
|
|
}
|
|
}
|
|
}), angular.module("bahmni.common.patient").directive("fallbackSrc", function() {
|
|
return {
|
|
restrict: "A",
|
|
link: function(scope, element, attrs) {
|
|
_.isEmpty(attrs.ngSrc) && element.attr("src", attrs.fallbackSrc), element.bind("error", function() {
|
|
element.attr("src", attrs.fallbackSrc)
|
|
})
|
|
}
|
|
}
|
|
}), angular.module("bahmni.common.patient").directive("stopEventPropagation", function() {
|
|
return {
|
|
link: function(scope, elem, attrs) {
|
|
elem.on(attrs.stopEventPropagation, function(e) {
|
|
e.stopPropagation()
|
|
})
|
|
}
|
|
}
|
|
}), angular.module("bahmni.common.patientSearch", ["bahmni.common.patient", "infinite-scroll"]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.PatientSearch = Bahmni.Common.PatientSearch || {}, Bahmni.Common.PatientSearch.Constants = {
|
|
searchExtensionTileViewType: "tile",
|
|
searchExtensionTabularViewType: "tabular",
|
|
tabularViewIgnoreHeadingsList: ["display", "uuid", "image", "$$hashKey", "activeVisitUuid", "hasBeenAdmitted", "forwardUrl", "programUuid", "enrollment"],
|
|
identifierHeading: ["ID", "Id", "id", "identifier", "DQ_COLUMN_TITLE_ACTION"],
|
|
nameHeading: ["NAME", "Name", "name"],
|
|
patientTileHeight: 100,
|
|
patientTileWidth: 100,
|
|
printIgnoreHeadingsList: ["DQ_COLUMN_TITLE_ACTION"],
|
|
tileLoadRatio: .5
|
|
}, Bahmni.Common.PatientSearch.Search = function(searchTypes) {
|
|
function mapPatient(patient) {
|
|
return (patient.name || patient.givenName || patient.familyName) && (patient.name = patient.name || patient.givenName + (patient.familyName ? " " + patient.familyName : "")), patient.display = _.map(self.searchColumns, function(column) {
|
|
return patient[column]
|
|
}).join(" - "), patient.image = Bahmni.Common.Constants.patientImageUrlByPatientUuid + patient.uuid, patient
|
|
}
|
|
var self = this;
|
|
self.searchTypes = searchTypes || [], self.searchType = this.searchTypes[0], self.searchParameter = "", self.noResultsMessage = null, self.searchResults = [], self.activePatients = [], self.navigated = !1, self.links = self.searchType && self.searchType.links ? self.searchType.links : [], self.searchColumns = self.searchType && self.searchType.searchColumns ? self.searchType.searchColumns : ["identifier", "name"], angular.forEach(searchTypes, function(searchType) {
|
|
searchType.patientCount = "..."
|
|
}), self.switchSearchType = function(searchType) {
|
|
self.noResultsMessage = null, self.isSelectedSearch(searchType) || (self.searchParameter = "", self.navigated = !0, self.searchType = searchType, self.activePatients = [], self.searchResults = [], self.links = self.searchType && self.searchType.links ? self.searchType.links : [], self.searchColumns = self.searchType && self.searchType.searchColumns ? self.searchType.searchColumns : ["identifier", "name"]),
|
|
self.markPatientEntry()
|
|
}, self.markPatientEntry = function() {
|
|
self.startPatientSearch = !0, window.setTimeout(function() {
|
|
self.startPatientSearch = !1
|
|
})
|
|
}, self.patientsCount = function() {
|
|
return self.activePatients.length
|
|
}, self.updatePatientList = function(patientList) {
|
|
self.activePatients = patientList.map(mapPatient), self.searchResults = self.activePatients
|
|
}, self.updateSearchResults = function(patientList) {
|
|
self.updatePatientList(patientList), 0 === self.activePatients.length && "" != self.searchParameter ? self.noResultsMessage = "NO_RESULTS_FOUND" : self.noResultsMessage = null
|
|
}, self.hasSingleActivePatient = function() {
|
|
return 1 === self.activePatients.length
|
|
}, self.filterPatients = function(matchingCriteria) {
|
|
matchingCriteria = matchingCriteria ? matchingCriteria : matchesNameOrId, self.searchResults = self.searchParameter ? self.activePatients.filter(matchingCriteria) : self.activePatients
|
|
}, self.filterPatientsByIdentifier = function() {
|
|
self.filterPatients(matchesId)
|
|
}, self.isSelectedSearch = function(searchType) {
|
|
return self.searchType && self.searchType.id == searchType.id
|
|
}, self.isCurrentSearchLookUp = function() {
|
|
return self.searchType && self.searchType.handler
|
|
}, self.isTileView = function() {
|
|
return self.searchType && self.searchType.view === Bahmni.Common.PatientSearch.Constants.searchExtensionTileViewType
|
|
}, self.isTabularView = function() {
|
|
return self.searchType && self.searchType.view === Bahmni.Common.PatientSearch.Constants.searchExtensionTabularViewType
|
|
}, self.showPatientCountOnSearchParameter = function(searchType) {
|
|
return showPatientCount(searchType) && self.searchParameter
|
|
};
|
|
var matchesNameOrId = function(patient) {
|
|
return patient.display.toLowerCase().indexOf(self.searchParameter.toLowerCase()) !== -1
|
|
},
|
|
matchesId = function(patient) {
|
|
return patient.identifier.toLowerCase().indexOf(self.searchParameter.toLowerCase()) !== -1
|
|
},
|
|
showPatientCount = function(searchType) {
|
|
return self.isSelectedSearch(searchType) && self.isCurrentSearchLookUp()
|
|
}
|
|
}, angular.module("bahmni.common.patientSearch").directive("resize", ["$window", function($window) {
|
|
var controller = function($scope) {
|
|
$scope.storeWindowDimensions = function() {
|
|
var windowWidth = window.innerWidth,
|
|
windowHeight = window.innerHeight,
|
|
tileWidth = Bahmni.Common.PatientSearch.Constants.patientTileWidth,
|
|
tileHeight = Bahmni.Common.PatientSearch.Constants.patientTileHeight;
|
|
$scope.tilesToFit = Math.ceil(windowWidth * windowHeight / (tileWidth * tileHeight)), $scope.tilesToLoad = Math.ceil($scope.tilesToFit * Bahmni.Common.PatientSearch.Constants.tileLoadRatio)
|
|
};
|
|
var updateVisibleResults = function() {
|
|
$scope.visibleResults = $scope.searchResults.slice(0, $scope.tilesToLoad)
|
|
};
|
|
$scope.loadMore = function() {
|
|
var last = $scope.visibleResults.length,
|
|
more = $scope.searchResults.length - last,
|
|
toShow = more > $scope.tilesToLoad ? $scope.tilesToLoad : more;
|
|
if (toShow > 0)
|
|
for (var i = 1; i <= toShow; i++) $scope.visibleResults.push($scope.searchResults[last + i - 1])
|
|
}, $scope.$watch("searchResults", updateVisibleResults), $scope.$watch("tilesToFit", updateVisibleResults)
|
|
},
|
|
link = function($scope) {
|
|
$scope.storeWindowDimensions(), angular.element($window).bind("resize", function() {
|
|
$scope.$apply(function() {
|
|
$scope.storeWindowDimensions()
|
|
})
|
|
})
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
link: link,
|
|
controller: controller,
|
|
transclude: !0,
|
|
scope: {
|
|
searchResults: "=",
|
|
visibleResults: "="
|
|
},
|
|
template: '<div ng-transclude infinite-scroll="loadMore()"></div>'
|
|
}
|
|
}]), angular.module("bahmni.common.patientSearch").directive("scheduler", ["$interval", function($interval) {
|
|
var link = function($scope) {
|
|
var promise, cancelSchedule = function() {
|
|
promise && ($interval.cancel(promise), promise = null)
|
|
},
|
|
startSchedule = function() {
|
|
promise || (promise = $interval($scope.triggerFunction, 1e3 * $scope.refreshTime))
|
|
};
|
|
$scope.$watch(function() {
|
|
return $scope.watchOn
|
|
}, function(value) {
|
|
$scope.refreshTime > 0 && (value ? cancelSchedule() : startSchedule())
|
|
}), $scope.triggerFunction(), $scope.$on("$destroy", function() {
|
|
cancelSchedule()
|
|
})
|
|
};
|
|
return {
|
|
restrict: "A",
|
|
link: link,
|
|
scope: {
|
|
refreshTime: "=",
|
|
watchOn: "=",
|
|
triggerFunction: "&"
|
|
}
|
|
}
|
|
}]), angular.module("bahmni.common.patientSearch").controller("PatientsListController", ["$scope", "$http", "$window", "patientService", "$rootScope", "appService", "spinner", "$stateParams", "$bahmniCookieStore", "printer", "configurationService", function($scope, $http, $window, patientService, $rootScope, appService, spinner, $stateParams, $bahmniCookieStore, printer, configurationService) {
|
|
const DEFAULT_FETCH_DELAY = 2e3;
|
|
var patientListSpinner, patientSearchConfig = appService.getAppDescriptor().getConfigValue("patientSearch"),
|
|
initialize = function() {
|
|
var searchTypes = appService.getAppDescriptor().getExtensions("org.bahmni.patient.search", "config").map(mapExtensionToSearchType);
|
|
$scope.search = new Bahmni.Common.PatientSearch.Search(_.without(searchTypes, void 0)), $scope.search.markPatientEntry(), $scope.$watch("search.searchType", function(currentSearchType) {
|
|
_.isEmpty(currentSearchType) || fetchPatients(currentSearchType)
|
|
}), $scope.$watch("search.activePatients", function(activePatientsList) {
|
|
activePatientsList.length > 0 && patientListSpinner && hideSpinner(spinner, patientListSpinner, $(".tab-content"))
|
|
}), patientSearchConfig && patientSearchConfig.serializeSearch ? getPatientCountSeriallyBySearchIndex(0) : _.each($scope.search.searchTypes, function(searchType) {
|
|
_.isEmpty(searchType) || $scope.search.searchType != searchType && getPatientCount(searchType, null)
|
|
}), null != $rootScope.currentSearchType && $scope.search.switchSearchType($rootScope.currentSearchType), configurationService.getConfigurations(["identifierTypesConfig"]).then(function(response) {
|
|
$scope.primaryIdentifier = _.find(response.identifierTypesConfig, {
|
|
primary: !0
|
|
}).name
|
|
})
|
|
};
|
|
$scope.searchPatients = function() {
|
|
return spinner.forPromise(patientService.search($scope.search.searchParameter)).then(function(response) {
|
|
$scope.search.updateSearchResults(response.data.pageOfResults), $scope.search.hasSingleActivePatient() && $scope.forwardPatient($scope.search.activePatients[0])
|
|
})
|
|
}, $scope.filterPatientsAndSubmit = function() {
|
|
1 == $scope.search.searchResults.length && $scope.forwardPatient($scope.search.searchResults[0])
|
|
};
|
|
var getPatientCount = function(searchType, patientListSpinner) {
|
|
if (searchType.handler) {
|
|
var params = {
|
|
q: searchType.handler,
|
|
v: "full",
|
|
location_uuid: $bahmniCookieStore.get(Bahmni.Common.Constants.locationCookieName).uuid,
|
|
provider_uuid: $rootScope.currentProvider.uuid
|
|
};
|
|
searchType.additionalParams && (params.additionalParams = searchType.additionalParams), patientService.findPatients(params).then(function(response) {
|
|
searchType.patientCount = response.data.length, $scope.search.isSelectedSearch(searchType) && $scope.search.updatePatientList(response.data), patientListSpinner && hideSpinner(spinner, patientListSpinner, $(".tab-content"))
|
|
})
|
|
}
|
|
},
|
|
hideSpinner = function(spinnerObj, data, container) {
|
|
spinnerObj.hide(data, container), $(container).children("patient-list-spinner").hide()
|
|
};
|
|
$scope.getHeadings = function(patients) {
|
|
if (patients && patients.length > 0) {
|
|
var headings = _.chain(patients[0]).keys().filter(function(heading) {
|
|
return _.indexOf(Bahmni.Common.PatientSearch.Constants.tabularViewIgnoreHeadingsList, heading) === -1
|
|
}).value();
|
|
return headings
|
|
}
|
|
return []
|
|
}, $scope.isHeadingOfLinkColumn = function(heading) {
|
|
var identifierHeading = _.includes(Bahmni.Common.PatientSearch.Constants.identifierHeading, heading);
|
|
return identifierHeading ? identifierHeading : $scope.search.searchType && $scope.search.searchType.links ? _.find($scope.search.searchType.links, {
|
|
linkColumn: heading
|
|
}) : $scope.search.searchType && $scope.search.searchType.linkColumn ? _.includes([$scope.search.searchType.linkColumn], heading) : void 0
|
|
}, $scope.isHeadingOfName = function(heading) {
|
|
return _.includes(Bahmni.Common.PatientSearch.Constants.nameHeading, heading)
|
|
}, $scope.getPrintableHeadings = function(patients) {
|
|
var headings = $scope.getHeadings(patients),
|
|
printableHeadings = headings.filter(function(heading) {
|
|
return _.indexOf(Bahmni.Common.PatientSearch.Constants.printIgnoreHeadingsList, heading) === -1
|
|
});
|
|
return printableHeadings
|
|
}, $scope.printPage = function() {
|
|
null != $scope.search.searchType.printHtmlLocation && printer.printFromScope($scope.search.searchType.printHtmlLocation, $scope)
|
|
};
|
|
var mapExtensionToSearchType = function(appExtn) {
|
|
return {
|
|
name: appExtn.label,
|
|
display: appExtn.extensionParams.display,
|
|
handler: appExtn.extensionParams.searchHandler,
|
|
forwardUrl: appExtn.extensionParams.forwardUrl,
|
|
id: appExtn.id,
|
|
params: appExtn.extensionParams.searchParams,
|
|
refreshTime: appExtn.extensionParams.refreshTime || 0,
|
|
view: appExtn.extensionParams.view || Bahmni.Common.PatientSearch.Constants.searchExtensionTileViewType,
|
|
showPrint: appExtn.extensionParams.showPrint || !1,
|
|
printHtmlLocation: appExtn.extensionParams.printHtmlLocation || null,
|
|
additionalParams: appExtn.extensionParams.additionalParams,
|
|
searchColumns: appExtn.extensionParams.searchColumns,
|
|
translationKey: appExtn.extensionParams.translationKey,
|
|
linkColumn: appExtn.extensionParams.linkColumn,
|
|
links: appExtn.extensionParams.links
|
|
}
|
|
},
|
|
debounceGetPatientCount = _.debounce(function(currentSearchType, patientListSpinner) {
|
|
getPatientCount(currentSearchType, patientListSpinner)
|
|
}, patientSearchConfig && patientSearchConfig.fetchDelay || DEFAULT_FETCH_DELAY, {}),
|
|
showSpinner = function(spinnerObj, container) {
|
|
return $(container).children("patient-list-spinner").show(), spinnerObj.show(container)
|
|
},
|
|
fetchPatients = function(currentSearchType) {
|
|
void 0 !== patientListSpinner && hideSpinner(spinner, patientListSpinner, $(".tab-content")), $rootScope.currentSearchType = currentSearchType, $scope.search.isCurrentSearchLookUp() && (patientListSpinner = showSpinner(spinner, $(".tab-content")), patientSearchConfig && patientSearchConfig.debounceSearch ? debounceGetPatientCount(currentSearchType, patientListSpinner) : getPatientCount(currentSearchType, patientListSpinner))
|
|
};
|
|
$scope.forwardPatient = function(patient, heading) {
|
|
var options = $.extend({}, $stateParams);
|
|
$rootScope.patientAdmitLocationStatus = patient.Status, $.extend(options, {
|
|
patientUuid: patient.uuid,
|
|
visitUuid: patient.activeVisitUuid || null,
|
|
encounterUuid: $stateParams.encounterUuid || "active",
|
|
programUuid: patient.programUuid || null,
|
|
enrollment: patient.enrollment || null,
|
|
forwardUrl: patient.forwardUrl || null,
|
|
dateEnrolled: patient.dateEnrolled || null
|
|
});
|
|
var link = options.forwardUrl ? {
|
|
url: options.forwardUrl,
|
|
newTab: !0
|
|
} : {
|
|
url: $scope.search.searchType.forwardUrl,
|
|
newTab: !1
|
|
};
|
|
$scope.search.searchType.links && (link = _.find($scope.search.searchType.links, {
|
|
linkColumn: heading
|
|
}) || link), "#/default/patient/{{patientUuid}}/dashboard?encounterUuid=active" === link.url ? $http({
|
|
method: "GET",
|
|
url: "/openmrs/ws/rest/v1/visit?includeInactive=true&patient=" + patient.uuid + "&v=custom:(uuid,visitType,startDatetime,stopDatetime,location,encounters:(uuid))"
|
|
}).then(function(response) {
|
|
var result = response.data.results;
|
|
result.length > 1 ? $window.open(appService.getAppDescriptor().formatUrl(link.url, options, !0), link.newTab ? "_blank" : "_self") : $window.location.href = "https://" + $window.location.hostname + ":6060/patientDashboard/" + patient.uuid
|
|
}) : $window.open(appService.getAppDescriptor().formatUrl(link.url, options, !0), link.newTab ? "_blank" : "_self")
|
|
};
|
|
var getPatientCountSeriallyBySearchIndex = function(index) {
|
|
if (index !== $scope.search.searchTypes.length) {
|
|
var searchType = $scope.search.searchTypes[index];
|
|
if (searchType.handler) {
|
|
var params = {
|
|
q: searchType.handler,
|
|
v: "full",
|
|
location_uuid: $bahmniCookieStore.get(Bahmni.Common.Constants.locationCookieName).uuid,
|
|
provider_uuid: $rootScope.currentProvider.uuid
|
|
};
|
|
searchType.additionalParams && (params.additionalParams = searchType.additionalParams), patientService.findPatients(params).then(function(response) {
|
|
return searchType.patientCount = response.data.length, $scope.search.isSelectedSearch(searchType) && $scope.search.updatePatientList(response.data), getPatientCountSeriallyBySearchIndex(index + 1)
|
|
})
|
|
}
|
|
}
|
|
};
|
|
initialize()
|
|
}]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.Domain = Bahmni.Common.Domain || {}, Bahmni.Common.Domain.Helper = Bahmni.Common.Domain.Helper || {}, angular.module("bahmni.common.domain", []), Bahmni.Common.Domain.RetrospectiveEntry = function() {
|
|
var self = this;
|
|
Object.defineProperty(this, "encounterDate", {
|
|
get: function() {
|
|
return self._encounterDate
|
|
},
|
|
set: function(value) {
|
|
value && (self._encounterDate = value)
|
|
}
|
|
})
|
|
}, Bahmni.Common.Domain.RetrospectiveEntry.createFrom = function(retrospectiveEncounterDateCookie) {
|
|
var obj = new Bahmni.Common.Domain.RetrospectiveEntry;
|
|
return obj.encounterDate = retrospectiveEncounterDateCookie, obj
|
|
}, Bahmni.Common.Domain.Diagnosis = function(codedAnswer, order, certainty, existingObsUuid, freeTextAnswer, diagnosisDateTime, voided) {
|
|
var self = this;
|
|
self.codedAnswer = codedAnswer, self.order = order, self.certainty = certainty, self.existingObs = existingObsUuid, self.freeTextAnswer = freeTextAnswer, self.diagnosisDateTime = diagnosisDateTime, self.diagnosisStatus = void 0, self.isNonCodedAnswer = !1, self.codedAnswer && (self.conceptName = self.codedAnswer.name), self.voided = voided, self.firstDiagnosis = null, self.comments = "", self.getDisplayName = function() {
|
|
return self.freeTextAnswer ? self.freeTextAnswer : self.codedAnswer.shortName || self.codedAnswer.name
|
|
}, self.isPrimary = function() {
|
|
return "PRIMARY" == self.order
|
|
}, self.isSecondary = function() {
|
|
return "SECONDARY" == self.order
|
|
}, self.isRuledOut = function() {
|
|
return self.diagnosisStatus == $rootScope.diagnosisStatus
|
|
}, self.answerNotFilled = function() {
|
|
return !self.codedAnswer.name
|
|
}, self.isValidAnswer = function() {
|
|
return self.codedAnswer.name && self.codedAnswer.uuid || self.codedAnswer.name && !self.codedAnswer.uuid && self.isNonCodedAnswer || self.answerNotFilled()
|
|
}, self.isValidOrder = function() {
|
|
return self.isEmpty() || void 0 !== self.order
|
|
}, self.isValidCertainty = function() {
|
|
return self.isEmpty() || void 0 !== self.certainty
|
|
}, self.isEmpty = function() {
|
|
return void 0 === self.getDisplayName() || 0 === self.getDisplayName().length
|
|
}, self.diagnosisStatusValue = null, self.diagnosisStatusConcept = null, Object.defineProperty(this, "diagnosisStatus", {
|
|
get: function() {
|
|
return this.diagnosisStatusValue
|
|
},
|
|
set: function(newStatus) {
|
|
newStatus ? (this.diagnosisStatusValue = newStatus, this.diagnosisStatusConcept = {
|
|
name: Bahmni.Common.Constants.ruledOutdiagnosisStatus
|
|
}) : (this.diagnosisStatusValue = null, this.diagnosisStatusConcept = null)
|
|
}
|
|
}), self.clearCodedAnswerUuid = function() {
|
|
self.codedAnswer.uuid = void 0
|
|
}, self.setAsNonCodedAnswer = function() {
|
|
self.isNonCodedAnswer = !self.isNonCodedAnswer
|
|
}
|
|
},
|
|
function() {
|
|
var DateUtil = Bahmni.Common.Util.DateUtil,
|
|
Conditions = Bahmni.Common.Domain.Conditions = {},
|
|
Condition = Bahmni.Common.Domain.Condition = function(data) {
|
|
data = data || {}, this.uuid = data.uuid, this.concept = {
|
|
uuid: _.get(data, "concept.uuid"),
|
|
shortName: _.get(data, "concept.shortName"),
|
|
name: _.get(data, "concept.name")
|
|
}, this.status = data.status, this.onSetDate = data.onSetDate, this.conditionNonCoded = data.conditionNonCoded, this.voided = data.voided, this.additionalDetail = data.additionalDetail, this.isNonCoded = data.isNonCoded, this.creator = data.creator, this.previousConditionUuid = data.previousConditionUuid, this.activeSince = data.onSetDate
|
|
};
|
|
Condition.prototype = {}, Condition.prototype.toggleNonCoded = function() {
|
|
this.isNonCoded = !this.isNonCoded
|
|
}, Condition.prototype.clearConcept = function() {
|
|
this.concept.uuid = void 0
|
|
}, Condition.prototype.isValidConcept = function() {
|
|
return !(this.concept.name && !this.concept.uuid && !this.isNonCoded)
|
|
}, Condition.prototype.isValid = function() {
|
|
return this.status && (this.concept.name && this.isNonCoded || this.concept.uuid)
|
|
}, Condition.prototype.isActive = function() {
|
|
return "ACTIVE" == this.status
|
|
}, Condition.prototype.displayString = function() {
|
|
return this.conditionNonCoded || this.concept.shortName || this.concept.name
|
|
}, Condition.prototype.isEmpty = function() {
|
|
return !(this.status || this.concept.name || this.isNonCoded || this.concept.uuid || this.onSetDate || this.additionalDetail)
|
|
}, Condition.createFromDiagnosis = function(diagnosis) {
|
|
return new Condition({
|
|
concept: {
|
|
uuid: diagnosis.codedAnswer.uuid,
|
|
shortName: diagnosis.codedAnswer.shortName,
|
|
name: diagnosis.codedAnswer.name
|
|
},
|
|
status: "ACTIVE",
|
|
onSetDate: DateUtil.today(),
|
|
conditionNonCoded: diagnosis.freeTextAnswer,
|
|
additionalDetail: diagnosis.comments,
|
|
voided: !1
|
|
})
|
|
}, Conditions.fromConditionHistories = function(conditionsHistories) {
|
|
return _.map(conditionsHistories, function(conditionsHistory) {
|
|
var conditions = conditionsHistory.conditions;
|
|
return new Condition(_.last(_.sortBy(_.reject(conditions, "endDate"), "onSetDate")))
|
|
})
|
|
}, Conditions.getPreviousActiveCondition = function(condition, allConditions) {
|
|
if ("ACTIVE" == condition.status) return condition;
|
|
var previousCondition = _.find(allConditions, {
|
|
uuid: condition.previousConditionUuid
|
|
});
|
|
return previousCondition ? Conditions.getPreviousActiveCondition(previousCondition, allConditions) : condition
|
|
}
|
|
}(), angular.module("bahmni.common.domain").service("retrospectiveEntryService", ["$rootScope", "$bahmniCookieStore", function($rootScope, $bahmniCookieStore) {
|
|
var retrospectiveEntryService = this,
|
|
dateUtil = Bahmni.Common.Util.DateUtil;
|
|
this.getRetrospectiveEntry = function() {
|
|
return $rootScope.retrospectiveEntry
|
|
}, this.isRetrospectiveMode = function() {
|
|
return !_.isEmpty(retrospectiveEntryService.getRetrospectiveEntry())
|
|
}, this.getRetrospectiveDate = function() {
|
|
return $rootScope.retrospectiveEntry && $rootScope.retrospectiveEntry.encounterDate
|
|
}, this.initializeRetrospectiveEntry = function() {
|
|
var retrospectiveEncounterDateCookie = $bahmniCookieStore.get(Bahmni.Common.Constants.retrospectiveEntryEncounterDateCookieName);
|
|
retrospectiveEncounterDateCookie && ($rootScope.retrospectiveEntry = Bahmni.Common.Domain.RetrospectiveEntry.createFrom(dateUtil.getDate(retrospectiveEncounterDateCookie)))
|
|
}, this.resetRetrospectiveEntry = function(date) {
|
|
$bahmniCookieStore.remove(Bahmni.Common.Constants.retrospectiveEntryEncounterDateCookieName, {
|
|
path: "/",
|
|
expires: 1
|
|
}), $rootScope.retrospectiveEntry = void 0, date && !dateUtil.isSameDate(date, dateUtil.today()) && ($rootScope.retrospectiveEntry = Bahmni.Common.Domain.RetrospectiveEntry.createFrom(dateUtil.getDate(date)), $bahmniCookieStore.put(Bahmni.Common.Constants.retrospectiveEntryEncounterDateCookieName, date, {
|
|
path: "/",
|
|
expires: 1
|
|
}))
|
|
}
|
|
}]), angular.module("bahmni.common.domain").factory("dispositionService", ["$http", function($http) {
|
|
var getDispositionActions = function() {
|
|
return $http.get(Bahmni.Common.Constants.conceptSearchByFullNameUrl + "&name=" + Bahmni.Common.Constants.dispositionConcept + "&v=custom:(uuid,name,answers:(uuid,name,mappings))", {
|
|
cache: !0
|
|
})
|
|
},
|
|
getDispositionNoteConcept = function() {
|
|
return $http.get(Bahmni.Common.Constants.conceptSearchByFullNameUrl + "&name=" + Bahmni.Common.Constants.dispositionNoteConcept + "&v=custom:(uuid,name:(name))", {
|
|
cache: !0
|
|
})
|
|
},
|
|
getDispositionByVisit = function(visitUuid) {
|
|
return $http.get(Bahmni.Common.Constants.bahmniDispositionByVisitUrl, {
|
|
params: {
|
|
visitUuid: visitUuid
|
|
}
|
|
})
|
|
},
|
|
getDispositionByPatient = function(patientUuid, numberOfVisits) {
|
|
return $http.get(Bahmni.Common.Constants.bahmniDispositionByPatientUrl, {
|
|
params: {
|
|
patientUuid: patientUuid,
|
|
numberOfVisits: numberOfVisits
|
|
}
|
|
})
|
|
};
|
|
return {
|
|
getDispositionActions: getDispositionActions,
|
|
getDispositionNoteConcept: getDispositionNoteConcept,
|
|
getDispositionByVisit: getDispositionByVisit,
|
|
getDispositionByPatient: getDispositionByPatient
|
|
}
|
|
}]), angular.module("bahmni.common.domain").service("visitDocumentService", ["$http", "auditLogService", "configurations", "$q", function($http, auditLogService, configurations, $q) {
|
|
var removeVoidedDocuments = function(documents) {
|
|
documents.forEach(function(document) {
|
|
if (document.voided && document.image) {
|
|
var url = Bahmni.Common.Constants.RESTWS_V1 + "/bahmnicore/visitDocument?filename=" + document.image;
|
|
$http["delete"](url, {
|
|
withCredentials: !0
|
|
})
|
|
}
|
|
})
|
|
};
|
|
this.save = function(visitDocument) {
|
|
var url = Bahmni.Common.Constants.RESTWS_V1 + "/bahmnicore/visitDocument",
|
|
isNewVisit = !visitDocument.visitUuid;
|
|
removeVoidedDocuments(visitDocument.documents);
|
|
var visitTypeName = configurations.encounterConfig().getVisitTypeByUuid(visitDocument.visitTypeUuid).name,
|
|
encounterTypeName = configurations.encounterConfig().getEncounterTypeByUuid(visitDocument.encounterTypeUuid).name;
|
|
return $http.post(url, visitDocument).then(function(response) {
|
|
var promise = isNewVisit ? auditLogService.log(visitDocument.patientUuid, "OPEN_VISIT", {
|
|
visitUuid: response.data.visitUuid,
|
|
visitType: visitTypeName
|
|
}, encounterTypeName) : $q.when();
|
|
return promise.then(function() {
|
|
return auditLogService.log(visitDocument.patientUuid, "EDIT_ENCOUNTER", {
|
|
encounterUuid: response.data.encounterUuid,
|
|
encounterType: encounterTypeName
|
|
}, encounterTypeName).then(function() {
|
|
return response
|
|
})
|
|
})
|
|
})
|
|
}, this.saveFile = function(file, patientUuid, encounterTypeName, fileName, fileType) {
|
|
var searchStr = ";base64",
|
|
format = file.split(searchStr)[0].split("/")[1];
|
|
"video" === fileType && (format = _.last(_.split(fileName, ".")));
|
|
var url = Bahmni.Common.Constants.RESTWS_V1 + "/bahmnicore/visitDocument/uploadDocument";
|
|
return $http.post(url, {
|
|
content: file.substring(file.indexOf(searchStr) + searchStr.length, file.length),
|
|
format: format,
|
|
patientUuid: patientUuid,
|
|
encounterTypeName: encounterTypeName,
|
|
fileType: fileType || "file"
|
|
}, {
|
|
withCredentials: !0,
|
|
headers: {
|
|
Accept: "application/json",
|
|
"Content-Type": "application/json"
|
|
}
|
|
})
|
|
}, this.getFileType = function(fileType) {
|
|
var pdfType = "pdf",
|
|
imageType = "image";
|
|
return fileType.indexOf(pdfType) !== -1 ? pdfType : fileType.indexOf(imageType) !== -1 ? imageType : "not_supported"
|
|
}
|
|
}]), angular.module("bahmni.common.domain").service("bedService", ["$http", "$rootScope", function($http, $rootScope) {
|
|
var mapBedDetails = function(response) {
|
|
var results = response.data.results;
|
|
if (!_.isEmpty(results)) {
|
|
var bed = _.first(results);
|
|
return {
|
|
wardName: bed.physicalLocation.parentLocation.display,
|
|
wardUuid: bed.physicalLocation.parentLocation.uuid,
|
|
physicalLocationName: bed.physicalLocation.name,
|
|
bedNumber: bed.bedNumber,
|
|
bedId: bed.bedId
|
|
}
|
|
}
|
|
};
|
|
this.setBedDetailsForPatientOnRootScope = function(uuid) {
|
|
var promise = this.getAssignedBedForPatient(uuid);
|
|
return promise.then(function(bedDetails) {
|
|
$rootScope.bedDetails = bedDetails
|
|
}), promise
|
|
}, this.getAssignedBedForPatient = function(patientUuid, visitUuid) {
|
|
var params = {
|
|
patientUuid: patientUuid,
|
|
v: "full"
|
|
};
|
|
return visitUuid && (params.visitUuid = visitUuid, params.s = "bedDetailsFromVisit"), $http.get(Bahmni.Common.Constants.bedFromVisit, {
|
|
method: "GET",
|
|
params: params,
|
|
withCredentials: !0
|
|
}).then(mapBedDetails)
|
|
}, this.assignBed = function(bedId, patientUuid, encounterUuid) {
|
|
var patientJson = {
|
|
patientUuid: patientUuid,
|
|
encounterUuid: encounterUuid
|
|
};
|
|
return $http.post(Bahmni.Common.Constants.bedFromVisit + "/" + bedId, patientJson, {
|
|
withCredentials: !0,
|
|
headers: {
|
|
Accept: "application/json",
|
|
"Content-Type": "application/json"
|
|
}
|
|
})
|
|
}, this.getBedInfo = function(bedId) {
|
|
return $http.get(Bahmni.Common.Constants.bedFromVisit + "/" + bedId + "?v=custom:(bedId,bedNumber,patients:(uuid,person:(age,personName:(givenName,familyName),gender),identifiers:(uuid,identifier),),physicalLocation:(name))", {
|
|
withCredentials: !0
|
|
})
|
|
}, this.getCompleteBedDetailsByBedId = function(bedId) {
|
|
return $http.get(Bahmni.Common.Constants.bedFromVisit + "/" + bedId, {
|
|
withCredentials: !0
|
|
})
|
|
}
|
|
}]), angular.module("bahmni.common.domain").factory("providerService", ["$http", function($http) {
|
|
var search = function(fieldValue) {
|
|
return $http.get(Bahmni.Common.Constants.providerUrl, {
|
|
method: "GET",
|
|
params: {
|
|
q: fieldValue,
|
|
v: "full"
|
|
},
|
|
withCredentials: !0
|
|
})
|
|
},
|
|
searchByUuid = function(uuid) {
|
|
return $http.get(Bahmni.Common.Constants.providerUrl, {
|
|
method: "GET",
|
|
params: {
|
|
user: uuid
|
|
},
|
|
cache: !1
|
|
})
|
|
},
|
|
list = function(params) {
|
|
return $http.get(Bahmni.Common.Constants.providerUrl, {
|
|
method: "GET",
|
|
cache: !1,
|
|
params: params
|
|
})
|
|
};
|
|
return {
|
|
search: search,
|
|
searchByUuid: searchByUuid,
|
|
list: list
|
|
}
|
|
}]), Bahmni.Common.Domain.Helper.getHintForNumericConcept = function(concept) {
|
|
if (concept) return null != concept.hiNormal && null != concept.lowNormal ? "(" + concept.lowNormal + " - " + concept.hiNormal + ")" : null != concept.hiNormal && null == concept.lowNormal ? "(< " + concept.hiNormal + ")" : null == concept.hiNormal && null != concept.lowNormal ? "(> " + concept.lowNormal + ")" : ""
|
|
}, Bahmni.Common.Domain.ProviderMapper = function() {
|
|
this.map = function(openMrsProvider) {
|
|
return openMrsProvider ? {
|
|
uuid: openMrsProvider.uuid,
|
|
name: openMrsProvider.preferredName ? openMrsProvider.preferredName.display : openMrsProvider.person.preferredName.display
|
|
} : null
|
|
}
|
|
}, Bahmni.Common.Domain.ConceptMapper = function() {
|
|
this.map = function(openMrsConcept) {
|
|
if (!openMrsConcept) return null;
|
|
if (alreadyMappedConcept(openMrsConcept)) return openMrsConcept;
|
|
var openMrsDescription = openMrsConcept.descriptions ? openMrsConcept.descriptions[0] : null,
|
|
shortConceptName = _.find(openMrsConcept.names, {
|
|
conceptNameType: "SHORT"
|
|
});
|
|
return {
|
|
uuid: openMrsConcept.uuid,
|
|
name: openMrsConcept.name.name,
|
|
shortName: shortConceptName ? shortConceptName.name : null,
|
|
description: openMrsDescription ? openMrsDescription.description : null,
|
|
set: openMrsConcept.set,
|
|
dataType: openMrsConcept.datatype ? openMrsConcept.datatype.name : null,
|
|
hiAbsolute: openMrsConcept.hiAbsolute,
|
|
lowAbsolute: openMrsConcept.lowAbsolute,
|
|
hiNormal: openMrsConcept.hiNormal,
|
|
handler: openMrsConcept.handler,
|
|
allowDecimal: openMrsConcept.allowDecimal,
|
|
lowNormal: openMrsConcept.lowNormal,
|
|
conceptClass: openMrsConcept.conceptClass ? openMrsConcept.conceptClass.name : null,
|
|
answers: openMrsConcept.answers,
|
|
units: openMrsConcept.units,
|
|
displayString: shortConceptName ? shortConceptName.name : openMrsConcept.name.name,
|
|
names: openMrsConcept.names
|
|
}
|
|
};
|
|
var alreadyMappedConcept = function(concept) {
|
|
return !concept.name.name
|
|
}
|
|
}, Bahmni.Common.Domain.ObservationMapper = function() {
|
|
this.map = function(openMrsObs) {
|
|
var conceptMapper = new Bahmni.Common.Domain.ConceptMapper,
|
|
groupMembers = openMrsObs.groupMembers || [];
|
|
return {
|
|
uuid: openMrsObs.uuid,
|
|
concept: conceptMapper.map(openMrsObs.concept),
|
|
value: openMrsObs.value,
|
|
voided: openMrsObs.voided,
|
|
voidedReason: openMrsObs.voidedReason,
|
|
observationDateTime: openMrsObs.obsDatetime,
|
|
orderUuid: openMrsObs.orderUuid,
|
|
groupMembers: groupMembers.map(this.map)
|
|
}
|
|
}
|
|
},
|
|
function() {
|
|
var nameFor = {
|
|
Date: function(obs) {
|
|
return moment(obs.value).format("D-MMM-YYYY")
|
|
},
|
|
Datetime: function(obs) {
|
|
var date = Bahmni.Common.Util.DateUtil.parseDatetime(obs.value);
|
|
return null != date ? Bahmni.Common.Util.DateUtil.formatDateWithTime(date) : ""
|
|
},
|
|
Boolean: function(obs) {
|
|
return obs.value === !0 ? "Yes" : obs.value === !1 ? "No" : obs.value
|
|
},
|
|
Coded: function(obs) {
|
|
return obs.value.shortName || obs.value.name || obs.value
|
|
},
|
|
Object: function(obs) {
|
|
return nameFor.Coded(obs)
|
|
},
|
|
MultiSelect: function(obs) {
|
|
return obs.getValues().join(", ")
|
|
},
|
|
Default: function(obs) {
|
|
return obs.value
|
|
}
|
|
};
|
|
Bahmni.Common.Domain.ObservationValueMapper = {
|
|
getNameFor: nameFor,
|
|
map: function(obs) {
|
|
var type = obs.concept && obs.concept.dataType || obs.type;
|
|
return type in nameFor || (type = "object" == typeof obs.value && "Object" || obs.isMultiSelect && "MultiSelect" || "Default"), nameFor[type](obs)
|
|
}
|
|
}
|
|
}(), Bahmni.DiagnosisMapper = function(diagnosisStatus) {
|
|
var self = this,
|
|
mapDiagnosis = function(diagnosis) {
|
|
diagnosis.codedAnswer || (diagnosis.codedAnswer = {
|
|
name: void 0,
|
|
uuid: void 0
|
|
});
|
|
var mappedDiagnosis = angular.extend(new Bahmni.Common.Domain.Diagnosis, diagnosis);
|
|
return mappedDiagnosis.firstDiagnosis && (mappedDiagnosis.firstDiagnosis = mapDiagnosis(mappedDiagnosis.firstDiagnosis)), mappedDiagnosis.latestDiagnosis && (mappedDiagnosis.latestDiagnosis = mapDiagnosis(mappedDiagnosis.latestDiagnosis)), diagnosis.diagnosisStatusConcept && Bahmni.Common.Constants.ruledOutdiagnosisStatus === diagnosis.diagnosisStatusConcept.name && (mappedDiagnosis.diagnosisStatus = diagnosisStatus), mappedDiagnosis
|
|
};
|
|
self.mapDiagnosis = mapDiagnosis, self.mapDiagnoses = function(diagnoses) {
|
|
var mappedDiagnoses = [];
|
|
return _.each(diagnoses, function(diagnosis) {
|
|
mappedDiagnoses.push(mapDiagnosis(diagnosis))
|
|
}), mappedDiagnoses
|
|
}, self.mapPastDiagnosis = function(diagnoses, currentEncounterUuid) {
|
|
var pastDiagnosesResponse = [];
|
|
return diagnoses.forEach(function(diagnosis) {
|
|
diagnosis.encounterUuid !== currentEncounterUuid && (diagnosis.previousObs = diagnosis.existingObs, diagnosis.existingObs = null, diagnosis.inCurrentEncounter = void 0, pastDiagnosesResponse.push(diagnosis))
|
|
}), pastDiagnosesResponse
|
|
}, self.mapSavedDiagnosesFromCurrentEncounter = function(diagnoses, currentEncounterUuid) {
|
|
var savedDiagnosesFromCurrentEncounter = [];
|
|
return diagnoses.forEach(function(diagnosis) {
|
|
diagnosis.encounterUuid === currentEncounterUuid && (diagnosis.inCurrentEncounter = !0, savedDiagnosesFromCurrentEncounter.push(diagnosis))
|
|
}), savedDiagnosesFromCurrentEncounter
|
|
}
|
|
};
|
|
var EncounterConfig = function() {
|
|
function EncounterConfig(encounterTypes) {
|
|
this.encounterTypes = encounterTypes
|
|
}
|
|
return EncounterConfig.prototype = {
|
|
getConsultationEncounterTypeUuid: function() {
|
|
return this.getEncounterTypeUuid("Consultation")
|
|
},
|
|
getAdmissionEncounterTypeUuid: function() {
|
|
return this.getEncounterTypeUuid("ADMISSION")
|
|
},
|
|
getDischargeEncounterTypeUuid: function() {
|
|
return this.getEncounterTypeUuid("DISCHARGE")
|
|
},
|
|
getTransferEncounterTypeUuid: function() {
|
|
return this.getEncounterTypeUuid("TRANSFER")
|
|
},
|
|
getRadiologyEncounterTypeUuid: function() {
|
|
return this.getEncounterTypeUuid("RADIOLOGY")
|
|
},
|
|
getPatientDocumentEncounterTypeUuid: function() {
|
|
return this.getEncounterTypeUuid("Patient Document")
|
|
},
|
|
getValidationEncounterTypeUuid: function() {
|
|
return this.getEncounterTypeUuid(Bahmni.Common.Constants.validationNotesEncounterType)
|
|
},
|
|
getEncounterTypeUuid: function(encounterTypeName) {
|
|
return this.encounterTypes[encounterTypeName]
|
|
},
|
|
getVisitTypes: function() {
|
|
var visitTypesArray = [];
|
|
for (var name in this.visitTypes) visitTypesArray.push({
|
|
name: name,
|
|
uuid: this.visitTypes[name]
|
|
});
|
|
return visitTypesArray
|
|
},
|
|
getEncounterTypes: function() {
|
|
var encounterTypesArray = [];
|
|
for (var name in this.encounterTypes) encounterTypesArray.push({
|
|
name: name,
|
|
uuid: this.encounterTypes[name]
|
|
});
|
|
return encounterTypesArray
|
|
},
|
|
getVisitTypeByUuid: function(uuid) {
|
|
var visitTypes = this.getVisitTypes();
|
|
return visitTypes.filter(function(visitType) {
|
|
return visitType.uuid === uuid
|
|
})[0]
|
|
},
|
|
getEncounterTypeByUuid: function(uuid) {
|
|
var encounterType = this.getEncounterTypes();
|
|
return encounterType.filter(function(encounterType) {
|
|
return encounterType.uuid === uuid
|
|
})[0]
|
|
}
|
|
}, EncounterConfig
|
|
}();
|
|
! function() {
|
|
Bahmni.Common.Domain.ObservationFilter = function() {
|
|
var self = this,
|
|
voidExistingObservationWithOutValue = function(observations) {
|
|
observations.forEach(function(observation) {
|
|
voidExistingObservationWithOutValue(observation.groupMembers), observation.voided = observation.voided || observation.canBeVoided(), observation.voided && voidAllChildren(observation)
|
|
})
|
|
},
|
|
voidAllChildren = function(voidedObservation) {
|
|
voidedObservation.groupMembers.forEach(function(childWithVoidedParent) {
|
|
childWithVoidedParent.voided = !0, voidAllChildren(childWithVoidedParent)
|
|
})
|
|
},
|
|
removeNewObservationsWithoutValue = function(observations) {
|
|
return observations.forEach(function(observation) {
|
|
observation.groupMembers = removeNewObservationsWithoutValue(observation.groupMembers)
|
|
}), observations.filter(function(observation) {
|
|
var validObs = observation.isExisting() || observation.hasValue() || observation.hasMemberWithValue();
|
|
return validObs && !observation.voided || observation.isExisting() && observation.voided
|
|
})
|
|
},
|
|
removeNewObservationsWhichAreVoided = function(observations) {
|
|
return observations.forEach(function(observation) {
|
|
observation.groupMembers = removeNewObservationsWhichAreVoided(observation.groupMembers)
|
|
}), _.reject(observations, function(observation) {
|
|
return observation.isNew() && observation.voided
|
|
})
|
|
};
|
|
self.filter = function(observations) {
|
|
var wrappedObservations = observations.map(Observation.wrap),
|
|
filteredObservations = removeNewObservationsWithoutValue(wrappedObservations);
|
|
return filteredObservations = removeNewObservationsWhichAreVoided(filteredObservations), voidExistingObservationWithOutValue(filteredObservations), filteredObservations
|
|
}
|
|
};
|
|
var Observation = function(observationData) {
|
|
angular.extend(this, observationData), this.isNew = function() {
|
|
return !this.uuid
|
|
}, this.isExisting = function() {
|
|
return !this.isNew()
|
|
}, this.hasValue = function() {
|
|
return void 0 !== this.value && null !== this.value && "" !== this.value
|
|
}, this.hasMemberWithValue = function() {
|
|
return this.groupMembers.some(function(groupMember) {
|
|
return groupMember.hasValue() || groupMember.hasMemberWithValue()
|
|
})
|
|
}, this.isGroup = function() {
|
|
return this.groupMembers.length > 0
|
|
}, this.isLeaf = function() {
|
|
return !this.isGroup()
|
|
}, this.isGroupWithOnlyVoidedMembers = function() {
|
|
return this.isGroup() && this.groupMembers.every(function(groupMember) {
|
|
return groupMember.voided
|
|
})
|
|
}, this.isLeafNodeWithOutValue = function() {
|
|
return this.isLeaf() && !this.hasValue()
|
|
}, this.canBeVoided = function() {
|
|
return this.isExisting() && (this.isLeafNodeWithOutValue() || this.isGroupWithOnlyVoidedMembers())
|
|
}
|
|
};
|
|
Observation.wrap = function(observationData) {
|
|
var observation = new Observation(observationData);
|
|
return observation.groupMembers = observation.groupMembers ? observation.groupMembers.map(Observation.wrap) : [], observation
|
|
}
|
|
}(), angular.module("bahmni.common.gallery", []), angular.module("bahmni.common.gallery").directive("bmGalleryPane", ["$rootScope", "$document", "observationsService", "encounterService", "spinner", "configurations", "ngDialog", function($rootScope, $document, observationsService, encounterService, spinner, configurations, ngDialog) {
|
|
function close() {
|
|
$("body #gallery-pane").remove(),
|
|
$body.removeClass("gallery-open"), keyboardJS.releaseKey("right"), keyboardJS.releaseKey("left")
|
|
}
|
|
var $body = $document.find("body");
|
|
$rootScope.$on("$stateChangeStart", function() {
|
|
close()
|
|
});
|
|
var link = function($scope, element) {
|
|
$scope.galleryElement = element, $body.prepend($scope.galleryElement).addClass("gallery-open"), keyboardJS.on("right", function() {
|
|
$scope.$apply(function() {
|
|
$scope.getTotalLength() > 1 && $scope.showNext()
|
|
})
|
|
}), keyboardJS.on("left", function() {
|
|
$scope.$apply(function() {
|
|
$scope.getTotalLength() > 1 && $scope.showPrev()
|
|
})
|
|
})
|
|
},
|
|
controller = function($scope) {
|
|
$scope.imageIndex = $scope.imagePosition.index ? $scope.imagePosition.index : 0, $scope.albumTag = $scope.imagePosition.tag ? $scope.imagePosition.tag : "defaultTag", $scope.showImpression = !1, $scope.isActive = function(index, tag) {
|
|
return $scope.imageIndex == index && $scope.albumTag == tag
|
|
};
|
|
var getAlbumIndex = function() {
|
|
return _.findIndex($scope.albums, function(album) {
|
|
return album.tag == $scope.albumTag
|
|
})
|
|
};
|
|
$scope.showPrev = function() {
|
|
var albumIndex = getAlbumIndex();
|
|
if ($scope.imageIndex > 0) --$scope.imageIndex;
|
|
else {
|
|
0 == albumIndex && (albumIndex = $scope.albums.length);
|
|
var previousAlbum = $scope.albums[albumIndex - 1];
|
|
0 == previousAlbum.images.length && $scope.showPrev(albumIndex - 1), $scope.albumTag = previousAlbum.tag, $scope.imageIndex = previousAlbum.images.length - 1
|
|
}
|
|
}, $scope.showNext = function() {
|
|
var albumIndex = getAlbumIndex();
|
|
if ($scope.imageIndex < $scope.albums[albumIndex].images.length - 1) ++$scope.imageIndex;
|
|
else {
|
|
albumIndex == $scope.albums.length - 1 && (albumIndex = -1);
|
|
var nextAlbum = $scope.albums[albumIndex + 1];
|
|
0 == nextAlbum.images.length && $scope.showNext(albumIndex + 1), $scope.albumTag = nextAlbum.tag, $scope.imageIndex = 0
|
|
}
|
|
}, $scope.isPdf = function(image) {
|
|
return image.src && image.src.indexOf(".pdf") > 0
|
|
}, $scope.getTotalLength = function() {
|
|
var totalLength = 0;
|
|
return angular.forEach($scope.albums, function(album) {
|
|
totalLength += album.images.length
|
|
}), totalLength
|
|
}, $scope.getCurrentIndex = function() {
|
|
for (var currentIndex = 1, i = 0; i < getAlbumIndex(); i++) currentIndex += $scope.albums[i].images.length;
|
|
return currentIndex + parseInt($scope.imageIndex)
|
|
}, $scope.close = function() {
|
|
close($scope)
|
|
}, $scope.toggleImpression = function() {
|
|
$scope.showImpression = !$scope.showImpression
|
|
}, $scope.hasObsRelationship = function(image) {
|
|
return image.commentOnUpload || image.sourceObs && image.sourceObs.length > 0
|
|
}, $scope.saveImpression = function(image) {
|
|
var bahmniEncounterTransaction = mapBahmniEncounterTransaction(image);
|
|
spinner.forPromise(encounterService.create(bahmniEncounterTransaction).then(function() {
|
|
constructNewSourceObs(image), fetchObsRelationship(image)
|
|
}))
|
|
};
|
|
var init = function() {
|
|
$scope.accessImpression && $scope.albums.forEach(function(album) {
|
|
album.images.forEach(function(image) {
|
|
fetchObsRelationship(image), constructNewSourceObs(image)
|
|
})
|
|
}), ngDialog.openConfirm({
|
|
template: "../common/gallery/views/gallery.html",
|
|
scope: $scope,
|
|
closeByEscape: !0,
|
|
className: "gallery-dialog ngdialog-theme-default"
|
|
})
|
|
},
|
|
fetchObsRelationship = function(image) {
|
|
observationsService.getObsRelationship(image.uuid).then(function(response) {
|
|
image.sourceObs = response.data
|
|
})
|
|
},
|
|
constructNewSourceObs = function(image) {
|
|
image.newSourceObs = $scope.newSourceObs && $scope.newSourceObs.targetObsRelation.targetObs.uuid === image.uuid ? $scope.targetObs : {
|
|
value: "",
|
|
concept: {
|
|
uuid: configurations.impressionConcept().uuid
|
|
},
|
|
targetObsRelation: {
|
|
relationshipType: Bahmni.Common.Constants.qualifiedByRelationshipType,
|
|
targetObs: {
|
|
uuid: image.uuid
|
|
}
|
|
}
|
|
}
|
|
},
|
|
mapBahmniEncounterTransaction = function(image) {
|
|
return {
|
|
patientUuid: $scope.patient.uuid,
|
|
encounterTypeUuid: configurations.encounterConfig().getConsultationEncounterTypeUuid(),
|
|
observations: [image.newSourceObs]
|
|
}
|
|
};
|
|
init()
|
|
};
|
|
return {
|
|
link: link,
|
|
controller: controller
|
|
}
|
|
}]), angular.module("bahmni.common.uiHelper", ["ngClipboard"]), angular.module("bahmni.common.uiHelper").factory("spinner", ["messagingService", "$timeout", function(messagingService, $timeout) {
|
|
var tokens = [],
|
|
topLevelDiv = function(element) {
|
|
return $(element).find("div").eq(0)
|
|
},
|
|
showSpinnerForElement = function(element) {
|
|
return 0 === $(element).find(".dashboard-section-loader").length && topLevelDiv(element).addClass("spinnable").append('<div class="dashboard-section-loader"></div>'), {
|
|
element: $(element).find(".dashboard-section-loader")
|
|
}
|
|
},
|
|
showSpinnerForOverlay = function() {
|
|
var token = Math.random();
|
|
tokens.push(token), 0 === $("#overlay").length && $("body").prepend('<div id="overlay"><div></div></div>');
|
|
var spinnerElement = $("#overlay");
|
|
return spinnerElement.stop().show(), {
|
|
element: spinnerElement,
|
|
token: token
|
|
}
|
|
},
|
|
show = function(element) {
|
|
return void 0 !== element ? showSpinnerForElement(element) : showSpinnerForOverlay()
|
|
},
|
|
hide = function(spinner, parentElement) {
|
|
var spinnerElement = spinner.element;
|
|
spinner.token ? (_.pull(tokens, spinner.token), 0 === tokens.length && spinnerElement.fadeOut(300)) : (topLevelDiv(parentElement).removeClass("spinnable"), spinnerElement && spinnerElement.remove())
|
|
},
|
|
forPromise = function(promise, element) {
|
|
return $timeout(function() {
|
|
var spinner = show(element);
|
|
return promise["finally"](function() {
|
|
hide(spinner, element)
|
|
}), promise
|
|
})
|
|
},
|
|
forAjaxPromise = function(promise, element) {
|
|
var spinner = show(element);
|
|
return promise.always(function() {
|
|
hide(spinner, element)
|
|
}), promise
|
|
};
|
|
return {
|
|
forPromise: forPromise,
|
|
forAjaxPromise: forAjaxPromise,
|
|
show: show,
|
|
hide: hide
|
|
}
|
|
}]), angular.module("bahmni.common.uiHelper").factory("printer", ["$rootScope", "$compile", "$http", "$timeout", "$q", "spinner", function($rootScope, $compile, $http, $timeout, $q, spinner) {
|
|
var printHtml = function(html) {
|
|
var deferred = $q.defer(),
|
|
hiddenFrame = $('<iframe style="visibility: hidden"></iframe>').appendTo("body")[0];
|
|
hiddenFrame.contentWindow.printAndRemove = function() {
|
|
hiddenFrame.contentWindow.print(), $(hiddenFrame).remove(), deferred.resolve()
|
|
};
|
|
var htmlContent = '<!doctype html><html><body onload="printAndRemove();">' + html + "</body></html>",
|
|
doc = hiddenFrame.contentWindow.document.open("text/html", "replace");
|
|
return doc.write(htmlContent), doc.close(), deferred.promise
|
|
},
|
|
print = function(templateUrl, data) {
|
|
$rootScope.isBeingPrinted = !0, $http.get(templateUrl).then(function(templateData) {
|
|
var template = templateData.data,
|
|
printScope = $rootScope.$new();
|
|
angular.extend(printScope, data);
|
|
var element = $compile($("<div>" + template + "</div>"))(printScope),
|
|
renderAndPrintPromise = $q.defer(),
|
|
waitForRenderAndPrint = function() {
|
|
return printScope.$$phase || $http.pendingRequests.length ? $timeout(waitForRenderAndPrint, 1e3) : (printHtml(element.html()).then(function() {
|
|
$rootScope.isBeingPrinted = !1, renderAndPrintPromise.resolve()
|
|
}), printScope.$destroy()), renderAndPrintPromise.promise
|
|
};
|
|
spinner.forPromise(waitForRenderAndPrint())
|
|
})
|
|
},
|
|
printFromScope = function(templateUrl, scope, afterPrint) {
|
|
$rootScope.isBeingPrinted = !0, $http.get(templateUrl).then(function(response) {
|
|
var template = response.data,
|
|
printScope = scope,
|
|
element = $compile($("<div>" + template + "</div>"))(printScope),
|
|
renderAndPrintPromise = $q.defer(),
|
|
waitForRenderAndPrint = function() {
|
|
return printScope.$$phase || $http.pendingRequests.length ? $timeout(waitForRenderAndPrint) : printHtml(element.html()).then(function() {
|
|
$rootScope.isBeingPrinted = !1, afterPrint && afterPrint(), renderAndPrintPromise.resolve()
|
|
}), renderAndPrintPromise.promise
|
|
};
|
|
spinner.forPromise(waitForRenderAndPrint())
|
|
})
|
|
};
|
|
return {
|
|
print: print,
|
|
printFromScope: printFromScope
|
|
}
|
|
}]), angular.module("bahmni.common.uiHelper").directive("nonBlank", function() {
|
|
return function($scope, element, attrs) {
|
|
var addNonBlankAttrs = function() {
|
|
element.attr({
|
|
required: "required"
|
|
})
|
|
},
|
|
removeNonBlankAttrs = function() {
|
|
element.removeAttr("required")
|
|
};
|
|
return attrs.nonBlank ? void $scope.$watch(attrs.nonBlank, function(value) {
|
|
return value ? addNonBlankAttrs() : removeNonBlankAttrs()
|
|
}) : addNonBlankAttrs(element)
|
|
}
|
|
}).directive("datepicker", function() {
|
|
var link = function($scope, element, attrs, ngModel) {
|
|
var maxDate = attrs.maxDate,
|
|
minDate = attrs.minDate || "-120y",
|
|
format = attrs.dateFormat || "dd-mm-yy";
|
|
element.datepicker({
|
|
changeYear: !0,
|
|
changeMonth: !0,
|
|
maxDate: maxDate,
|
|
minDate: minDate,
|
|
yearRange: "c-120:c+120",
|
|
dateFormat: format,
|
|
onSelect: function(dateText) {
|
|
$scope.$apply(function() {
|
|
ngModel.$setViewValue(dateText)
|
|
})
|
|
}
|
|
})
|
|
};
|
|
return {
|
|
require: "ngModel",
|
|
link: link
|
|
}
|
|
}).directive("myAutocomplete", ["$parse", function($parse) {
|
|
var link = function(scope, element, attrs, ngModelCtrl) {
|
|
var source = ($parse(attrs.ngModel), scope.source()),
|
|
responseMap = scope.responseMap(),
|
|
onSelect = scope.onSelect();
|
|
element.autocomplete({
|
|
autofocus: !0,
|
|
minLength: 2,
|
|
source: function(request, response) {
|
|
source(attrs.id, request.term, attrs.itemType).then(function(data) {
|
|
var results = responseMap ? responseMap(data.data) : data.data;
|
|
response(results)
|
|
})
|
|
},
|
|
select: function(event, ui) {
|
|
return scope.$apply(function(scope) {
|
|
ngModelCtrl.$setViewValue(ui.item.value), scope.$eval(attrs.ngChange), null != onSelect && onSelect(ui.item)
|
|
}), !0
|
|
},
|
|
search: function(event) {
|
|
var searchTerm = $.trim(element.val());
|
|
searchTerm.length < 2 && event.preventDefault()
|
|
}
|
|
})
|
|
};
|
|
return {
|
|
link: link,
|
|
require: "ngModel",
|
|
scope: {
|
|
source: "&",
|
|
responseMap: "&",
|
|
onSelect: "&"
|
|
}
|
|
}
|
|
}]).directive("bmForm", ["$timeout", function($timeout) {
|
|
var link = function(scope, elem, attrs) {
|
|
$timeout(function() {
|
|
$(elem).unbind("submit").submit(function(e) {
|
|
var formScope = scope.$parent,
|
|
formName = attrs.name;
|
|
e.preventDefault(), scope.autofillable && $(elem).find("input").trigger("change"), formScope[formName].$valid ? (formScope.$apply(attrs.ngSubmit), $(elem).removeClass("submitted-with-error")) : $(elem).addClass("submitted-with-error")
|
|
})
|
|
}, 0)
|
|
};
|
|
return {
|
|
link: link,
|
|
require: "form",
|
|
scope: {
|
|
autofillable: "="
|
|
}
|
|
}
|
|
}]).directive("patternValidate", ["$timeout", function($timeout) {
|
|
return function($scope, element, attrs) {
|
|
var addPatternToElement = function() {
|
|
$scope.fieldValidation && $scope.fieldValidation[attrs.id] && element.attr({
|
|
pattern: $scope.fieldValidation[attrs.id].pattern,
|
|
title: $scope.fieldValidation[attrs.id].errorMessage,
|
|
type: "text"
|
|
})
|
|
};
|
|
$timeout(addPatternToElement)
|
|
}
|
|
}]).directive("validateOn", function() {
|
|
var link = function(scope, element, attrs, ngModelCtrl) {
|
|
var validationMessage = attrs.validationMessage || "Please enter a valid detail",
|
|
setValidity = function(value) {
|
|
var valid = !!value;
|
|
ngModelCtrl.$setValidity("blank", valid), element[0].setCustomValidity(valid ? "" : validationMessage)
|
|
};
|
|
scope.$watch(attrs.validateOn, setValidity, !0)
|
|
};
|
|
return {
|
|
link: link,
|
|
require: "ngModel"
|
|
}
|
|
}), angular.module("bahmni.common.uiHelper").directive("bahmniAutocomplete", ["$translate", function($translate) {
|
|
var link = function(scope, element, attrs, ngModelCtrl) {
|
|
var source = scope.source(),
|
|
responseMap = scope.responseMap && scope.responseMap(),
|
|
onSelect = scope.onSelect(),
|
|
onEdit = scope.onEdit && scope.onEdit(),
|
|
minLength = scope.minLength || 2,
|
|
formElement = element[0],
|
|
validationMessage = scope.validationMessage || $translate.instant("SELECT_VALUE_FROM_AUTOCOMPLETE_DEFAULT_MESSAGE"),
|
|
validateIfNeeded = function(value) {
|
|
scope.strictSelect && (scope.isInvalid = value !== scope.selectedValue, _.isEmpty(value) && (scope.isInvalid = !1))
|
|
};
|
|
scope.$watch("initialValue", function() {
|
|
scope.initialValue && (scope.selectedValue = scope.initialValue, scope.isInvalid = !1)
|
|
}), element.autocomplete({
|
|
autofocus: !0,
|
|
minLength: minLength,
|
|
source: function(request, response) {
|
|
source({
|
|
elementId: attrs.id,
|
|
term: request.term,
|
|
elementType: attrs.type
|
|
}).then(function(data) {
|
|
var results = responseMap ? responseMap(data) : data;
|
|
response(results)
|
|
})
|
|
},
|
|
select: function(event, ui) {
|
|
return scope.selectedValue = ui.item.value, ngModelCtrl.$setViewValue(ui.item.value), null != onSelect && onSelect(ui.item), validateIfNeeded(ui.item.value), scope.blurOnSelect && element.blur(), scope.$apply(), scope.$eval(attrs.ngDisabled), scope.$apply(), !0
|
|
},
|
|
search: function(event, ui) {
|
|
null != onEdit && onEdit(ui.item);
|
|
var searchTerm = $.trim(element.val());
|
|
validateIfNeeded(searchTerm), searchTerm.length < minLength && event.preventDefault()
|
|
}
|
|
});
|
|
var changeHanlder = function(e) {
|
|
validateIfNeeded(element.val())
|
|
},
|
|
keyUpHandler = function(e) {
|
|
validateIfNeeded(element.val()), scope.$apply()
|
|
};
|
|
element.on("change", changeHanlder), element.on("keyup", keyUpHandler), scope.$watch("isInvalid", function() {
|
|
ngModelCtrl.$setValidity("selection", !scope.isInvalid), formElement.setCustomValidity(scope.isInvalid ? validationMessage : "")
|
|
}), scope.$on("$destroy", function() {
|
|
element.off("change", changeHanlder), element.off("keyup", keyUpHandler)
|
|
})
|
|
};
|
|
return {
|
|
link: link,
|
|
require: "ngModel",
|
|
scope: {
|
|
source: "&",
|
|
responseMap: "&?",
|
|
onSelect: "&",
|
|
onEdit: "&?",
|
|
minLength: "=?",
|
|
blurOnSelect: "=?",
|
|
strictSelect: "=?",
|
|
validationMessage: "@",
|
|
isInvalid: "=?",
|
|
initialValue: "=?"
|
|
}
|
|
}
|
|
}]), angular.module("bahmni.common.uiHelper").directive("bmPopOver", function() {
|
|
var controller = function($scope) {
|
|
$scope.targetElements = [];
|
|
var hideTargetElements = function() {
|
|
$scope.targetElements.forEach(function(el) {
|
|
el.hide()
|
|
})
|
|
},
|
|
showTargetElements = function() {
|
|
$scope.targetElements.forEach(function(el) {
|
|
el.show()
|
|
})
|
|
};
|
|
this.registerTriggerElement = function(triggerElement) {
|
|
$scope.triggerElement = triggerElement;
|
|
var docClickHandler = function() {
|
|
$scope.autoclose && (hideTargetElements(), $scope.isTargetOpen = !1, $(document).off("click", docClickHandler))
|
|
};
|
|
$scope.triggerElement.on("click", function(event) {
|
|
$scope.isTargetOpen ? ($scope.isTargetOpen = !1, hideTargetElements(0), $(document).off("click", docClickHandler)) : ($scope.isTargetOpen = !0, showTargetElements(), $(document).on("click", docClickHandler), event.stopImmediatePropagation())
|
|
}), $scope.$on("$destroy", function() {
|
|
$(document).off("click", docClickHandler)
|
|
})
|
|
}, this.registerTargetElement = function(targetElement) {
|
|
targetElement.hide(), $scope.targetElements.push(targetElement)
|
|
};
|
|
var hideOrShowTargetElements = function() {
|
|
$scope.isTargetOpen && ($scope.isTargetOpen = !1, hideTargetElements(0))
|
|
};
|
|
$(document).on("click", ".reg-wrapper", hideOrShowTargetElements), $scope.$on("$destroy", function() {
|
|
$(document).off("click", ".reg-wrapper", hideOrShowTargetElements)
|
|
})
|
|
};
|
|
return {
|
|
restrict: "A",
|
|
controller: controller,
|
|
scope: {
|
|
autoclose: "="
|
|
}
|
|
}
|
|
}).directive("bmPopOverTarget", function() {
|
|
var link = function($scope, element, attrs, popOverController) {
|
|
popOverController.registerTargetElement(element)
|
|
};
|
|
return {
|
|
restrict: "A",
|
|
require: "^bmPopOver",
|
|
link: link
|
|
}
|
|
}).directive("bmPopOverTrigger", function() {
|
|
var link = function($scope, element, attrs, popOverController) {
|
|
popOverController.registerTriggerElement(element)
|
|
};
|
|
return {
|
|
restrict: "A",
|
|
require: "^bmPopOver",
|
|
link: link
|
|
}
|
|
}),
|
|
function() {
|
|
var constructSearchResult = function(concept, searchString) {
|
|
var matchingName = null,
|
|
conceptName = concept.name;
|
|
if (!_.includes(_.toLower(conceptName), _.toLower(searchString))) {
|
|
var synonyms = _.map(concept.names, "name");
|
|
matchingName = _.find(synonyms, function(name) {
|
|
return name !== conceptName && name.search(new RegExp(searchString, "i")) !== -1
|
|
})
|
|
}
|
|
return {
|
|
label: matchingName ? matchingName + " => " + conceptName : conceptName,
|
|
value: conceptName,
|
|
concept: concept,
|
|
uuid: concept.uuid,
|
|
name: conceptName
|
|
}
|
|
},
|
|
searchWithDefaultConcept = function(searchMethod, request, response) {
|
|
var searchTerm = _.toLower(request.term.trim()),
|
|
isMatching = function(answer) {
|
|
var conceptNameFound = _.find(answer.names, function(name) {
|
|
return _.includes(_.toLower(name.name), searchTerm)
|
|
}),
|
|
conceptDrugNameFound = _.includes(_.toLower(answer.name), searchTerm);
|
|
return conceptNameFound || conceptDrugNameFound
|
|
},
|
|
responseMap = _.partial(constructSearchResult, _, searchTerm);
|
|
searchMethod().then(_.partial(_.filter, _, isMatching)).then(_.partial(_.map, _, responseMap)).then(response)
|
|
},
|
|
searchWithGivenConcept = function(searchMethod, request, response) {
|
|
var searchTerm = request.term.trim(),
|
|
responseMap = _.partial(constructSearchResult, _, searchTerm);
|
|
searchMethod().then(_.partial(_.map, _, responseMap)).then(response)
|
|
},
|
|
toBeInjected = ["$parse", "$http", "conceptService"],
|
|
conceptAutocomplete = function($parse, $http, conceptService) {
|
|
var link = function(scope, element, attrs, ngModelCtrl) {
|
|
var minLength = scope.minLength || 2,
|
|
previousValue = scope.previousValue,
|
|
validator = function(searchTerm) {
|
|
if (scope.strictSelect) return scope.illegalValue || !_.isEmpty(searchTerm) && searchTerm !== previousValue ? void element.addClass("illegalValue") : void element.removeClass("illegalValue")
|
|
};
|
|
element.autocomplete({
|
|
autofocus: !0,
|
|
minLength: minLength,
|
|
source: function(request, response) {
|
|
var searchMethod;
|
|
!scope.answersConceptName && scope.defaultConcept ? (searchMethod = _.partial(conceptService.getAnswers, scope.defaultConcept), searchWithDefaultConcept(searchMethod, request, response)) : (searchMethod = _.partial(conceptService.getAnswersForConceptName, {
|
|
term: request.term,
|
|
answersConceptName: scope.answersConceptName
|
|
}), searchWithGivenConcept(searchMethod, request, response))
|
|
},
|
|
select: function(event, ui) {
|
|
return scope.$apply(function(scope) {
|
|
ngModelCtrl.$setViewValue(ui.item), scope.blurOnSelect && element.blur(), previousValue = ui.item.value, validator(previousValue), scope.$eval(attrs.ngChange)
|
|
}), !0
|
|
},
|
|
search: function(event) {
|
|
var searchTerm = $.trim(element.val());
|
|
searchTerm.length < minLength && event.preventDefault(), previousValue = null
|
|
}
|
|
});
|
|
var blurHandler = function() {
|
|
var searchTerm = $.trim(element.val());
|
|
validator(searchTerm)
|
|
};
|
|
element.on("blur", blurHandler), scope.$on("$destroy", function() {
|
|
element.off("blur", blurHandler)
|
|
})
|
|
};
|
|
return {
|
|
link: link,
|
|
require: "ngModel",
|
|
scope: {
|
|
illegalValue: "=",
|
|
defaultConcept: "=",
|
|
answersConceptName: "=",
|
|
minLength: "=",
|
|
blurOnSelect: "=",
|
|
strictSelect: "=?",
|
|
previousValue: "="
|
|
}
|
|
}
|
|
};
|
|
conceptAutocomplete.$inject = toBeInjected, angular.module("bahmni.common.uiHelper").directive("conceptAutocomplete", conceptAutocomplete)
|
|
}(), angular.module("bahmni.common.uiHelper").directive("datetimepicker", function() {
|
|
var link = function($scope) {
|
|
$scope.allowFutureDates || ($scope.maxDate = Bahmni.Common.Util.DateTimeFormatter.getDateWithoutTime());
|
|
var getSelectedDateStr = function() {
|
|
return null != $scope.selectedDate ? moment($scope.selectedDate).format("YYYY-MM-DD") : ""
|
|
},
|
|
getSelectedTimeStr = function() {
|
|
return null != $scope.selectedTime ? moment($scope.selectedTime).format("HH:mm") : ""
|
|
},
|
|
valueNotFilled = function() {
|
|
return null == $scope.selectedDate && null == $scope.selectedTime
|
|
},
|
|
valueCompletelyFilled = function() {
|
|
return null != $scope.selectedDate && null != $scope.selectedTime
|
|
};
|
|
if ($scope.updateModel = function() {
|
|
valueCompletelyFilled() ? $scope.model = getSelectedDateStr() + " " + getSelectedTimeStr() : $scope.isValid() ? $scope.model = "" : $scope.model = "Invalid Datetime"
|
|
}, $scope.isValid = function() {
|
|
return valueNotFilled() || valueCompletelyFilled()
|
|
}, $scope.model) {
|
|
var date = moment($scope.model).toDate();
|
|
$scope.selectedDate = date, $scope.selectedTime = date, $scope.updateModel()
|
|
}
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
link: link,
|
|
scope: {
|
|
model: "=",
|
|
observation: "=",
|
|
showTime: "=",
|
|
illegalValue: "=",
|
|
allowFutureDates: "="
|
|
},
|
|
template: "<div><input type='date' ng-change='updateModel()' ng-class=\"{'illegalValue': illegalValue}\" ng-attr-max='{{maxDate || undefined}}' ng-model='selectedDate' ng-disabled='observation.disabled' /></div><div><input type='time' ng-change='updateModel()' ng-class= \"{'illegalValue': !isValid()}\" ng-model='selectedTime' ng-disabled='observation.disabled' /></div>"
|
|
}
|
|
}), angular.module("bahmni.common.uiHelper").directive("monthyearpicker", ["$translate", function($translate) {
|
|
var link = function($scope) {
|
|
var monthNames = $translate.instant("MONTHS");
|
|
$scope.monthNames = monthNames.split(",");
|
|
var getYearList = function() {
|
|
for (var minYear = $scope.minYear ? $scope.minYear : moment().toDate().getFullYear() - 15, maxYear = $scope.maxYear ? $scope.maxYear : moment().toDate().getFullYear() + 5, yearList = [], i = maxYear; i >= minYear; i--) yearList.push(i);
|
|
return yearList
|
|
};
|
|
$scope.years = getYearList();
|
|
var valueCompletelyFilled = function() {
|
|
return null != $scope.selectedMonth && null != $scope.selectedYear
|
|
},
|
|
valueNotFilled = function() {
|
|
return null == $scope.selectedMonth && null == $scope.selectedYear
|
|
},
|
|
getCompleteDate = function() {
|
|
var month = $scope.selectedMonth + 1;
|
|
return $scope.selectedYear + "-" + month + "-01"
|
|
};
|
|
if ($scope.updateModel = function() {
|
|
valueCompletelyFilled() ? $scope.model = getCompleteDate() : $scope.isValid() ? $scope.model = "" : $scope.model = "Invalid Date"
|
|
}, $scope.isValid = function() {
|
|
return valueNotFilled() || valueCompletelyFilled()
|
|
}, $scope.illegalMonth = function() {
|
|
return (void 0 === $scope.selectedMonth || null === $scope.selectedMonth) && null !== $scope.selectedYear && void 0 !== $scope.selectedYear
|
|
}, $scope.illegalYear = function() {
|
|
return null !== $scope.selectedMonth && void 0 !== $scope.selectedMonth && (void 0 === $scope.selectedYear || null === $scope.selectedYear)
|
|
}, $scope.model) {
|
|
var date = moment($scope.model).toDate();
|
|
$scope.selectedMonth = date.getMonth(), $scope.selectedYear = date.getFullYear()
|
|
}
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
link: link,
|
|
scope: {
|
|
observation: "=",
|
|
minYear: "=",
|
|
maxYear: "=",
|
|
illegalValue: "=",
|
|
model: "="
|
|
},
|
|
template: '<span><select ng-model=\'selectedMonth\' ng-class="{\'illegalValue\': illegalMonth() || illegalValue}" ng-change="updateModel()" ng-options="monthNames.indexOf(month) as month for month in monthNames" ><option value="">{{\'CHOOSE_MONTH_KEY\' | translate}}</option>></select></span><span><select ng-model=\'selectedYear\' ng-class="{\'illegalValue\': illegalYear() || illegalValue}" ng-change="updateModel()" ng-options="year as year for year in years"><option value="">{{\'CHOOSE_YEAR_KEY\' | translate}}</option>></select></span>'
|
|
}
|
|
}]), angular.module("bahmni.common.uiHelper").directive("toggle", function() {
|
|
var link = function($scope, element) {
|
|
$scope.toggle = void 0 !== $scope.toggle && $scope.toggle, $(element).click(function() {
|
|
$scope.$apply(function() {
|
|
$scope.toggle = !$scope.toggle
|
|
})
|
|
}), $scope.$watch("toggle", function() {
|
|
$(element).toggleClass("active", $scope.toggle)
|
|
}), $scope.$on("$destroy", function() {
|
|
element.off("click")
|
|
})
|
|
};
|
|
return {
|
|
scope: {
|
|
toggle: "="
|
|
},
|
|
link: link
|
|
}
|
|
}), angular.module("bahmni.common.uiHelper").directive("bmGallery", ["$location", "$rootScope", "$compile", function($location, $rootScope, $compile) {
|
|
var controller = function($scope) {
|
|
$scope.albums = [], $scope.imagePosition = {
|
|
tag: void 0,
|
|
index: 0
|
|
}, this.image = function(record) {
|
|
var provider = record.provider;
|
|
return {
|
|
src: Bahmni.Common.Constants.documentsPath + "/" + record.imageObservation.value,
|
|
title: record.concept.name,
|
|
commentOnUpload: record.comment || record.imageObservation.comment,
|
|
date: record.imageObservation.observationDateTime,
|
|
uuid: record.imageObservation.uuid,
|
|
providerName: provider ? provider.name : null
|
|
}
|
|
}, this.addImageObservation = function(record, tag) {
|
|
return this.addImage(this.image(record), tag)
|
|
}, this.addImage = function(image, tag, tagOrder) {
|
|
var matchedAlbum = getMatchingAlbum(tag);
|
|
if (matchedAlbum) {
|
|
var index = image.imageIndex ? image.imageIndex : matchedAlbum.images.length;
|
|
matchedAlbum.images.splice(index, 0, image)
|
|
} else {
|
|
var newAlbum = {};
|
|
newAlbum.tag = tag, newAlbum.images = [image], $scope.albums.splice(tagOrder, 0, newAlbum)
|
|
}
|
|
return $scope.albums[0].images.length - 1
|
|
};
|
|
var getMatchingAlbum = function(tag) {
|
|
return _.find($scope.albums, function(album) {
|
|
return album.tag == tag
|
|
})
|
|
};
|
|
this.removeImage = function(image, tag, index) {
|
|
var matchedAlbum = getMatchingAlbum(tag);
|
|
matchedAlbum && matchedAlbum.images && matchedAlbum.images.splice(index, 1)
|
|
}, this.setIndex = function(tag, index) {
|
|
$scope.imagePosition.tag = tag, $scope.imagePosition.index = index
|
|
}, this.open = function() {
|
|
$compile("<div bm-gallery-pane id='gallery-pane'></div>")($scope)
|
|
}
|
|
};
|
|
return {
|
|
controller: controller,
|
|
scope: {
|
|
patient: "=",
|
|
accessImpression: "=?"
|
|
}
|
|
}
|
|
}]).directive("bmGalleryItem", function() {
|
|
var link = function($scope, element, attrs, imageGalleryController) {
|
|
var image = {
|
|
src: $scope.image.encodedValue,
|
|
title: $scope.image.concept ? $scope.image.concept.name : "",
|
|
date: $scope.image.obsDatetime,
|
|
uuid: $scope.image.obsUuid,
|
|
providerName: $scope.image.provider ? $scope.image.provider.name : "",
|
|
imageIndex: $scope.image.imageIndex,
|
|
commentOnUpload: $scope.image.comment
|
|
};
|
|
imageGalleryController.addImage(image, $scope.visitUuid, $scope.visitOrder), element.click(function(e) {
|
|
e.stopPropagation(), imageGalleryController.setIndex($scope.visitUuid, $scope.index), imageGalleryController.open()
|
|
}), element.on("$destroy", function() {
|
|
imageGalleryController.removeImage(image, $scope.visitUuid, $scope.index)
|
|
})
|
|
};
|
|
return {
|
|
link: link,
|
|
scope: {
|
|
image: "=",
|
|
index: "@",
|
|
visitUuid: "=",
|
|
visitOrder: "@"
|
|
},
|
|
require: "^bmGallery"
|
|
}
|
|
}).directive("bmImageObservationGalleryItem", function() {
|
|
var link = function(scope, element, attrs, imageGalleryController) {
|
|
scope.imageIndex = imageGalleryController.addImageObservation(scope.observation, "defaultTag"), element.click(function(e) {
|
|
e.stopPropagation(), imageGalleryController.setIndex("defaultTag", scope.imageIndex), imageGalleryController.open()
|
|
})
|
|
};
|
|
return {
|
|
link: link,
|
|
scope: {
|
|
observation: "="
|
|
},
|
|
require: "^bmGallery"
|
|
}
|
|
}).directive("bmObservationGalleryItem", function() {
|
|
var link = function(scope, element, attrs, imageGalleryController) {
|
|
scope.imageObservation = new Bahmni.Common.Obs.ImageObservation(scope.observation, scope.observation.concept, scope.observation.provider), scope.imageIndex = imageGalleryController.addImageObservation(scope.imageObservation, "defaultTag"), element.click(function(e) {
|
|
e.stopPropagation(), imageGalleryController.setIndex("defaultTag", scope.imageIndex), imageGalleryController.open()
|
|
})
|
|
};
|
|
return {
|
|
link: link,
|
|
scope: {
|
|
observation: "="
|
|
},
|
|
require: "^bmGallery"
|
|
}
|
|
}).directive("bmImageObservationGalleryItems", function() {
|
|
var link = function(scope, elem, attrs, imageGalleryController) {
|
|
angular.forEach(scope.list, function(record) {
|
|
imageGalleryController.addImageObservation(record, "defaultTag")
|
|
}), $(elem).click(function() {
|
|
imageGalleryController.open()
|
|
})
|
|
};
|
|
return {
|
|
link: link,
|
|
scope: {
|
|
list: "="
|
|
},
|
|
require: "^bmGallery"
|
|
}
|
|
}).directive("bmLazyImageObservationGalleryItems", function() {
|
|
var link = function(scope, elem, attrs, imageGalleryController) {
|
|
scope.promise.then(function(response) {
|
|
angular.forEach(response, function(record) {
|
|
var index = imageGalleryController.addImageObservation(record, "defaultTag");
|
|
scope.currentObservation && scope.currentObservation.imageObservation.uuid == record.imageObservation.uuid && imageGalleryController.setIndex("defaultTag", index)
|
|
}), $(elem).click(function() {
|
|
imageGalleryController.open()
|
|
})
|
|
})
|
|
};
|
|
return {
|
|
link: link,
|
|
scope: {
|
|
promise: "=",
|
|
currentObservation: "=?index"
|
|
},
|
|
require: "^bmGallery"
|
|
}
|
|
}), angular.module("bahmni.common.uiHelper").directive("ngConfirmClick", function() {
|
|
var link = function(scope, element, attr) {
|
|
var msg = attr.confirmMessage || "Are you sure?",
|
|
clickAction = attr.ngConfirmClick;
|
|
element.bind("click", function() {
|
|
window.confirm(msg) && scope.$apply(clickAction)
|
|
})
|
|
};
|
|
return {
|
|
restrict: "A",
|
|
link: link
|
|
}
|
|
}), angular.module("bahmni.common.uiHelper").directive("bmShow", ["$rootScope", function($rootScope) {
|
|
var link = function($scope, element) {
|
|
$scope.$watch("bmShow", function() {
|
|
$rootScope.isBeingPrinted || $scope.bmShow ? element.removeClass("ng-hide") : element.addClass("ng-hide")
|
|
})
|
|
};
|
|
return {
|
|
scope: {
|
|
bmShow: "="
|
|
},
|
|
link: link
|
|
}
|
|
}]), angular.module("bahmni.common.uiHelper").directive("confirmOnExit", ["$translate", function($translate) {
|
|
return {
|
|
link: function($scope) {
|
|
var cleanUpListenerPageUnload = $scope.$on("event:pageUnload", function() {
|
|
window.onbeforeunload = function() {
|
|
return $translate.instant("BROWSER_CLOSE_DIALOG_MESSAGE_KEY")
|
|
}
|
|
});
|
|
$scope.$on("$destroy", cleanUpListenerPageUnload)
|
|
}
|
|
}
|
|
}]), angular.module("bahmni.common.uiHelper").filter("days", function() {
|
|
return function(startDate, endDate) {
|
|
return Bahmni.Common.Util.DateUtil.diffInDays(startDate, endDate)
|
|
}
|
|
}).filter("bahmniDateTime", function() {
|
|
return function(date) {
|
|
return Bahmni.Common.Util.DateUtil.formatDateWithTime(date)
|
|
}
|
|
}).filter("bahmniDate", function() {
|
|
return function(date) {
|
|
return Bahmni.Common.Util.DateUtil.formatDateWithoutTime(date)
|
|
}
|
|
}).filter("bahmniTime", function() {
|
|
return function(date) {
|
|
return Bahmni.Common.Util.DateUtil.formatTime(date)
|
|
}
|
|
}).filter("bahmniDateInStrictMode", function() {
|
|
return function(date) {
|
|
return Bahmni.Common.Util.DateUtil.formatDateInStrictMode(date)
|
|
}
|
|
}), angular.module("bahmni.common.uiHelper").filter("reverse", function() {
|
|
return function(items) {
|
|
return items && items.slice().reverse()
|
|
}
|
|
}), angular.module("bahmni.common.uiHelper").filter("thumbnail", function() {
|
|
return function(url, extension) {
|
|
if (url) return extension ? Bahmni.Common.Constants.documentsPath + "/" + url.replace(/(.*)\.(.*)$/, "$1_thumbnail." + extension) || null : Bahmni.Common.Constants.documentsPath + "/" + url.replace(/(.*)\.(.*)$/, "$1_thumbnail.$2") || null
|
|
}
|
|
}), angular.module("bahmni.common.uiHelper").filter("formatDecimalValues", function() {
|
|
return function(value) {
|
|
return value ? value.toString().replace(/.0(\s+)/g, "$1") : null
|
|
}
|
|
}), angular.module("bahmni.common.uiHelper").service("backlinkService", ["$window", function($window) {
|
|
var self = this,
|
|
urls = [];
|
|
self.reset = function() {
|
|
urls = []
|
|
}, self.setUrls = function(backLinks) {
|
|
self.reset(), angular.forEach(backLinks, function(backLink) {
|
|
self.addUrl(backLink)
|
|
})
|
|
}, self.addUrl = function(backLink) {
|
|
urls.push(backLink)
|
|
}, self.addBackUrl = function(label) {
|
|
var backLabel = label || "Back";
|
|
urls.push({
|
|
label: backLabel,
|
|
action: $window.history.back
|
|
})
|
|
}, self.getUrlByLabel = function(label) {
|
|
return urls.filter(function(url) {
|
|
return url.label === label
|
|
})
|
|
}, self.getAllUrls = function() {
|
|
return urls
|
|
}
|
|
}]), angular.module("bahmni.common.uiHelper").service("contextChangeHandler", ["$rootScope", function($rootScope) {
|
|
var callbacks = [],
|
|
self = this;
|
|
$rootScope.$on("$stateChangeSuccess", function() {
|
|
self.reset()
|
|
}), this.reset = function() {
|
|
callbacks = []
|
|
}, this.add = function(callback) {
|
|
callbacks.push(callback)
|
|
}, this.execute = function() {
|
|
var allow = !0,
|
|
callBackReturn = null,
|
|
errorMessage = null;
|
|
return callbacks.forEach(function(callback) {
|
|
callBackReturn = callback(), allow = allow && callBackReturn.allow, _.isEmpty(errorMessage) && (errorMessage = callBackReturn.errorMessage)
|
|
}), callBackReturn && errorMessage ? {
|
|
allow: allow,
|
|
errorMessage: errorMessage
|
|
} : {
|
|
allow: allow
|
|
}
|
|
}
|
|
}]), angular.module("bahmni.common.uiHelper").service("stateChangeSpinner", ["$rootScope", "spinner", function($rootScope, spinner) {
|
|
var showSpinner = function(event, toState) {
|
|
toState.spinnerToken = spinner.show()
|
|
},
|
|
hideSpinner = function(event, toState) {
|
|
spinner.hide(toState.spinnerToken)
|
|
};
|
|
this.activate = function() {
|
|
$rootScope.$on("$stateChangeStart", showSpinner), $rootScope.$on("$stateChangeSuccess", hideSpinner), $rootScope.$on("$stateChangeError", hideSpinner)
|
|
}
|
|
}]), angular.module("bahmni.common.uiHelper").directive("bmBackLinks", function() {
|
|
return {
|
|
template: '<ul><li ng-repeat="backLink in backLinks"><a class="back-btn" ng-if="backLink.action" accesskey="{{backLink.accessKey}}" ng-click="closeAllDialogs();backLink.action()" id="{{backLink.id}}"> <span ng-bind-html="backLink.label"></span> </a><a class="back-btn" ng-class="{\'dashboard-link\':backLink.image}" ng-if="backLink.url" accesskey="{{backLink.accessKey}}" ng-href="{{backLink.url}}" ng-click="closeAllDialogs()" id="{{backLink.id}}" title="{{backLink.title}}"> <img ng-if="backLink.image" ng-src="{{backLink.image}}" onerror="this.onerror=null; this.src=\'../images/blank-user.gif\'"/><i ng-if="backLink.icon && !backLink.image" class="fa {{backLink.icon}}"></i></a><a class="back-btn" ng-if="backLink.state && !backLink.text" accesskey="{{backLink.accessKey}}" ui-sref="{{backLink.state}}" ng-click="closeAllDialogs()" id="{{backLink.id}}"><i ng-if="backLink.icon" class="fa {{backLink.icon}}"></i></a><a ng-if="backLink.text && backLink.requiredPrivilege" show-if-privilege="{{backLink.requiredPrivilege}}" accesskey="{{backLink.accessKey}}" ui-sref="{{backLink.state}}" id="{{backLink.id}}" class="back-btn-noIcon" ui-sref-active="active"><span>{{backLink.text | translate}}</span> </a><a ng-if="backLink.text && !backLink.requiredPrivilege" accesskey="{{backLink.accessKey}}" ui-sref="{{backLink.state}}" id="{{backLink.id}}" class="back-btn-noIcon" ui-sref-active="active"><span>{{backLink.text | translate}}</span> </a></li></ul>',
|
|
controller: function($scope, backlinkService) {
|
|
$scope.backLinks = backlinkService.getAllUrls(), $scope.$on("$stateChangeSuccess", function(event, state) {
|
|
state.data && state.data.backLinks && (backlinkService.setUrls(state.data.backLinks), $scope.backLinks = backlinkService.getAllUrls())
|
|
}), $scope.$on("$destroy", function() {
|
|
window.onbeforeunload = void 0
|
|
})
|
|
},
|
|
restrict: "E"
|
|
}
|
|
}), angular.module("bahmni.common.uiHelper").directive("providerDirective", function() {
|
|
var template = '<span><span ng-if=":: creatorName && providerName && (creatorName != providerName)">{{::creatorName}} {{"ON_BEHALF_OF_TRANSLATION_KEY"|translate}} </span>{{::providerName}} <span ng-if=":: providerDate"> {{::providerDate | bahmniTime}} </span></span>';
|
|
return {
|
|
restrict: "EA",
|
|
replace: !0,
|
|
scope: {
|
|
creatorName: "@",
|
|
providerName: "@",
|
|
providerDate: "=?"
|
|
},
|
|
template: template
|
|
}
|
|
}), angular.module("bahmni.common.uiHelper").directive("focusOn", ["$timeout", function($timeout) {
|
|
return function(scope, elem, attrs) {
|
|
Modernizr.ios || scope.$watch(attrs.focusOn, function(value) {
|
|
value && $timeout(function() {
|
|
$(elem).focus()
|
|
})
|
|
})
|
|
}
|
|
}]), angular.module("bahmni.common.uiHelper").directive("scrollToObsElement", function() {
|
|
return function(scope, elem, attrs) {
|
|
if (attrs.scrollToObsElement && scope.observation.scrollToElement) {
|
|
$(elem).focus();
|
|
var scrollPosition = $(elem).offset().top - window.innerHeight / 2;
|
|
if ($("#scrollOnEdit")[0]) {
|
|
var container = $("#scrollOnEdit"),
|
|
scrollTo = elem;
|
|
scrollPosition = scrollTo.offset().top + container.scrollTop() - (container.offset().top + container.offset().top / 2), container.animate({
|
|
scrollTop: scrollPosition
|
|
}, 900)
|
|
} else $(window).animate({
|
|
scrollTop: scrollPosition
|
|
}, 900);
|
|
scope.observation.scrollToElement = !1
|
|
}
|
|
}
|
|
}), angular.module("bahmni.common.uiHelper").directive("dateConverter", [function() {
|
|
return {
|
|
require: "ngModel",
|
|
link: function(scope, element, attrs, ngModelController) {
|
|
var DateUtil = Bahmni.Common.Util.DateUtil;
|
|
ngModelController.$parsers.push(function(date) {
|
|
return DateUtil.parse(date)
|
|
}), ngModelController.$formatters.push(function(date) {
|
|
return DateUtil.parse(DateUtil.getDateWithoutTime(date))
|
|
})
|
|
}
|
|
}
|
|
}]), angular.module("bahmni.common.uiHelper").directive("compileHtml", ["$compile", function($compile) {
|
|
return function(scope, element, attrs) {
|
|
scope.$watch(function(scope) {
|
|
return scope.$eval(attrs.compileHtml)
|
|
}, function(value) {
|
|
element.html(value), $compile(element.contents())(scope)
|
|
})
|
|
}
|
|
}]), angular.module("bahmni.common.uiHelper").controller("MessageController", ["$scope", "messagingService", function($scope, messagingService) {
|
|
$scope.messages = messagingService.messages, $scope.getMessageText = function(level) {
|
|
var string = "";
|
|
return $scope.messages[level].forEach(function(message) {
|
|
string = string.concat(message.value)
|
|
}), string
|
|
}, $scope.hideMessage = function(level) {
|
|
messagingService.hideMessages(level)
|
|
}, $scope.isErrorMessagePresent = function() {
|
|
return $scope.messages.error.length > 0
|
|
}, $scope.isInfoMessagePresent = function() {
|
|
return $scope.messages.info.length > 0
|
|
}
|
|
}]), angular.module("bahmni.common.uiHelper").service("messagingService", ["$rootScope", "$timeout", function($rootScope, $timeout) {
|
|
this.messages = {
|
|
error: [],
|
|
info: []
|
|
};
|
|
var self = this;
|
|
$rootScope.$on("event:serverError", function(event, errorMessage) {
|
|
self.showMessage("error", errorMessage, "serverError")
|
|
}), this.showMessage = function(level, message, errorEvent) {
|
|
var messageObject = {
|
|
value: "",
|
|
isServerError: !1
|
|
};
|
|
messageObject.value = message, errorEvent ? messageObject.isServerError = !0 : "info" == level && this.createTimeout("info", 4e3);
|
|
var index = _.findIndex(this.messages[level], function(msg) {
|
|
return msg.value == messageObject.value
|
|
});
|
|
index >= 0 && this.messages[level].splice(index, 1), this.messages[level].push(messageObject)
|
|
}, this.createTimeout = function(level, time) {
|
|
$timeout(function() {
|
|
self.messages[level] = []
|
|
}, time, !0)
|
|
}, this.hideMessages = function(level) {
|
|
self.messages[level].length = 0
|
|
}, this.clearAll = function() {
|
|
self.messages.error = [], self.messages.info = []
|
|
}
|
|
}]), angular.module("bahmni.common.uiHelper").service("confirmBox", ["$rootScope", "ngDialog", function($rootScope, ngDialog) {
|
|
var dialog, confirmBox = function(config) {
|
|
var confirmBoxScope = $rootScope.$new();
|
|
confirmBoxScope.close = function() {
|
|
ngDialog.close(dialog.id), confirmBoxScope.$destroy()
|
|
}, confirmBoxScope.scope = config.scope, confirmBoxScope.actions = config.actions, dialog = ngDialog.open({
|
|
template: "../common/ui-helper/views/confirmBox.html",
|
|
scope: confirmBoxScope,
|
|
className: config.className || "ngdialog-theme-default"
|
|
})
|
|
};
|
|
return confirmBox
|
|
}]), angular.module("bahmni.common.uiHelper").directive("focusOnInputErrors", ["$timeout", function($timeout) {
|
|
return function(scope) {
|
|
var cleanUpListenerErrorsOnForm = scope.$on("event:errorsOnForm", function() {
|
|
$timeout(function() {
|
|
$(".illegalValue:first button").focus(), $(".illegalValue:first").focus()
|
|
}, 10, !1)
|
|
});
|
|
scope.$on("$destroy", cleanUpListenerErrorsOnForm)
|
|
}
|
|
}]), angular.module("bahmni.common.uiHelper").directive("fixedFirstColumn", ["$interval", function($interval) {
|
|
return {
|
|
restrict: "A",
|
|
template: "<div class='table-responsive'><div ng-transclude class='table-responsive-fixedColumn' ></div></div>",
|
|
transclude: !0,
|
|
link: function($scope, $element) {
|
|
var checkIfTableLoaded = $interval(function() {
|
|
if ($element.find("table").length > 0) {
|
|
var tr = $element.find("tr");
|
|
angular.forEach(tr, function(i) {
|
|
var columns = angular.element(i).children();
|
|
if (!(columns.length < 1)) {
|
|
var column0 = columns[0],
|
|
column1 = columns[1],
|
|
height0 = column0.offsetHeight,
|
|
height1 = column1 ? column1.offsetHeight : 0,
|
|
height = Math.max(height0, height1);
|
|
columns[0].style.height = height + "px", i.style.height = height + "px", column1 && (column1.style.height = height + "px"), 0 !== height0 && height0 === height1 && clearInterval(checkIfTableLoaded)
|
|
}
|
|
}), clearInterval(checkIfTableLoaded)
|
|
}
|
|
}, 100, 1)
|
|
}
|
|
}
|
|
}]), angular.module("bahmni.common.uiHelper").directive("assignHeight", function() {
|
|
return {
|
|
restrict: "A",
|
|
link: function(scope, element, attrs) {
|
|
var height;
|
|
scope.$watch(function() {
|
|
height = element[0].offsetHeight, attrs.key && (scope[attrs.key] = {
|
|
height: height
|
|
})
|
|
})
|
|
}
|
|
}
|
|
}), angular.module("bahmni.common.attributeTypes", []).directive("attributeTypes", [function() {
|
|
return {
|
|
scope: {
|
|
targetModel: "=",
|
|
attribute: "=",
|
|
fieldValidation: "=",
|
|
isAutoComplete: "&",
|
|
getAutoCompleteList: "&",
|
|
getDataResults: "&",
|
|
handleUpdate: "&",
|
|
isReadOnly: "&",
|
|
isForm: "=?"
|
|
},
|
|
templateUrl: "../common/attributeTypes/views/attributeInformation.html",
|
|
restrict: "E",
|
|
controller: function($scope) {
|
|
$scope.getAutoCompleteList = $scope.getAutoCompleteList(), $scope.getDataResults = $scope.getDataResults(), $scope.isAutoComplete = $scope.isAutoComplete() || function() {
|
|
return !1
|
|
}, $scope.isReadOnly = $scope.isReadOnly() || function() {
|
|
return !1
|
|
}, $scope.handleUpdate = $scope.handleUpdate() || function() {
|
|
return !1
|
|
}, $scope.appendConceptNameToModel = function(attribute) {
|
|
var attributeValueConceptType = $scope.targetModel[attribute.name],
|
|
concept = _.find(attribute.answers, function(answer) {
|
|
return answer.conceptId === attributeValueConceptType.conceptUuid
|
|
});
|
|
attributeValueConceptType.value = concept && concept.fullySpecifiedName
|
|
}
|
|
}
|
|
}
|
|
}]), Bahmni.Common.Domain.AttributeTypeMapper = function() {
|
|
function AttributeTypeMapper() {}
|
|
return AttributeTypeMapper.prototype.mapFromOpenmrsAttributeTypes = function(mrsAttributeTypes, mandatoryAttributes, attributesConfig) {
|
|
var attributeTypes = [];
|
|
return angular.forEach(mrsAttributeTypes, function(mrsAttributeType) {
|
|
var isRequired = function() {
|
|
var element = _.find(mandatoryAttributes, function(mandatoryAttribute) {
|
|
return mandatoryAttribute == mrsAttributeType.name
|
|
});
|
|
return !!element
|
|
},
|
|
attributeType = {
|
|
uuid: mrsAttributeType.uuid,
|
|
sortWeight: mrsAttributeType.sortWeight,
|
|
name: mrsAttributeType.name,
|
|
fullySpecifiedName: mrsAttributeType.name,
|
|
description: mrsAttributeType.description || mrsAttributeType.name,
|
|
format: mrsAttributeType.format || mrsAttributeType.datatypeClassname,
|
|
answers: [],
|
|
required: isRequired(),
|
|
concept: mrsAttributeType.concept || {},
|
|
excludeFrom: attributesConfig && attributesConfig[mrsAttributeType.name] && attributesConfig[mrsAttributeType.name].excludeFrom || []
|
|
};
|
|
attributeType.concept.dataType = attributeType.concept.datatype && attributeType.concept.datatype.name, mrsAttributeType.concept && mrsAttributeType.concept.answers && angular.forEach(mrsAttributeType.concept.answers, function(mrsAnswer) {
|
|
var displayName = mrsAnswer.display,
|
|
fullySpecifiedName = mrsAnswer.display;
|
|
mrsAnswer.names && 2 == mrsAnswer.names.length && "FULLY_SPECIFIED" == mrsAnswer.name.conceptNameType && (mrsAnswer.names[0].display == displayName ? (displayName = mrsAnswer.names[1].display, fullySpecifiedName = mrsAnswer.names[0].display) : (displayName = mrsAnswer.names[0].display, fullySpecifiedName = mrsAnswer.names[1].display)), attributeType.answers.push({
|
|
fullySpecifiedName: fullySpecifiedName,
|
|
description: displayName,
|
|
conceptId: mrsAnswer.uuid
|
|
})
|
|
}), "org.openmrs.customdatatype.datatype.RegexValidatedTextDatatype" == attributeType.format && (attributeType.pattern = mrsAttributeType.datatypeConfig), attributeTypes.push(attributeType)
|
|
}), {
|
|
attributeTypes: attributeTypes
|
|
}
|
|
}, AttributeTypeMapper
|
|
}(), Bahmni.Common.Domain.AttributeFormatter = function() {
|
|
function AttributeFormatter() {}
|
|
AttributeFormatter.prototype.getMrsAttributes = function(model, attributeTypes) {
|
|
return attributeTypes.map(function(result) {
|
|
var attribute = {
|
|
attributeType: {
|
|
uuid: result.uuid
|
|
}
|
|
};
|
|
return _.isEmpty(model) || setAttributeValue(result, attribute, model[result.name]), attribute
|
|
})
|
|
}, AttributeFormatter.prototype.getMrsAttributesForUpdate = function(model, attributeTypes, attributes) {
|
|
return _.filter(AttributeFormatter.prototype.getMrsAttributes(model, attributeTypes), function(mrsAttribute) {
|
|
var attribute = _.find(attributes, function(attribute) {
|
|
return mrsAttribute.attributeType.uuid === attribute.attributeType.uuid
|
|
});
|
|
return attribute && !attribute.voided && (mrsAttribute.uuid = attribute.uuid), isAttributeChanged(mrsAttribute)
|
|
})
|
|
}, AttributeFormatter.prototype.removeUnfilledAttributes = function(formattedAttributes) {
|
|
return _.filter(formattedAttributes, isAttributeChanged)
|
|
};
|
|
var isAttributeChanged = function(attribute) {
|
|
return attribute.value || attribute.uuid
|
|
},
|
|
setAttributeValue = function(attributeType, attr, value) {
|
|
if ("" === value || null === value || void 0 === value || null === value.conceptUuid) attr.voided = !0;
|
|
else if ("org.openmrs.Concept" === attributeType.format) {
|
|
var attrDescription = _.find(attributeType.answers, function(answer) {
|
|
if (answer.conceptId === value.conceptUuid) return !0
|
|
});
|
|
attr.value = void 0 != attrDescription ? attrDescription.description : null, attr.hydratedObject = value.conceptUuid
|
|
} else if ("org.openmrs.util.AttributableDate" == attributeType.format || "org.openmrs.customdatatype.datatype.DateDatatype" == attributeType.format) {
|
|
var mnt = moment(value);
|
|
attr.value = mnt.format("YYYY-MM-DD")
|
|
} else attr.value = value.toString()
|
|
};
|
|
return AttributeFormatter
|
|
}();
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.ConceptSet = Bahmni.ConceptSet || {}, Bahmni.ConceptSet.FormConditions = Bahmni.ConceptSet.FormConditions || {}, angular.module("bahmni.common.conceptSet", ["bahmni.common.uiHelper", "ui.select2", "pasvaz.bindonce", "ngSanitize", "ngTagsInput"]), angular.module("bahmni.common.conceptSet").controller("ConceptSetGroupController", ["$scope", "contextChangeHandler", "spinner", "messagingService", "conceptSetService", "$rootScope", "sessionService", "encounterService", "treatmentConfig", "retrospectiveEntryService", "userService", "conceptSetUiConfigService", "$timeout", "clinicalAppConfigService", "$stateParams", "$translate", function($scope, contextChangeHandler, spinner, messagingService, conceptSetService, $rootScope, sessionService, encounterService, treatmentConfig, retrospectiveEntryService, userService, conceptSetUiConfigService, $timeout, clinicalAppConfigService, $stateParams, $translate) {
|
|
var conceptSetUIConfig = conceptSetUiConfigService.getConfig(),
|
|
init = function() {
|
|
$scope.validationHandler = new Bahmni.ConceptSet.ConceptSetGroupPanelViewValidationHandler($scope.allTemplates), contextChangeHandler.add($scope.validationHandler.validate)
|
|
};
|
|
$scope.toggleSideBar = function() {
|
|
$rootScope.showLeftpanelToggle = !$rootScope.showLeftpanelToggle
|
|
}, $scope.showLeftpanelToggle = function() {
|
|
return $rootScope.showLeftpanelToggle
|
|
}, $scope.togglePref = function(conceptSet, conceptName) {
|
|
$rootScope.currentUser.toggleFavoriteObsTemplate(conceptName), spinner.forPromise(userService.savePreferences())
|
|
}, $scope.getNormalized = function(conceptName) {
|
|
return conceptName.replace(/['\.\s\(\)\/,\\]+/g, "_")
|
|
}, $scope.showPreviousButton = function(conceptSetName) {
|
|
return conceptSetUIConfig[conceptSetName] && conceptSetUIConfig[conceptSetName].showPreviousButton
|
|
}, $scope.showPrevious = function(conceptSetName, event) {
|
|
event.stopPropagation(), $timeout(function() {
|
|
$scope.$broadcast("event:showPrevious" + conceptSetName)
|
|
})
|
|
}, $scope.isInEditEncounterMode = function() {
|
|
return void 0 !== $stateParams.encounterUuid && "active" !== $stateParams.encounterUuid
|
|
}, $scope.computeField = function(conceptSet, event) {
|
|
event.stopPropagation(), $scope.consultation.preSaveHandler.fire();
|
|
var defaultRetrospectiveVisitType = clinicalAppConfigService.getVisitTypeForRetrospectiveEntries(),
|
|
encounterData = (new Bahmni.Clinical.EncounterTransactionMapper).map(angular.copy($scope.consultation), $scope.patient, sessionService.getLoginLocationUuid(), retrospectiveEntryService.getRetrospectiveEntry(), defaultRetrospectiveVisitType, $scope.isInEditEncounterMode());
|
|
encounterData = encounterService.buildEncounter(encounterData), encounterData.drugOrders = [];
|
|
var conceptSetData = {
|
|
name: conceptSet.conceptName,
|
|
uuid: conceptSet.uuid
|
|
},
|
|
data = {
|
|
encounterModifierObservations: encounterData.observations,
|
|
drugOrders: encounterData.drugOrders,
|
|
conceptSetData: conceptSetData,
|
|
patientUuid: encounterData.patientUuid,
|
|
encounterDateTime: encounterData.encounterDateTime
|
|
};
|
|
spinner.forPromise(treatmentConfig().then(function(treatmentConfig) {
|
|
return $scope.treatmentConfiguration = treatmentConfig, conceptSetService.getComputedValue(data)
|
|
}).then(function(response) {
|
|
response = response.data, copyValues($scope.consultation.observations, response.encounterModifierObservations), $scope.consultation.newlyAddedTreatments = $scope.consultation.newlyAddedTreatments || [], response.drugOrders.forEach(function(drugOrder) {
|
|
$scope.consultation.newlyAddedTreatments.push(Bahmni.Clinical.DrugOrderViewModel.createFromContract(drugOrder, $scope.treatmentConfiguration))
|
|
})
|
|
}))
|
|
}, $scope.canRemove = function(index) {
|
|
var observations = $scope.allTemplates[index].observations;
|
|
return !(void 0 !== observations && !_.isEmpty(observations)) || void 0 === observations[0].uuid
|
|
}, $scope.clone = function(index) {
|
|
var clonedObj = $scope.allTemplates[index].clone();
|
|
$scope.allTemplates.splice(index + 1, 0, clonedObj), $.scrollTo("#concept-set-" + (index + 1), 200, {
|
|
offset: {
|
|
top: -400
|
|
}
|
|
})
|
|
}, $scope.clonePanelConceptSet = function(conceptSet) {
|
|
var index = _.findIndex($scope.allTemplates, conceptSet);
|
|
messagingService.showMessage("info", $translate.instant("CLINICAL_TEMPLATE_ADDED_SUCCESS_KEY", {
|
|
label: $scope.allTemplates[index].label
|
|
})), $scope.clone(index), $scope.showLeftPanelConceptSet($scope.allTemplates[index + 1])
|
|
}, $scope.isClonedSection = function(conceptSetTemplate, allTemplates) {
|
|
if (allTemplates) {
|
|
var index = allTemplates.indexOf(conceptSetTemplate);
|
|
return index > 0 && allTemplates[index].label == allTemplates[index - 1].label
|
|
}
|
|
return !1
|
|
}, $scope.isLastClonedSection = function(conceptSetTemplate) {
|
|
var index = _.findIndex($scope.allTemplates, conceptSetTemplate);
|
|
return !(!$scope.allTemplates || index != $scope.allTemplates.length - 1 && $scope.allTemplates[index].label == $scope.allTemplates[index + 1].label)
|
|
}, $scope.remove = function(index) {
|
|
var label = $scope.allTemplates[index].label,
|
|
currentTemplate = $scope.allTemplates[index],
|
|
anotherTemplate = _.find($scope.allTemplates, function(template) {
|
|
return template.label == currentTemplate.label && template !== currentTemplate
|
|
});
|
|
if (anotherTemplate) $scope.allTemplates.splice(index, 1);
|
|
else {
|
|
var clonedObj = $scope.allTemplates[index].clone();
|
|
$scope.allTemplates[index] = clonedObj, $scope.allTemplates[index].isAdded = !1, $scope.allTemplates[index].isOpen = !1, $scope.allTemplates[index].klass = "", $scope.allTemplates[index].isLoaded = !1
|
|
}
|
|
$scope.leftPanelConceptSet = "", messagingService.showMessage("info", $translate.instant("CLINICAL_TEMPLATE_REMOVED_SUCCESS_KEY", {
|
|
label: label
|
|
}))
|
|
}, $scope.openActiveForm = function(conceptSet) {
|
|
return conceptSet && "active" == conceptSet.klass && conceptSet != $scope.leftPanelConceptSet && $scope.showLeftPanelConceptSet(conceptSet), conceptSet.klass
|
|
};
|
|
var copyValues = function(existingObservations, modifiedObservations) {
|
|
existingObservations.forEach(function(observation, index) {
|
|
observation.groupMembers && observation.groupMembers.length > 0 ? copyValues(observation.groupMembers, modifiedObservations[index].groupMembers) : observation.value = modifiedObservations[index].value
|
|
})
|
|
},
|
|
collapseExistingActiveSection = function(section) {
|
|
section && (section.klass = "", section.isOpen = !1, section.isLoaded = !1)
|
|
};
|
|
$scope.showLeftPanelConceptSet = function(selectedConceptSet) {
|
|
collapseExistingActiveSection($scope.leftPanelConceptSet), $scope.leftPanelConceptSet = selectedConceptSet, $scope.leftPanelConceptSet.isOpen = !0, $scope.leftPanelConceptSet.isLoaded = !0, $scope.leftPanelConceptSet.klass = "active", $scope.leftPanelConceptSet.atLeastOneValueIsSet = selectedConceptSet.hasSomeValue(), $scope.leftPanelConceptSet.isAdded = !0, $scope.consultation.lastvisited = selectedConceptSet.id || selectedConceptSet.formUuid, $(window).scrollTop(0)
|
|
}, $scope.focusOnErrors = function() {
|
|
var errorMessage = $scope.leftPanelConceptSet.errorMessage ? $scope.leftPanelConceptSet.errorMessage : "{{'CLINICAL_FORM_ERRORS_MESSAGE_KEY' | translate }}";
|
|
messagingService.showMessage("error", errorMessage), $scope.$parent.$parent.$broadcast("event:errorsOnForm")
|
|
}, $scope.isFormTemplate = function(data) {
|
|
return data.formUuid
|
|
}, init()
|
|
}]).directive("conceptSetGroup", function() {
|
|
return {
|
|
restrict: "EA",
|
|
scope: {
|
|
conceptSetGroupExtensionId: "=?",
|
|
observations: "=",
|
|
allTemplates: "=",
|
|
context: "=",
|
|
autoScrollEnabled: "=",
|
|
patient: "=",
|
|
consultation: "="
|
|
},
|
|
controller: "ConceptSetGroupController",
|
|
templateUrl: "../common/concept-set/views/conceptSetGroup.html"
|
|
}
|
|
}), angular.module("bahmni.common.conceptSet").controller("multiSelectObservationSearchController", ["$scope", "conceptSetService", function($scope, conceptSetService) {
|
|
var possibleAnswers = [],
|
|
unselectedValues = [];
|
|
$scope.values = [];
|
|
var init = function() {
|
|
var selectedValues = _.map(_.values($scope.observation.selectedObs), "value");
|
|
_.remove(selectedValues, _.isUndefined), selectedValues.forEach(function(observation) {
|
|
$scope.values.push({
|
|
label: observation.name,
|
|
name: observation.name
|
|
})
|
|
});
|
|
var configuredConceptSetName = $scope.observation.getConceptUIConfig().answersConceptName;
|
|
_.isUndefined(configuredConceptSetName) ? (possibleAnswers = $scope.observation.getPossibleAnswers(), unselectedValues = _.xorBy(possibleAnswers, selectedValues, "uuid")) : conceptSetService.getConcept({
|
|
name: configuredConceptSetName,
|
|
v: "bahmni"
|
|
}).then(function(response) {
|
|
possibleAnswers = _.isEmpty(response.data.results) ? [] : response.data.results[0].answers, unselectedValues = _.xorBy(possibleAnswers, $scope.values, "uuid")
|
|
})
|
|
};
|
|
$scope.search = function(query) {
|
|
var matchingAnswers = [];
|
|
return _.forEach(unselectedValues, function(answer) {
|
|
if ("object" != typeof answer.name && answer.name.toLowerCase().indexOf(query.toLowerCase()) !== -1) answer.label = answer.name, matchingAnswers.push(answer);
|
|
else if ("object" == typeof answer.name && answer.name.name.toLowerCase().indexOf(query.toLowerCase()) !== -1) answer.name = answer.name.name, answer.label = answer.name, matchingAnswers.push(answer);
|
|
else {
|
|
var synonyms = _.map(answer.names, "name");
|
|
_.find(synonyms, function(name) {
|
|
name.toLowerCase().indexOf(query.toLowerCase()) !== -1 && (answer.label = name + " => " + answer.name, matchingAnswers.push(answer))
|
|
})
|
|
}
|
|
}), _.uniqBy(matchingAnswers, "uuid")
|
|
}, $scope.addItem = function(item) {
|
|
unselectedValues = _.remove(unselectedValues, function(value) {
|
|
return value.uuid !== item.uuid
|
|
}), $scope.observation.toggleSelection(item)
|
|
}, $scope.removeItem = function(item) {
|
|
unselectedValues.push(item), $scope.observation.toggleSelection(item)
|
|
}, $scope.setLabel = function(answer) {
|
|
return answer.label = answer.name, !0
|
|
}, $scope.removeFreeTextItem = function() {
|
|
var value = $("input.input").val();
|
|
_.isEmpty($scope.search(value)) && $("input.input").val("")
|
|
}, init()
|
|
}]).config(["tagsInputConfigProvider", function(tagsInputConfigProvider) {
|
|
tagsInputConfigProvider.setDefaults("tagsInput", {
|
|
placeholder: ""
|
|
})
|
|
}]), angular.module("bahmni.common.conceptSet").directive("conceptSet", ["contextChangeHandler", "appService", "observationsService", "messagingService", "conceptSetService", "conceptSetUiConfigService", "spinner", function(contextChangeHandler, appService, observationsService, messagingService, conceptSetService, conceptSetUiConfigService, spinner) {
|
|
var controller = function($scope) {
|
|
var conceptSetName = $scope.conceptSetName,
|
|
ObservationUtil = Bahmni.Common.Obs.ObservationUtil,
|
|
conceptSetUIConfig = conceptSetUiConfigService.getConfig(),
|
|
observationMapper = new Bahmni.ConceptSet.ObservationMapper,
|
|
validationHandler = $scope.validationHandler() || contextChangeHandler,
|
|
id = "#" + $scope.sectionId;
|
|
$scope.atLeastOneValueIsSet = $scope.atLeastOneValueIsSet || !1, $scope.conceptSetRequired = !1, $scope.showTitleValue = $scope.showTitle(), $scope.numberOfVisits = conceptSetUIConfig[conceptSetName] && conceptSetUIConfig[conceptSetName].numberOfVisits ? conceptSetUIConfig[conceptSetName].numberOfVisits : null, $scope.hideAbnormalButton = conceptSetUIConfig[conceptSetName] && conceptSetUIConfig[conceptSetName].hideAbnormalButton;
|
|
var focusFirstObs = function() {
|
|
if ($scope.conceptSetFocused && $scope.rootObservation.groupMembers && $scope.rootObservation.groupMembers.length > 0) {
|
|
var firstObs = _.find($scope.rootObservation.groupMembers, function(obs) {
|
|
return obs.isFormElement && obs.isFormElement()
|
|
});
|
|
firstObs && (firstObs.isFocused = !0)
|
|
}
|
|
},
|
|
updateObservationsOnRootScope = function() {
|
|
if ($scope.rootObservation) {
|
|
for (var i = 0; i < $scope.observations.length; i++)
|
|
if ($scope.observations[i].concept.uuid === $scope.rootObservation.concept.uuid) return void($scope.observations[i] = $scope.rootObservation);
|
|
$scope.observations.push($scope.rootObservation)
|
|
}
|
|
},
|
|
getObservationsOfCurrentTemplate = function() {
|
|
return _.filter($scope.observations, function(observation) {
|
|
return _.toLower(observation.conceptSetName) === _.toLower($scope.rootObservation.concept.name)
|
|
})
|
|
},
|
|
getDefaults = function() {
|
|
var conceptSetUI = appService.getAppDescriptor().getConfigValue("conceptSetUI");
|
|
if (conceptSetUI && conceptSetUI.defaults) return conceptSetUI.defaults || {}
|
|
},
|
|
getCodedAnswerWithDefaultAnswerString = function(defaults, groupMember) {
|
|
var defaultCodedAnswer, possibleAnswers = groupMember.possibleAnswers,
|
|
defaultAnswer = defaults[groupMember.concept.name];
|
|
return defaultAnswer instanceof Array ? (defaultCodedAnswer = [], _.each(defaultAnswer, function(answer) {
|
|
defaultCodedAnswer.push(_.find(possibleAnswers, {
|
|
displayString: answer
|
|
}))
|
|
})) : defaultCodedAnswer = _.find(possibleAnswers, {
|
|
displayString: defaultAnswer
|
|
}), defaultCodedAnswer
|
|
},
|
|
setDefaultsForGroupMembers = function(groupMembers, defaults) {
|
|
defaults && _.each(groupMembers, function(groupMember) {
|
|
var conceptFullName = groupMember.concept.name,
|
|
present = _.includes(_.keys(defaults), conceptFullName);
|
|
present && void 0 == groupMember.value && ("Coded" == groupMember.concept.dataType ? setDefaultsForCodedObservations(groupMember, defaults) : groupMember.value = defaults[conceptFullName]), groupMember.groupMembers && groupMember.groupMembers.length > 0 && (setDefaultsForGroupMembers(groupMember.groupMembers, defaults), groupMember instanceof Bahmni.ConceptSet.ObservationNode && defaults[groupMember.label] && groupMember.abnormalObs && void 0 == groupMember.abnormalObs.value && groupMember.onValueChanged(groupMember.value))
|
|
})
|
|
},
|
|
setDefaultsForCodedObservations = function(observation, defaults) {
|
|
var defaultCodedAnswer = getCodedAnswerWithDefaultAnswerString(defaults, observation);
|
|
observation.isMultiSelect ? observation.hasValue() || _.each(defaultCodedAnswer, function(answer) {
|
|
observation.selectAnswer(answer)
|
|
}) : defaultCodedAnswer instanceof Array || (observation.value = defaultCodedAnswer)
|
|
},
|
|
getFlattenedObsValues = function(flattenedObs) {
|
|
return _.reduce(flattenedObs, function(flattenedObsValues, obs) {
|
|
if (void 0 == flattenedObsValues[obs.concept.name + "|" + obs.uniqueId])
|
|
if (obs.isMultiSelect) {
|
|
var selectedObsConceptNames = [];
|
|
_.each(obs.selectedObs, function(observation) {
|
|
observation.voided || selectedObsConceptNames.push(observation.value.name), observation.voided || selectedObsConceptNames.push(observation.value.name)
|
|
}), flattenedObsValues[obs.concept.name + "|" + obs.uniqueId] = selectedObsConceptNames
|
|
} else if (obs.conceptUIConfig.multiSelect) {
|
|
var alreadyProcessedMultiSelect = [];
|
|
_.each(_.keys(flattenedObsValues), function(eachObsKey) {
|
|
eachObsKey.split("|")[0] == obs.concept.name && alreadyProcessedMultiSelect.push(eachObsKey)
|
|
}), alreadyProcessedMultiSelect.length < 2 && (flattenedObsValues[obs.concept.name + "|" + obs.uniqueId] = flattenedObsValues[obs.concept.name + "|undefined"])
|
|
} else obs.value instanceof Object ? flattenedObsValues[obs.concept.name + "|" + obs.uniqueId] = obs.value.name instanceof Object ? obs.value.name.name : obs.value.name : flattenedObsValues[obs.concept.name + "|" + obs.uniqueId] = obs.value;
|
|
return flattenedObsValues
|
|
}, {})
|
|
},
|
|
clearFieldValuesOnDisabling = function(obs) {
|
|
if (obs.comment = void 0, obs.value || obs.isBoolean) obs.value = void 0;
|
|
else if (obs.isMultiSelect)
|
|
for (var key in obs.selectedObs) obs.selectedObs[key].voided || obs.toggleSelection(obs.selectedObs[key].value)
|
|
},
|
|
setObservationState = function(obsArray, disable, error, hide) {
|
|
_.isEmpty(obsArray) || _.each(obsArray, function(obs) {
|
|
obs.disabled = disable || hide, obs.error = error, obs.hide = hide, (hide || obs.disabled) && clearFieldValuesOnDisabling(obs), obs.groupMembers && _.each(obs.groupMembers, function(groupMember) {
|
|
groupMember && setObservationState([groupMember], disable, error, hide)
|
|
})
|
|
})
|
|
},
|
|
processConditions = function(flattenedObs, fields, disable, error, hide) {
|
|
_.each(fields, function(field) {
|
|
var clonedObsInSameGroup, matchingObsArray = [];
|
|
flattenedObs.forEach(function(obs) {
|
|
0 != clonedObsInSameGroup && obs.concept.name == field ? (matchingObsArray.push(obs), clonedObsInSameGroup = !0) : clonedObsInSameGroup && obs.concept.name != field && (clonedObsInSameGroup = !1)
|
|
}), _.isEmpty(matchingObsArray) ? messagingService.showMessage("error", "No element found with name : " + field) : setObservationState(matchingObsArray, disable, error, hide)
|
|
})
|
|
},
|
|
runFormConditionForObs = function(enableCase, formName, formCondition, conceptName, flattenedObs) {
|
|
var conceptSetObsValues = getFlattenedObsValues(flattenedObs);
|
|
_.each(_.keys(conceptSetObsValues), function(eachObsKey) {
|
|
if (eachObsKey.split("|")[0] == conceptName && "undefined" != eachObsKey.split("|")[1]) {
|
|
var valueMap = _.reduce(conceptSetObsValues, function(conceptSetValueMap, obsValue, conceptName) {
|
|
return conceptSetValueMap[conceptName.split("|")[0]] = obsValue, conceptSetValueMap
|
|
}, {}),
|
|
conditions = formCondition(formName, valueMap, $scope.patient);
|
|
_.isUndefined(conditions) || (conditions.error && !_.isEmpty(conditions.error) ? (messagingService.showMessage("error", conditions.error), processConditions(flattenedObs, [conceptName], !1, !0, !1)) : enableCase && processConditions(flattenedObs, [conceptName], !1, !1, !1), processConditions(flattenedObs, conditions.disable, !0), processConditions(flattenedObs, conditions.enable, !1), processConditions(flattenedObs, conditions.show, !1, void 0, !1), processConditions(flattenedObs, conditions.hide, !1, void 0, !0), _.each(conditions.enable, function(subConditionConceptName) {
|
|
var conditionFn = Bahmni.ConceptSet.FormConditions.rules && Bahmni.ConceptSet.FormConditions.rules[subConditionConceptName];
|
|
null != conditionFn && runFormConditionForObs(!0, formName, conditionFn, subConditionConceptName, flattenedObs)
|
|
}), _.each(conditions.disable, function(subConditionConceptName) {
|
|
var conditionFn = Bahmni.ConceptSet.FormConditions.rules && Bahmni.ConceptSet.FormConditions.rules[subConditionConceptName];
|
|
null != conditionFn && _.each(flattenedObs, function(obs) {
|
|
obs.concept.name == subConditionConceptName && runFormConditionForObs(!1, formName, conditionFn, subConditionConceptName, flattenedObs)
|
|
})
|
|
}), _.each(conditions.show, function(subConditionConceptName) {
|
|
var conditionFn = Bahmni.ConceptSet.FormConditions.rules && Bahmni.ConceptSet.FormConditions.rules[subConditionConceptName];
|
|
conditionFn && runFormConditionForObs(!0, formName, conditionFn, subConditionConceptName, flattenedObs)
|
|
}), _.each(conditions.hide, function(subConditionConceptName) {
|
|
var conditionFn = Bahmni.ConceptSet.FormConditions.rules && Bahmni.ConceptSet.FormConditions.rules[subConditionConceptName];
|
|
conditionFn && _.each(flattenedObs, function(obs) {
|
|
obs.concept.name == subConditionConceptName && runFormConditionForObs(!1, formName, conditionFn, subConditionConceptName, flattenedObs)
|
|
})
|
|
}))
|
|
}
|
|
})
|
|
},
|
|
updateFormConditions = function(observationsOfCurrentTemplate, rootObservation) {
|
|
Bahmni.ConceptSet.FormConditions.rules && runFormConditionForAllObsRecursively(rootObservation.concept.name, rootObservation)
|
|
},
|
|
runFormConditionForAllObsRecursively = function(formName, rootObservation) {
|
|
_.each(rootObservation.groupMembers, function(observation) {
|
|
var conditionFn = Bahmni.ConceptSet.FormConditions.rules && Bahmni.ConceptSet.FormConditions.rules[observation.concept.name];
|
|
if (null != conditionFn) {
|
|
var flattenedObs = ObservationUtil.flattenObsToArray([rootObservation]);
|
|
runFormConditionForObs(!1, formName, conditionFn, observation.concept.name, flattenedObs)
|
|
}
|
|
observation.groupMembers && observation.groupMembers.length > 0 && runFormConditionForAllObsRecursively(formName, observation)
|
|
})
|
|
},
|
|
addDummyImage = function() {
|
|
_.each($scope.rootObservation.groupMembers, function(observation) {
|
|
addDummyImageObservationForSavedObs(observation, $scope.rootObservation)
|
|
})
|
|
},
|
|
addDummyImageObservationForSavedObs = function(observation, rootObservation) {
|
|
if (_.each(observation.groupMembers, function(childObservation) {
|
|
addDummyImageObservationForSavedObs(childObservation, observation)
|
|
}), "image" === observation.getControlType() && observation.value && rootObservation.groupMembers.indexOf(observation) === rootObservation.groupMembers.length - 1) return void rootObservation.groupMembers.push(observation.cloneNew())
|
|
},
|
|
init = function() {
|
|
return conceptSetService.getConcept({
|
|
name: conceptSetName,
|
|
v: "bahmni"
|
|
}).then(function(response) {
|
|
if ($scope.conceptSet = response.data.results[0], $scope.rootObservation = $scope.conceptSet ? observationMapper.map($scope.observations, $scope.conceptSet, conceptSetUIConfig) : null, $scope.rootObservation) {
|
|
$scope.rootObservation.conceptSetName = $scope.conceptSetName, focusFirstObs(), updateObservationsOnRootScope();
|
|
var groupMembers = getObservationsOfCurrentTemplate()[0].groupMembers,
|
|
defaults = getDefaults();
|
|
addDummyImage(), setDefaultsForGroupMembers(groupMembers, defaults);
|
|
var observationsOfCurrentTemplate = getObservationsOfCurrentTemplate();
|
|
updateFormConditions(observationsOfCurrentTemplate, $scope.rootObservation)
|
|
} else $scope.showEmptyConceptSetMessage = !0
|
|
})["catch"](function(error) {
|
|
messagingService.showMessage("error", error.message)
|
|
})
|
|
};
|
|
spinner.forPromise(init(), id);
|
|
var validateObservationTree = function() {
|
|
if ("undefined" == typeof $scope.rootObservation || null === $scope.rootObservation) return {
|
|
allow: !0,
|
|
errorMessage: null
|
|
};
|
|
$scope.atLeastOneValueIsSet = $scope.rootObservation && $scope.rootObservation.atLeastOneValueSet(), $scope.conceptSetRequired = !$scope.required || $scope.required;
|
|
var nodes = $scope.rootObservation && findInvalidNodes($scope.rootObservation.groupMembers, $scope.rootObservation);
|
|
return {
|
|
allow: !nodes.status,
|
|
errorMessage: nodes.message
|
|
}
|
|
},
|
|
findInvalidNodes = function(members, parentNode) {
|
|
var errorMessage = null,
|
|
status = members.some(function(childNode) {
|
|
if (childNode.voided) return !1;
|
|
var groupMembers = childNode.groupMembers || [];
|
|
for (var index in groupMembers) {
|
|
var information = groupMembers[index].groupMembers && groupMembers[index].groupMembers.length ? findInvalidNodes(groupMembers[index].groupMembers, groupMembers[index]) : validateChildNode(groupMembers[index], childNode);
|
|
if (information.status) return errorMessage = information.message, !0
|
|
}
|
|
return information = validateChildNode(childNode, parentNode), information.status ? (errorMessage = information.message, !0) : !childNode.isValid($scope.atLeastOneValueIsSet, $scope.conceptSetRequired)
|
|
});
|
|
return {
|
|
message: errorMessage,
|
|
status: status
|
|
}
|
|
},
|
|
validateChildNode = function(childNode, parentNode) {
|
|
var errorMessage;
|
|
if (childNode.possibleAnswers && !childNode.possibleAnswers.length) {
|
|
if ("function" == typeof childNode.isValueInAbsoluteRange && !childNode.isValueInAbsoluteRange()) return errorMessage = "The value you entered (red field) is outside the range of allowable values for that record. Please check the value.", {
|
|
message: errorMessage,
|
|
status: !0
|
|
};
|
|
if (childNode.isNumeric()) {
|
|
if (!childNode.isValidNumeric()) return errorMessage = "Please enter Integer value, decimal value is not allowed", {
|
|
message: errorMessage,
|
|
status: !0
|
|
};
|
|
if (parentNode) {
|
|
if (!childNode.isValidNumericValue() || !parentNode.isValidNumericValue()) return errorMessage = "Please enter Numeric values", {
|
|
message: errorMessage,
|
|
status: !0
|
|
}
|
|
} else if (!childNode.isValidNumericValue()) return errorMessage = "Please enter Numeric values", {
|
|
message: errorMessage,
|
|
status: !0
|
|
}
|
|
}
|
|
}
|
|
return {
|
|
status: !1
|
|
}
|
|
};
|
|
validationHandler.add(validateObservationTree);
|
|
var cleanUpListenerShowPrevious = $scope.$on("event:showPrevious" + conceptSetName, function() {
|
|
return spinner.forPromise(observationsService.fetch($scope.patient.uuid, $scope.conceptSetName, null, $scope.numberOfVisits, null, !0), id).then(function(response) {
|
|
var recentObservations = ObservationUtil.flattenObsToArray(response.data),
|
|
conceptSetObservation = $scope.observations.filter(function(observation) {
|
|
return observation.conceptSetName === $scope.conceptSetName
|
|
});
|
|
ObservationUtil.flattenObsToArray(conceptSetObservation).forEach(function(obs) {
|
|
var correspondingRecentObs = _.filter(recentObservations, function(recentObs) {
|
|
return obs.concept.uuid === recentObs.concept.uuid
|
|
});
|
|
null != correspondingRecentObs && correspondingRecentObs.length > 0 && (correspondingRecentObs.sort(function(obs1, obs2) {
|
|
return new Date(obs2.encounterDateTime) - new Date(obs1.encounterDateTime)
|
|
}), obs.previous = correspondingRecentObs.map(function(previousObs) {
|
|
return {
|
|
value: Bahmni.Common.Domain.ObservationValueMapper.map(previousObs),
|
|
date: previousObs.observationDateTime
|
|
}
|
|
}))
|
|
})
|
|
})
|
|
}),
|
|
deregisterAddMore = $scope.$root.$on("event:addMore", function(event, observation) {
|
|
updateFormConditions([observation], observation)
|
|
}),
|
|
deregisterObservationUpdated = $scope.$root.$on("event:observationUpdated-" + conceptSetName, function(event, conceptName, rootObservation) {
|
|
var formName = rootObservation.concept.name,
|
|
formCondition = Bahmni.ConceptSet.FormConditions.rules && Bahmni.ConceptSet.FormConditions.rules[conceptName];
|
|
if (formCondition) {
|
|
var flattenedObs = ObservationUtil.flattenObsToArray([rootObservation]);
|
|
runFormConditionForObs(!0, formName, formCondition, conceptName, flattenedObs)
|
|
}
|
|
});
|
|
$scope.$on("$destroy", function() {
|
|
deregisterObservationUpdated(), deregisterAddMore(), cleanUpListenerShowPrevious()
|
|
})
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
scope: {
|
|
conceptSetName: "=",
|
|
observations: "=?",
|
|
required: "=?",
|
|
showTitle: "&",
|
|
validationHandler: "&",
|
|
patient: "=",
|
|
conceptSetFocused: "=?",
|
|
collapseInnerSections: "=?",
|
|
atLeastOneValueIsSet: "=?",
|
|
sectionId: "="
|
|
},
|
|
templateUrl: "../common/concept-set/views/conceptSet.html",
|
|
controller: controller
|
|
}
|
|
}]), angular.module("bahmni.common.conceptSet").directive("formControls", ["formService", "spinner", "$timeout", "$translate", function(formService, spinner, $timeout, $translate) {
|
|
var loadedFormDetails = {},
|
|
loadedFormTranslations = {},
|
|
unMountReactContainer = function(formUuid) {
|
|
var reactContainerElement = angular.element(document.getElementById(formUuid));
|
|
reactContainerElement.on("$destroy", function() {
|
|
unMountForm(document.getElementById(formUuid))
|
|
})
|
|
},
|
|
controller = function($scope) {
|
|
var formUuid = $scope.form.formUuid,
|
|
formVersion = $scope.form.formVersion,
|
|
formName = $scope.form.formName,
|
|
formObservations = $scope.form.observations,
|
|
collapse = $scope.form.collapseInnerSections && $scope.form.collapseInnerSections.value,
|
|
validateForm = $scope.validateForm || !1,
|
|
locale = $translate.use();
|
|
loadedFormDetails[formUuid] ? $timeout(function() {
|
|
$scope.form.component = renderWithControls(loadedFormDetails[formUuid], formObservations, formUuid, collapse, $scope.patient, validateForm, locale, loadedFormTranslations[formUuid]), unMountReactContainer($scope.form.formUuid)
|
|
}, 0, !1) : spinner.forPromise(formService.getFormDetail(formUuid, {
|
|
v: "custom:(resources:(value))"
|
|
}).then(function(response) {
|
|
var formDetailsAsString = _.get(response, "data.resources[0].value");
|
|
if (formDetailsAsString) {
|
|
var formDetails = JSON.parse(formDetailsAsString);
|
|
formDetails.version = formVersion, loadedFormDetails[formUuid] = formDetails;
|
|
var formParams = {
|
|
formName: formName,
|
|
formVersion: formVersion,
|
|
locale: locale,
|
|
formUuid: formDetails.uuid
|
|
};
|
|
spinner.forPromise(formService.getFormTranslations(formDetails.translationsUrl, formParams).then(function(response) {
|
|
var formTranslations = _.isEmpty(response.data) ? {} : response.data[0];
|
|
loadedFormTranslations[formUuid] = formTranslations, $scope.form.component = renderWithControls(formDetails, formObservations, formUuid, collapse, $scope.patient, validateForm, locale, formTranslations)
|
|
}, function() {
|
|
var formTranslations = {};
|
|
loadedFormTranslations[formUuid] = formTranslations, $scope.form.component = renderWithControls(formDetails, formObservations, formUuid, collapse, $scope.patient, validateForm, locale, formTranslations)
|
|
}))
|
|
}
|
|
unMountReactContainer($scope.form.formUuid)
|
|
})), $scope.$watch("form.collapseInnerSections", function() {
|
|
var collapse = $scope.form.collapseInnerSections && $scope.form.collapseInnerSections.value;
|
|
loadedFormDetails[formUuid] && ($scope.form.component = renderWithControls(loadedFormDetails[formUuid], formObservations, formUuid, collapse, $scope.patient, validateForm, locale, loadedFormTranslations[formUuid]))
|
|
}), $scope.$on("$destroy", function() {
|
|
if ($scope.$parent.consultation && $scope.$parent.consultation.observationForms && $scope.form.component) {
|
|
var formObservations = $scope.form.component.getValue();
|
|
$scope.form.observations = formObservations.observations;
|
|
var hasError = formObservations.errors;
|
|
_.isEmpty(hasError) || ($scope.form.isValid = !1)
|
|
}
|
|
})
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
scope: {
|
|
form: "=",
|
|
patient: "=",
|
|
validateForm: "="
|
|
},
|
|
controller: controller
|
|
}
|
|
}]), angular.module("bahmni.common.conceptSet").directive("concept", ["RecursionHelper", "spinner", "$filter", "messagingService", function(RecursionHelper, spinner, $filter, messagingService) {
|
|
var link = function(scope) {
|
|
var hideAbnormalbuttonConfig = scope.observation && scope.observation.conceptUIConfig && scope.observation.conceptUIConfig.hideAbnormalButton;
|
|
scope.now = moment().format("YYYY-MM-DD hh:mm:ss"), scope.showTitle = void 0 === scope.showTitle || scope.showTitle, scope.hideAbnormalButton = void 0 == hideAbnormalbuttonConfig ? scope.hideAbnormalButton : hideAbnormalbuttonConfig, scope.cloneNew = function(observation, parentObservation) {
|
|
observation.showAddMoreButton = function() {
|
|
return !1
|
|
};
|
|
var newObs = observation.cloneNew();
|
|
newObs.scrollToElement = !0;
|
|
var index = parentObservation.groupMembers.indexOf(observation);
|
|
parentObservation.groupMembers.splice(index + 1, 0, newObs), messagingService.showMessage("info", "A new " + observation.label + " section has been added"), scope.$root.$broadcast("event:addMore", newObs)
|
|
}, scope.removeClonedObs = function(observation, parentObservation) {
|
|
observation.voided = !0;
|
|
var lastObservationByLabel = _.findLast(parentObservation.groupMembers, function(groupMember) {
|
|
return groupMember.label === observation.label && !groupMember.voided
|
|
});
|
|
lastObservationByLabel.showAddMoreButton = function() {
|
|
return !0
|
|
}, observation.hidden = !0
|
|
}, scope.isClone = function(observation, parentObservation) {
|
|
if (parentObservation && parentObservation.groupMembers) {
|
|
var index = parentObservation.groupMembers.indexOf(observation);
|
|
return index > 0 && parentObservation.groupMembers[index].label == parentObservation.groupMembers[index - 1].label
|
|
}
|
|
return !1
|
|
}, scope.isRemoveValid = function(observation) {
|
|
return "image" != observation.getControlType() || !observation.value
|
|
}, scope.getStringValue = function(observations) {
|
|
return observations.map(function(observation) {
|
|
return observation.value + " (" + $filter("bahmniDate")(observation.date) + ")"
|
|
}).join(", ")
|
|
}, scope.toggleSection = function() {
|
|
scope.collapse = !scope.collapse
|
|
}, scope.isCollapsibleSet = function() {
|
|
return 1 == scope.showTitle
|
|
}, scope.hasPDFAsValue = function() {
|
|
return scope.observation.value && scope.observation.value.indexOf(".pdf") > 0
|
|
}, scope.$watch("collapseInnerSections", function() {
|
|
scope.collapse = scope.collapseInnerSections && scope.collapseInnerSections.value
|
|
}), scope.handleUpdate = function() {
|
|
scope.$root.$broadcast("event:observationUpdated-" + scope.conceptSetName, scope.observation.concept.name, scope.rootObservation)
|
|
}, scope.update = function(value) {
|
|
scope.getBooleanResult(scope.observation.isObservationNode) ? scope.observation.primaryObs.value = value : scope.getBooleanResult(scope.observation.isFormElement()) && (scope.observation.value = value), scope.handleUpdate()
|
|
}, scope.getBooleanResult = function(value) {
|
|
return !!value
|
|
}
|
|
},
|
|
compile = function(element) {
|
|
return RecursionHelper.compile(element, link)
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
compile: compile,
|
|
scope: {
|
|
conceptSetName: "=",
|
|
observation: "=",
|
|
atLeastOneValueIsSet: "=",
|
|
showTitle: "=",
|
|
conceptSetRequired: "=",
|
|
rootObservation: "=",
|
|
patient: "=",
|
|
collapseInnerSections: "=",
|
|
rootConcept: "&",
|
|
hideAbnormalButton: "="
|
|
},
|
|
templateUrl: "../common/concept-set/views/observation.html"
|
|
}
|
|
}]), angular.module("bahmni.common.conceptSet").directive("buttonSelect", function() {
|
|
return {
|
|
restrict: "E",
|
|
scope: {
|
|
observation: "=",
|
|
abnormalObs: "=?"
|
|
},
|
|
link: function(scope, element, attrs) {
|
|
attrs.dirtyCheckFlag && (scope.hasDirtyFlag = !0)
|
|
},
|
|
controller: function($scope) {
|
|
$scope.isSet = function(answer) {
|
|
return $scope.observation.hasValueOf(answer)
|
|
}, $scope.select = function(answer) {
|
|
$scope.observation.toggleSelection(answer), $scope.$parent.observation && "function" == typeof $scope.$parent.observation.onValueChanged && $scope.$parent.observation.onValueChanged(), $scope.$parent.handleUpdate()
|
|
}, $scope.getAnswerDisplayName = function(answer) {
|
|
var shortName = answer.names ? _.first(answer.names.filter(function(name) {
|
|
return "SHORT" === name.conceptNameType
|
|
})) : null;
|
|
return shortName ? shortName.name : answer.displayString
|
|
}
|
|
},
|
|
templateUrl: "../common/concept-set/views/buttonSelect.html"
|
|
}
|
|
}), angular.module("bahmni.common.conceptSet").directive("stepper", function() {
|
|
return {
|
|
restrict: "E",
|
|
require: "ngModel",
|
|
replace: !0,
|
|
scope: {
|
|
ngModel: "=",
|
|
obs: "=",
|
|
ngClass: "=",
|
|
focusMe: "="
|
|
},
|
|
template: '<div class="stepper clearfix"><button ng-click="decrement()" class="stepper__btn stepper__minus" ng-disabled="obs.disabled">-</button><input id="{{::obs.uniqueId}}" obs-constraints ng-model="ngModel" obs="::obs" ng-class="ngClass" focus-me="focusMe" type="text" class="stepper__field" ng-disabled="obs.disabled" /><button ng-click="increment()" class="stepper__btn stepper__plus" ng-disabled="obs.disabled">+</button></div> ',
|
|
link: function(scope, element, attrs, ngModelController) {
|
|
function updateModel(offset) {
|
|
var currValue = 0;
|
|
isNaN(ngModelController.$viewValue) ? null != scope.obs.concept.lowNormal && (currValue = scope.obs.concept.lowNormal - offset) : currValue = parseInt(ngModelController.$viewValue), ngModelController.$setViewValue(currValue + offset)
|
|
}
|
|
ngModelController.$render = function() {}, ngModelController.$formatters.push(function(value) {
|
|
return parseInt(value, 10)
|
|
}), ngModelController.$parsers.push(function(value) {
|
|
return parseInt(value, 10)
|
|
}), scope.increment = function() {
|
|
if (null != scope.obs.concept.hiNormal) {
|
|
var currValue = isNaN(ngModelController.$viewValue) ? 0 : ngModelController.$viewValue;
|
|
currValue < scope.obs.concept.hiNormal && updateModel(1)
|
|
} else updateModel(1)
|
|
}, scope.decrement = function() {
|
|
if (null != scope.obs.concept.lowNormal) {
|
|
var currValue = isNaN(ngModelController.$viewValue) ? 0 : ngModelController.$viewValue;
|
|
currValue > scope.obs.concept.lowNormal && updateModel(-1)
|
|
} else updateModel(-1)
|
|
}
|
|
}
|
|
}
|
|
}), angular.module("bahmni.common.conceptSet").directive("obsConstraints", function() {
|
|
var attributesMap = {
|
|
Numeric: "number",
|
|
Date: "date",
|
|
Datetime: "datetime"
|
|
},
|
|
link = function($scope, element) {
|
|
var attributes = {},
|
|
obsConcept = $scope.obs.concept;
|
|
obsConcept.conceptClass == Bahmni.Common.Constants.conceptDetailsClassName && (obsConcept = $scope.obs.primaryObs.concept), attributes.type = attributesMap[obsConcept.dataType] || "text", "number" === attributes.type && (attributes.step = "any"), obsConcept.hiNormal && (attributes.max = obsConcept.hiNormal), obsConcept.lowNormal && (attributes.min = obsConcept.lowNormal), "date" == attributes.type && (null != $scope.obs.conceptUIConfig && $scope.obs.conceptUIConfig.allowFutureDates || (attributes.max = Bahmni.Common.Util.DateTimeFormatter.getDateWithoutTime())), element.attr(attributes)
|
|
};
|
|
return {
|
|
link: link,
|
|
scope: {
|
|
obs: "="
|
|
},
|
|
require: "ngModel"
|
|
}
|
|
}), angular.module("bahmni.common.conceptSet").directive("duration", ["contextChangeHandler", function(contextChangeHandler) {
|
|
var link = function($scope, element, attrs, ngModelController) {
|
|
var setValue = function() {
|
|
if ($scope.unitValue && $scope.measureValue) {
|
|
var value = $scope.unitValue * $scope.measureValue;
|
|
ngModelController.$setViewValue(value)
|
|
} else ngModelController.$setViewValue(void 0)
|
|
};
|
|
$scope.$watch("measureValue", setValue), $scope.$watch("unitValue", setValue), $scope.$watch("disabled", function(value) {
|
|
value && ($scope.unitValue = void 0, $scope.measureValue = void 0, $scope.hours = void 0)
|
|
});
|
|
var illegalValueChecker = $scope.$watch("illegalValue", function(value) {
|
|
$scope.illegalDurationValue = value;
|
|
var contextChange = function() {
|
|
return {
|
|
allow: !$scope.illegalDurationValue
|
|
}
|
|
};
|
|
contextChangeHandler.add(contextChange)
|
|
});
|
|
$scope.$on("$destroy", function() {
|
|
$scope.illegalDurationValue = !1, illegalValueChecker()
|
|
})
|
|
},
|
|
controller = function($scope) {
|
|
var valueAndUnit = Bahmni.Common.Util.DateUtil.convertToUnits($scope.hours);
|
|
$scope.units = valueAndUnit.allUnits, $scope.measureValue = valueAndUnit.value, $scope.unitValue = valueAndUnit.unitValueInMinutes;
|
|
var durations = Object.keys($scope.units).reverse();
|
|
$scope.displayUnits = durations.map(function(duration) {
|
|
return {
|
|
name: duration,
|
|
value: $scope.units[duration]
|
|
}
|
|
})
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
require: "ngModel",
|
|
controller: controller,
|
|
scope: {
|
|
hours: "=ngModel",
|
|
illegalValue: "=",
|
|
disabled: "="
|
|
},
|
|
link: link,
|
|
template: '<span><input tabindex="1" style="float: left;" type="number" min="0" class="duration-value" ng-class="{\'illegalValue\': illegalValue}" ng-model=\'measureValue\' ng-disabled="disabled"/></span><span><select tabindex="1" ng-model=\'unitValue\' class="duration-unit" ng-class="{\'illegalValue\': illegalValue}" ng-options="displayUnit.value as displayUnit.name for displayUnit in displayUnits" ng-disabled="disabled"><option value=""></option>></select></span>'
|
|
}
|
|
}]), Bahmni.ConceptSet.ConceptSetGroupValidationHandler = function(conceptSetSections) {
|
|
var validations = [];
|
|
this.add = function(validation) {
|
|
validations.push(validation)
|
|
}, this.validate = function() {
|
|
var errorMessage = "",
|
|
allConceptSetSectionsValid = !0;
|
|
return validations.forEach(function(validation) {
|
|
var validationReturn = validation();
|
|
_.isEmpty(errorMessage) && (errorMessage = validationReturn.errorMessage), allConceptSetSectionsValid = allConceptSetSectionsValid && validationReturn.allow
|
|
}), allConceptSetSectionsValid || conceptSetSections.filter(_.property("isLoaded")).forEach(function(conceptSetSection) {
|
|
conceptSetSection.show()
|
|
}), {
|
|
allow: allConceptSetSectionsValid,
|
|
errorMessage: errorMessage
|
|
}
|
|
}
|
|
}, Bahmni.ConceptSet.ConceptSetGroupPanelViewValidationHandler = function(conceptSetSections) {
|
|
this.add = function(validation) {
|
|
var conceptSetPanel = getActiveConceptSet();
|
|
1 == conceptSetPanel.length && (conceptSetPanel[0].validate = validation)
|
|
};
|
|
var getActiveConceptSet = function() {
|
|
return _.filter(conceptSetSections, function(conceptSet) {
|
|
return "active" === conceptSet.klass
|
|
})
|
|
};
|
|
this.validate = function() {
|
|
var errorMessage = "",
|
|
allConceptSetSectionsValid = !0;
|
|
return _.forEach(conceptSetSections, function(conceptSet) {
|
|
if (conceptSet.validate && "function" == typeof conceptSet.validate) {
|
|
var validationReturn = conceptSet.validate();
|
|
conceptSet.isValid = validationReturn.allow, conceptSet.errorMessage = validationReturn.errorMessage, "active" == conceptSet.klass && (errorMessage = validationReturn.errorMessage), allConceptSetSectionsValid = allConceptSetSectionsValid && validationReturn.allow
|
|
}
|
|
}), allConceptSetSectionsValid || conceptSetSections.filter(_.property("isLoaded")).forEach(function(conceptSetSection) {
|
|
conceptSetSection.show()
|
|
}), {
|
|
allow: allConceptSetSectionsValid,
|
|
errorMessage: errorMessage
|
|
}
|
|
}
|
|
}, Bahmni.ConceptSet.ConceptSetSection = function(extensions, user, config, observations, conceptSet) {
|
|
var self = this;
|
|
self.clone = function() {
|
|
var clonedConceptSetSection = new Bahmni.ConceptSet.ConceptSetSection(extensions, user, config, [], conceptSet);
|
|
return clonedConceptSetSection.isAdded = !0, clonedConceptSetSection
|
|
};
|
|
var init = function() {
|
|
self.observations = observations, self.options = extensions.extensionParams || {}, self.conceptName = conceptSet.name ? conceptSet.name.name : self.options.conceptName;
|
|
var conceptName = _.find(conceptSet.names, {
|
|
conceptNameType: "SHORT"
|
|
}) || _.find(conceptSet.names, {
|
|
conceptNameType: "FULLY_SPECIFIED"
|
|
});
|
|
conceptName = conceptName ? conceptName.name : conceptName, self.label = conceptName || self.conceptName || self.options.conceptName, self.isLoaded = self.isOpen, self.collapseInnerSections = {
|
|
value: !1
|
|
}, self.uuid = conceptSet.uuid, self.alwaysShow = user.isFavouriteObsTemplate(self.conceptName), self.allowAddMore = config.allowAddMore, self.id = "concept-set-" + conceptSet.uuid
|
|
},
|
|
getShowIfFunction = function() {
|
|
if (!self.showIfFunction) {
|
|
var showIfFunctionStrings = self.options.showIf || ["return true;"];
|
|
self.showIfFunction = new Function("context", showIfFunctionStrings.join("\n"))
|
|
}
|
|
return self.showIfFunction
|
|
},
|
|
atLeastOneValueSet = function(observation) {
|
|
return observation.groupMembers && observation.groupMembers.length > 0 ? observation.groupMembers.some(function(groupMember) {
|
|
return atLeastOneValueSet(groupMember)
|
|
}) : !(_.isUndefined(observation.value) || "" === observation.value)
|
|
};
|
|
self.isAvailable = function(context) {
|
|
return getShowIfFunction()(context || {})
|
|
}, self.show = function() {
|
|
self.isOpen = !0, self.isLoaded = !0
|
|
}, self.hide = function() {
|
|
self.isOpen = !1
|
|
}, self.getObservationsForConceptSection = function() {
|
|
return self.observations.filter(function(observation) {
|
|
return observation.concept.name === self.conceptName
|
|
})
|
|
}, self.hasSomeValue = function() {
|
|
var observations = self.getObservationsForConceptSection();
|
|
return _.some(observations, function(observation) {
|
|
return atLeastOneValueSet(observation)
|
|
})
|
|
}, self.showComputeButton = function() {
|
|
return config.computeDrugs === !0
|
|
}, self.toggle = function() {
|
|
self.added = !self.added, self.added && self.show()
|
|
}, self.maximizeInnerSections = function(event) {
|
|
event.stopPropagation(), self.collapseInnerSections = {
|
|
value: !1
|
|
}
|
|
}, self.minimizeInnerSections = function(event) {
|
|
event.stopPropagation(), self.collapseInnerSections = {
|
|
value: !0
|
|
}
|
|
}, self.toggleDisplay = function() {
|
|
self.isOpen ? self.hide() : self.show()
|
|
}, self.canToggle = function() {
|
|
return !self.hasSomeValue()
|
|
}, self.canAddMore = function() {
|
|
return 1 == self.allowAddMore
|
|
}, Object.defineProperty(self, "isOpen", {
|
|
get: function() {
|
|
return void 0 === self.open && (self.open = self.hasSomeValue()), self.open
|
|
},
|
|
set: function(value) {
|
|
self.open = value
|
|
}
|
|
}), self.isDefault = function() {
|
|
return self.options["default"]
|
|
}, Object.defineProperty(self, "isAdded", {
|
|
get: function() {
|
|
return void 0 === self.added && (self.options["default"] ? self.added = !0 : self.added = self.hasSomeValue()), self.added
|
|
},
|
|
set: function(value) {
|
|
self.added = value
|
|
}
|
|
}), init()
|
|
}, Bahmni.ConceptSet.Observation = function(observation, savedObs, conceptUIConfig) {
|
|
var self = this;
|
|
angular.extend(this, observation), this.isObservation = !0, this.conceptUIConfig = conceptUIConfig[this.concept.name] || [], this.uniqueId = _.uniqueId("observation_"), this.erroneousValue = null, savedObs ? (this.uuid = savedObs.uuid, this.value = savedObs.value, this.observationDateTime = savedObs.observationDateTime, this.provider = savedObs.provider) : this.value = this.conceptUIConfig.defaultValue, Object.defineProperty(this, "autocompleteValue", {
|
|
enumerable: !0,
|
|
get: function() {
|
|
return null != this.value && "object" == typeof this.value ? this.value.name : this.value
|
|
},
|
|
set: function(newValue) {
|
|
this.__prevValue = this.value, this.value = newValue
|
|
}
|
|
}), Object.defineProperty(this, "value", {
|
|
enumerable: !0,
|
|
get: function() {
|
|
return null != self._value ? self._value : (savedObs && "object" == typeof savedObs.value && savedObs.value && (savedObs.value.displayString = savedObs.value.shortName ? savedObs.value.shortName : savedObs.value.name), savedObs ? savedObs.value : void 0)
|
|
},
|
|
set: function(newValue) {
|
|
self.__prevValue = this.value, self._value = newValue, newValue || (savedObs = null), self.onValueChanged()
|
|
}
|
|
});
|
|
var cloneNonTabularObs = function(oldObs) {
|
|
var newGroupMembers = [];
|
|
return oldObs.groupMembers.forEach(function(member) {
|
|
if (void 0 === member.isTabularObs) {
|
|
var clone = member.cloneNew();
|
|
clone.hidden = member.hidden, newGroupMembers.push(clone)
|
|
}
|
|
}), newGroupMembers
|
|
},
|
|
getTabularObs = function(oldObs) {
|
|
var tabularObsList = [];
|
|
return oldObs.groupMembers.forEach(function(member) {
|
|
void 0 !== member.isTabularObs && tabularObsList.push(member)
|
|
}), tabularObsList
|
|
},
|
|
cloneTabularObs = function(oldObs, tabularObsList) {
|
|
return tabularObsList = _.map(tabularObsList, function(tabularObs) {
|
|
var matchingObsList = _.filter(oldObs.groupMembers, function(member) {
|
|
return member.concept.name == tabularObs.concept.name
|
|
});
|
|
return new Bahmni.ConceptSet.TabularObservations(matchingObsList, oldObs, conceptUIConfig)
|
|
}), tabularObsList.forEach(function(tabularObs) {
|
|
oldObs.groupMembers.push(tabularObs)
|
|
}), oldObs
|
|
};
|
|
this.cloneNew = function() {
|
|
var oldObs = angular.copy(observation);
|
|
if (oldObs.groupMembers && oldObs.groupMembers.length > 0) {
|
|
oldObs.groupMembers = _.filter(oldObs.groupMembers, function(member) {
|
|
return !member.isMultiSelect
|
|
});
|
|
var newGroupMembers = cloneNonTabularObs(oldObs),
|
|
tabularObsList = getTabularObs(oldObs);
|
|
oldObs.groupMembers = newGroupMembers, _.isEmpty(tabularObsList) || (oldObs = cloneTabularObs(oldObs, tabularObsList))
|
|
}
|
|
new Bahmni.ConceptSet.MultiSelectObservations(conceptUIConfig).map(oldObs.groupMembers);
|
|
var clone = new Bahmni.ConceptSet.Observation(oldObs, null, conceptUIConfig);
|
|
return clone.comment = void 0, clone.disabled = this.disabled, clone
|
|
}
|
|
}, Bahmni.ConceptSet.Observation.prototype = {
|
|
displayValue: function() {
|
|
if (!(this.possibleAnswers.length > 0)) return this.value;
|
|
for (var i = 0; i < this.possibleAnswers.length; i++)
|
|
if (this.possibleAnswers[i].uuid === this.value) return this.possibleAnswers[i].display
|
|
},
|
|
isGroup: function() {
|
|
return !!this.groupMembers && this.groupMembers.length > 0
|
|
},
|
|
isComputed: function() {
|
|
return "Computed" === this.concept.conceptClass
|
|
},
|
|
isComputedAndEditable: function() {
|
|
return "Computed/Editable" === this.concept.conceptClass
|
|
},
|
|
isNumeric: function() {
|
|
return "Numeric" === this.getDataTypeName()
|
|
},
|
|
isValidNumeric: function() {
|
|
return !(!this.isDecimalAllowed() && this.value && this.value.toString().indexOf(".") >= 0)
|
|
},
|
|
isValidNumericValue: function() {
|
|
var element = document.getElementById(this.uniqueId);
|
|
return "" !== this.value || !element || element.checkValidity()
|
|
},
|
|
isText: function() {
|
|
return "Text" === this.getDataTypeName()
|
|
},
|
|
isCoded: function() {
|
|
return "Coded" === this.getDataTypeName()
|
|
},
|
|
isDatetime: function() {
|
|
return "Datetime" === this.getDataTypeName()
|
|
},
|
|
isImage: function() {
|
|
return this.concept.conceptClass == Bahmni.Common.Constants.imageClassName
|
|
},
|
|
isVideo: function() {
|
|
return this.concept.conceptClass == Bahmni.Common.Constants.videoClassName
|
|
},
|
|
getDataTypeName: function() {
|
|
return this.concept.dataType
|
|
},
|
|
isDecimalAllowed: function() {
|
|
return this.concept.allowDecimal
|
|
},
|
|
isDateDataType: function() {
|
|
return "Date".indexOf(this.getDataTypeName()) != -1
|
|
},
|
|
isVoided: function() {
|
|
return void 0 !== this.voided && this.voided
|
|
},
|
|
getPossibleAnswers: function() {
|
|
return this.possibleAnswers
|
|
},
|
|
getHighAbsolute: function() {
|
|
return this.concept.hiAbsolute
|
|
},
|
|
getLowAbsolute: function() {
|
|
return this.concept.lowAbsolute
|
|
},
|
|
isHtml5InputDataType: function() {
|
|
return ["Date", "Numeric"].indexOf(this.getDataTypeName()) !== -1
|
|
},
|
|
isGrid: function() {
|
|
return this.conceptUIConfig.grid
|
|
},
|
|
isButtonRadio: function() {
|
|
return this.conceptUIConfig.buttonRadio
|
|
},
|
|
isComplex: function() {
|
|
return "Complex" === this.concept.dataType
|
|
},
|
|
isLocationRef: function() {
|
|
return this.isComplex() && "LocationObsHandler" === this.concept.handler
|
|
},
|
|
isProviderRef: function() {
|
|
return this.isComplex() && "ProviderObsHandler" === this.concept.handler
|
|
},
|
|
getControlType: function() {
|
|
return this.hidden ? "hidden" : this.conceptUIConfig.freeTextAutocomplete ? "freeTextAutocomplete" : this.isHtml5InputDataType() ? "html5InputDataType" : this.isImage() ? "image" : this.isVideo() ? "video" : this.isText() ? "text" : this.isCoded() ? this._getCodedControlType() : this.isGrid() ? "grid" : this.isDatetime() ? "datetime" : this.isLocationRef() ? "text" : this.isProviderRef() ? "text" : "unknown"
|
|
},
|
|
canHaveComment: function() {
|
|
return this.conceptUIConfig.disableAddNotes ? !this.conceptUIConfig.disableAddNotes : !this.isText() && !this.isImage() && !this.isVideo()
|
|
},
|
|
canAddMore: function() {
|
|
return 1 == this.conceptUIConfig.allowAddMore
|
|
},
|
|
isStepperControl: function() {
|
|
if (this.isNumeric()) return 1 == this.conceptUIConfig.stepper
|
|
},
|
|
isConciseText: function() {
|
|
return 1 == this.conceptUIConfig.conciseText
|
|
},
|
|
_getCodedControlType: function() {
|
|
var conceptUIConfig = this.conceptUIConfig;
|
|
return conceptUIConfig.autocomplete ? "autocomplete" : conceptUIConfig.dropdown ? "dropdown" : "buttonselect"
|
|
},
|
|
onValueChanged: function() {
|
|
this.isNumeric() && this.setErroneousValue()
|
|
},
|
|
setErroneousValue: function() {
|
|
if (this.hasValue()) {
|
|
var erroneousValue = this.value > (this.concept.hiAbsolute || 1 / 0) || this.value < (this.concept.lowAbsolute || 0);
|
|
this.erroneousValue = erroneousValue
|
|
} else this.erroneousValue = void 0
|
|
},
|
|
getInputType: function() {
|
|
return this.getDataTypeName()
|
|
},
|
|
atLeastOneValueSet: function() {
|
|
return this.isGroup() ? this.groupMembers.some(function(childNode) {
|
|
return childNode.atLeastOneValueSet()
|
|
}) : this.hasValue() && !this.isVoided()
|
|
},
|
|
hasValue: function() {
|
|
var value = this.value;
|
|
return value === !1 || (0 === value || !("" === value || !value) && (!(value instanceof Array) || value.length > 0))
|
|
},
|
|
hasValueOf: function(value) {
|
|
return !(!this.value || !value) && (this.value == value || this.value.uuid == value.uuid)
|
|
},
|
|
toggleSelection: function(answer) {
|
|
this.value && this.value.uuid === answer.uuid ? this.value = null : this.value = answer
|
|
},
|
|
isValidDate: function() {
|
|
if (this.isComputed()) return !0;
|
|
if (!this.hasValue()) return !0;
|
|
var date = Bahmni.Common.Util.DateUtil.parse(this.value);
|
|
if (!this.conceptUIConfig.allowFutureDates) {
|
|
var today = Bahmni.Common.Util.DateUtil.parse(moment().format("YYYY-MM-DD"));
|
|
if (today < date) return !1
|
|
}
|
|
return date.getUTCFullYear() && date.getUTCFullYear().toString().length <= 4
|
|
},
|
|
hasInvalidDateTime: function() {
|
|
if (this.isComputed()) return !1;
|
|
var date = Bahmni.Common.Util.DateUtil.parse(this.value);
|
|
return !this.conceptUIConfig.allowFutureDates && moment() < date || "Invalid Datetime" === this.value
|
|
},
|
|
isValid: function(checkRequiredFields, conceptSetRequired) {
|
|
if (this.isNumeric() && !this.isValidNumeric()) return !1;
|
|
if (this.error) return !1;
|
|
if (this.hidden) return !0;
|
|
if (checkRequiredFields) {
|
|
if (this.isGroup()) return this._hasValidChildren(checkRequiredFields, conceptSetRequired);
|
|
if (conceptSetRequired && this.isRequired() && !this.hasValue()) return !1;
|
|
if (this.isRequired() && !this.hasValue()) return !1
|
|
}
|
|
return this._isDateDataType() ? this.isValidDate() : this._isDateTimeDataType() ? !this.hasInvalidDateTime() : !this.erroneousValue && ("autocomplete" !== this.getControlType() || (_.isEmpty(this.value) || _.isObject(this.value)))
|
|
},
|
|
isValueInAbsoluteRange: function() {
|
|
return !this.erroneousValue && (!this.isGroup() || this._areChildNodesInAbsoluteRange())
|
|
},
|
|
_isDateDataType: function() {
|
|
return "Date" === this.getDataTypeName()
|
|
},
|
|
_isDateTimeDataType: function() {
|
|
return "Datetime" === this.getDataTypeName()
|
|
},
|
|
isRequired: function() {
|
|
return this.disabled = !!this.disabled && this.disabled, this.conceptUIConfig.required === !0 && this.disabled === !1
|
|
},
|
|
isFormElement: function() {
|
|
return (!this.concept.set || this.isGrid()) && !this.isComputed()
|
|
},
|
|
_hasValidChildren: function(checkRequiredFields, conceptSetRequired) {
|
|
return this.groupMembers.every(function(member) {
|
|
return member.isValid(checkRequiredFields, conceptSetRequired)
|
|
})
|
|
},
|
|
_areChildNodesInAbsoluteRange: function() {
|
|
return this.groupMembers.every(function(member) {
|
|
return "function" != typeof member.isValueInAbsoluteRange || member.isValueInAbsoluteRange()
|
|
})
|
|
},
|
|
markAsNonCoded: function() {
|
|
this.markedAsNonCoded = !this.markedAsNonCoded
|
|
},
|
|
toggleVoidingOfImage: function() {
|
|
this.voided = !this.voided
|
|
},
|
|
assignAddMoreButtonID: function() {
|
|
return this.concept.name.split(" ").join("_").toLowerCase() + "_addmore_" + this.uniqueId
|
|
}
|
|
}, Bahmni.ConceptSet.MultiSelectObservations = function(conceptSetConfig) {
|
|
var self = this;
|
|
this.multiSelectObservationsMap = {}, this.map = function(memberOfCollection) {
|
|
memberOfCollection.forEach(function(member) {
|
|
isMultiSelectable(member.concept, conceptSetConfig) && add(member.concept, member, memberOfCollection)
|
|
}), insertMultiSelectObsInExistingOrder(memberOfCollection)
|
|
};
|
|
var isMultiSelectable = function(concept, conceptSetConfig) {
|
|
return conceptSetConfig[concept.name] && conceptSetConfig[concept.name].multiSelect
|
|
},
|
|
insertMultiSelectObsInExistingOrder = function(memberOfCollection) {
|
|
getAll().forEach(function(multiObs) {
|
|
var index = _.findIndex(memberOfCollection, function(member) {
|
|
return member.concept.name === multiObs.concept.name
|
|
});
|
|
memberOfCollection.splice(index, 0, multiObs)
|
|
})
|
|
},
|
|
add = function(concept, obs, memberOfCollection) {
|
|
var conceptName = concept.name.name || concept.name;
|
|
self.multiSelectObservationsMap[conceptName] = self.multiSelectObservationsMap[conceptName] || new Bahmni.ConceptSet.MultiSelectObservation(concept, memberOfCollection, conceptSetConfig), self.multiSelectObservationsMap[conceptName].add(obs)
|
|
},
|
|
getAll = function() {
|
|
return _.values(self.multiSelectObservationsMap)
|
|
}
|
|
}, Bahmni.ConceptSet.MultiSelectObservation = function(concept, memberOfCollection, conceptSetConfig) {
|
|
var self = this;
|
|
this.label = concept.shortName || concept.name, this.isMultiSelect = !0, this.selectedObs = {}, this.concept = concept, this.concept.answers = this.concept.answers || [], this.groupMembers = [], this.provider = null, this.observationDateTime = "", this.conceptUIConfig = conceptSetConfig[this.concept.name] || {}, this.possibleAnswers = self.concept.answers.map(function(answer) {
|
|
var cloned = _.cloneDeep(answer);
|
|
return answer.name.name && (cloned.name = answer.name.name), cloned
|
|
}), this.getPossibleAnswers = function() {
|
|
return this.possibleAnswers
|
|
}, this.cloneNew = function() {
|
|
var clone = new Bahmni.ConceptSet.MultiSelectObservation(concept, memberOfCollection, conceptSetConfig);
|
|
return clone.disabled = this.disabled, clone
|
|
}, this.add = function(obs) {
|
|
if (obs.value) {
|
|
self.selectedObs[obs.value.name] = obs, self.provider || (self.provider = self.selectedObs[obs.value.name].provider);
|
|
var currentObservationDateTime = self.selectedObs[obs.value.name].observationDateTime;
|
|
self.observationDateTime < currentObservationDateTime && (self.observationDateTime = currentObservationDateTime)
|
|
}
|
|
obs.hidden = !0
|
|
}, this.isComputedAndEditable = function() {
|
|
return "Computed/Editable" === this.concept.conceptClass
|
|
}, this.hasValueOf = function(answer) {
|
|
return self.selectedObs[answer.name] && !self.selectedObs[answer.name].voided
|
|
}, this.toggleSelection = function(answer) {
|
|
self.hasValueOf(answer) ? unselectAnswer(answer) : self.selectAnswer(answer)
|
|
}, this.isFormElement = function() {
|
|
return !0
|
|
}, this.getControlType = function() {
|
|
var conceptConfig = this.getConceptUIConfig();
|
|
return this.isCoded() && 1 == conceptConfig.autocomplete && 1 == conceptConfig.multiSelect ? "autocompleteMultiSelect" : 1 == conceptConfig.autocomplete ? "autocomplete" : "buttonselect"
|
|
}, this.atLeastOneValueSet = function() {
|
|
var obsValue = _.filter(this.selectedObs, function(obs) {
|
|
return obs.value
|
|
});
|
|
return !_.isEmpty(obsValue)
|
|
}, this.hasValue = function() {
|
|
return !_.isEmpty(this.selectedObs)
|
|
}, this.hasNonVoidedValue = function() {
|
|
var hasNonVoidedValue = !1;
|
|
return this.hasValue() && angular.forEach(this.selectedObs, function(obs) {
|
|
obs.voided || (hasNonVoidedValue = !0)
|
|
}), hasNonVoidedValue
|
|
}, this.isValid = function(checkRequiredFields, conceptSetRequired) {
|
|
if (this.error) return !1;
|
|
if (checkRequiredFields) {
|
|
if (conceptSetRequired && this.isRequired() && !this.hasNonVoidedValue()) return !1;
|
|
if (this.isRequired() && !this.hasNonVoidedValue()) return !1
|
|
}
|
|
return !0
|
|
}, this.canHaveComment = function() {
|
|
return !1
|
|
}, this.getConceptUIConfig = function() {
|
|
return this.conceptUIConfig || {}
|
|
}, this.canAddMore = function() {
|
|
return 1 == this.getConceptUIConfig().allowAddMore
|
|
}, this.isRequired = function() {
|
|
return this.disabled = !!this.disabled && this.disabled, this.getConceptUIConfig().required === !0 && this.disabled === !1
|
|
};
|
|
var createObsFrom = function(answer) {
|
|
var obs = newObservation(concept, answer, conceptSetConfig);
|
|
return memberOfCollection.push(obs), obs
|
|
},
|
|
removeObsFrom = function(answer) {
|
|
var obs = newObservation(concept, answer, conceptSetConfig);
|
|
_.remove(memberOfCollection, function(member) {
|
|
return !!member.value && obs.value.displayString == member.value.displayString
|
|
})
|
|
};
|
|
this.selectAnswer = function(answer) {
|
|
var obs = self.selectedObs[answer.name];
|
|
obs ? (obs.value = answer, obs.voided = !1) : (obs = createObsFrom(answer), self.add(obs))
|
|
};
|
|
var unselectAnswer = function(answer) {
|
|
var obs = self.selectedObs[answer.name];
|
|
obs && obs.uuid ? (obs.value = null, obs.voided = !0) : (removeObsFrom(answer), delete self.selectedObs[answer.name])
|
|
},
|
|
newObservation = function(concept, value, conceptSetConfig) {
|
|
var observation = buildObservation(concept);
|
|
return new Bahmni.ConceptSet.Observation(observation, {
|
|
value: value
|
|
}, conceptSetConfig, [])
|
|
},
|
|
buildObservation = function(concept) {
|
|
return {
|
|
concept: concept,
|
|
units: concept.units,
|
|
label: concept.shortName || concept.name,
|
|
possibleAnswers: self.concept.answers,
|
|
groupMembers: [],
|
|
comment: null
|
|
}
|
|
};
|
|
this.getValues = function() {
|
|
var values = [];
|
|
return _.values(self.selectedObs).forEach(function(obs) {
|
|
obs.value && values.push(obs.value.shortName || obs.value.name)
|
|
}), values
|
|
}, this.isComputed = function() {
|
|
return "Computed" === this.concept.conceptClass
|
|
}, this.getDataTypeName = function() {
|
|
return this.concept.dataType
|
|
}, this._isDateTimeDataType = function() {
|
|
return "Datetime" === this.getDataTypeName()
|
|
}, this.isNumeric = function() {
|
|
return "Numeric" === this.getDataTypeName()
|
|
}, this.isText = function() {
|
|
return "Text" === this.getDataTypeName()
|
|
}, this.isCoded = function() {
|
|
return "Coded" === this.getDataTypeName()
|
|
}
|
|
}, Bahmni.ConceptSet.SpecimenTypeObservation = function(observation, allSamples) {
|
|
angular.extend(this, observation), this.allSamples = allSamples, this.getPossibleAnswers = function() {
|
|
return this.allSamples
|
|
}, this.hasValueOf = function(answer) {
|
|
return observation.type && observation.type.uuid === answer.uuid
|
|
}, this.toggleSelection = function(answer) {
|
|
this.hasValueOf(answer) ? observation.type = null : observation.type = answer
|
|
}
|
|
}, Bahmni.ConceptSet.BooleanObservation = function(observation, conceptUIConfig) {
|
|
angular.extend(this, observation), this.isBoolean = !0, this.conceptUIConfig = conceptUIConfig[this.concept.name] || {}, this.cloneNew = function() {
|
|
var clone = new Bahmni.ConceptSet.BooleanObservation(angular.copy(observation), conceptUIConfig);
|
|
return clone.value = void 0, clone.comment = void 0, clone.uuid = null, clone.disabled = this.disabled, clone
|
|
};
|
|
var possibleAnswers = [{
|
|
displayString: "OBS_BOOLEAN_YES_KEY",
|
|
value: !0
|
|
}, {
|
|
displayString: "OBS_BOOLEAN_NO_KEY",
|
|
value: !1
|
|
}];
|
|
this.getPossibleAnswers = function() {
|
|
return possibleAnswers
|
|
}, this.hasValueOf = function(answer) {
|
|
return this.value === answer.value
|
|
}, this.toggleSelection = function(answer) {
|
|
this.value === answer.value ? this.value = null : this.value = answer.value
|
|
}, this.isFormElement = function() {
|
|
return !0
|
|
}, this.getControlType = function() {
|
|
return "buttonselect"
|
|
}, this.isRequired = function() {
|
|
return this.disabled = !!this.disabled && this.disabled, this.getConceptUIConfig().required === !0 && this.disabled === !1
|
|
}, this.isComputedAndEditable = function() {
|
|
return "Computed/Editable" === this.concept.conceptClass
|
|
}, this.atLeastOneValueSet = function() {
|
|
return void 0 != this.value
|
|
}, this.isValid = function(checkRequiredFields, conceptSetRequired) {
|
|
if (this.error) return !1;
|
|
var notYetSet = function(value) {
|
|
return "undefined" == typeof value || null == value;
|
|
};
|
|
if (checkRequiredFields) {
|
|
if (conceptSetRequired && this.isRequired() && notYetSet(this.value)) return !1;
|
|
if (this.isRequired() && notYetSet(this.value)) return !1
|
|
}
|
|
return !0
|
|
}, this.canHaveComment = function() {
|
|
return !this.getConceptUIConfig().disableAddNotes || !this.getConceptUIConfig().disableAddNotes
|
|
}, this.getConceptUIConfig = function() {
|
|
return this.conceptUIConfig
|
|
}, this.canAddMore = function() {
|
|
return 1 == this.getConceptUIConfig().allowAddMore
|
|
}, this.isComputed = function() {
|
|
return "Computed" === this.concept.conceptClass
|
|
}, this.getDataTypeName = function() {
|
|
return this.concept.dataType
|
|
}, this.hasValue = function() {
|
|
var value = this.value;
|
|
return value === !1 || (0 === value || !("" === value || !value) && (!(value instanceof Array) || value.length > 0))
|
|
}, this.isNumeric = function() {
|
|
return "Numeric" === this.getDataTypeName()
|
|
}, this.isText = function() {
|
|
return "Text" === this.getDataTypeName()
|
|
}, this.isCoded = function() {
|
|
return "Coded" === this.getDataTypeName()
|
|
}, this._isDateTimeDataType = function() {
|
|
return "Datetime" === this.getDataTypeName()
|
|
}
|
|
},
|
|
function() {
|
|
var findObservationByClassName = function(groupMembers, conceptClassName) {
|
|
return _.find(groupMembers, function(member) {
|
|
return member.concept.conceptClass.name === conceptClassName || member.concept.conceptClass === conceptClassName
|
|
})
|
|
},
|
|
findObservationByConceptName = function(groupMembers, conceptName) {
|
|
return _.find(groupMembers, {
|
|
concept: {
|
|
name: conceptName
|
|
}
|
|
})
|
|
},
|
|
setNewObservation = function(observation, newValue) {
|
|
observation && (observation.__prevValue = observation.value, observation.value = newValue, observation.voided = !1)
|
|
},
|
|
voidObservation = function(observation) {
|
|
observation && (observation.uuid ? observation.voided = !0 : observation.value = void 0)
|
|
},
|
|
isFreeTextAutocompleteType = function(conceptUIConfig) {
|
|
return conceptUIConfig.autocomplete && conceptUIConfig.nonCodedConceptName && conceptUIConfig.codedConceptName
|
|
};
|
|
Bahmni.ConceptSet.ObservationNode = function(observation, savedObs, conceptUIConfig, concept) {
|
|
angular.extend(this, observation), this.conceptUIConfig = conceptUIConfig[concept.name.name] || !_.isEmpty(concept.setMembers) && conceptUIConfig[concept.setMembers[0].name.name] || {}, this.cloneNew = function() {
|
|
var oldObs = angular.copy(observation);
|
|
oldObs.groupMembers = _.map(oldObs.groupMembers, function(member) {
|
|
return member.cloneNew()
|
|
});
|
|
var clone = new Bahmni.ConceptSet.ObservationNode(oldObs, null, conceptUIConfig, concept);
|
|
return clone.comment = void 0, clone
|
|
};
|
|
var getPrimaryObservationValue = function() {
|
|
return this.primaryObs && _.get(this, "primaryObs.value.name") || _.get(this, "primaryObs.value")
|
|
},
|
|
setFreeTextPrimaryObservationValue = function(newValue) {
|
|
var codedObservation = findObservationByConceptName(this.groupMembers, this.conceptUIConfig.codedConceptName),
|
|
nonCodedObservation = findObservationByConceptName(this.groupMembers, this.conceptUIConfig.nonCodedConceptName);
|
|
"object" == typeof newValue ? (setNewObservation(codedObservation, newValue), voidObservation(nonCodedObservation), this.markedAsNonCoded = !1) : (setNewObservation(nonCodedObservation, newValue), voidObservation(codedObservation)), this.onValueChanged(newValue)
|
|
},
|
|
setFirstObservationValue = function(newValue) {
|
|
setNewObservation(this.primaryObs, newValue), this.onValueChanged(newValue)
|
|
};
|
|
Object.defineProperty(this, "value", {
|
|
enumerable: !0,
|
|
get: getPrimaryObservationValue,
|
|
set: isFreeTextAutocompleteType(this.conceptUIConfig) ? setFreeTextPrimaryObservationValue : setFirstObservationValue
|
|
});
|
|
var getFreeTextPrimaryObservation = function() {
|
|
var isAlreadySavedObservation = function(observation) {
|
|
return _.isString(_.get(observation, "value")) && !_.get(observation, "voided")
|
|
},
|
|
codedConceptObservation = findObservationByConceptName(this.groupMembers, this.conceptUIConfig.codedConceptName),
|
|
nonCodedConceptObservation = findObservationByConceptName(this.groupMembers, this.conceptUIConfig.nonCodedConceptName);
|
|
if (isAlreadySavedObservation(nonCodedConceptObservation)) return nonCodedConceptObservation;
|
|
if (!codedConceptObservation) throw new Error("Configuration Error: Concept '" + this.conceptUIConfig.codedConceptName + "' is not a set member of '" + concept.name.name + "'.");
|
|
return codedConceptObservation
|
|
},
|
|
getGroupMembersWithoutClass = function(groupMembers, classNames) {
|
|
return _.filter(groupMembers, function(member) {
|
|
return !(_.includes(classNames, member.concept.conceptClass.name) || _.includes(classNames, member.concept.conceptClass))
|
|
})
|
|
},
|
|
getFirstObservation = function() {
|
|
var observations = getGroupMembersWithoutClass(this.groupMembers, [Bahmni.Common.Constants.abnormalConceptClassName, Bahmni.Common.Constants.unknownConceptClassName, Bahmni.Common.Constants.durationConceptClassName]);
|
|
if (_.isEmpty(observations)) return this.groupMembers[0];
|
|
var primaryObs = observations[1] && observations[1].uuid && !observations[1].voided ? observations[1] : observations[0];
|
|
return observations[0].isMultiSelect ? observations[0] : primaryObs.uuid && !primaryObs.voided ? primaryObs : !observations[1] || !observations[1].value && "" !== observations[1].value || observations[1].voided ? observations[0] : observations[1]
|
|
};
|
|
Object.defineProperty(this, "primaryObs", {
|
|
enumerable: !0,
|
|
get: isFreeTextAutocompleteType(this.conceptUIConfig) ? getFreeTextPrimaryObservation : getFirstObservation
|
|
}), this.isObservationNode = !0, this.uniqueId = _.uniqueId("observation_"), this.durationObs = findObservationByClassName(this.groupMembers, Bahmni.Common.Constants.durationConceptClassName), this.abnormalObs = findObservationByClassName(this.groupMembers, Bahmni.Common.Constants.abnormalConceptClassName), this.unknownObs = findObservationByClassName(this.groupMembers, Bahmni.Common.Constants.unknownConceptClassName), this.markedAsNonCoded = "Coded" !== this.primaryObs.concept.dataType && this.primaryObs.uuid, savedObs ? (this.uuid = savedObs.uuid, this.observationDateTime = savedObs.observationDateTime) : this.value = this.conceptUIConfig.defaultValue
|
|
}, Bahmni.ConceptSet.ObservationNode.prototype = {
|
|
canAddMore: function() {
|
|
return 1 == this.conceptUIConfig.allowAddMore
|
|
},
|
|
isStepperControl: function() {
|
|
return !!this.isNumeric() && 1 == this.conceptUIConfig.stepper
|
|
},
|
|
getPossibleAnswers: function() {
|
|
return this.primaryObs.concept.answers
|
|
},
|
|
getCodedConcept: function() {
|
|
return findObservationByConceptName(this.groupMembers, this.conceptUIConfig.codedConceptName).concept
|
|
},
|
|
onValueChanged: function() {
|
|
!this.primaryObs.hasValue() && this.abnormalObs && (this.abnormalObs.value = void 0, this.abnormalObs.erroneousValue = void 0), this.primaryObs.isNumeric() && this.primaryObs.hasValue() && this.abnormalObs && this.setAbnormal(), this.primaryObs.observationDateTime = null, this.unknownObs && this.setUnknown()
|
|
},
|
|
setAbnormal: function() {
|
|
if (this.primaryObs.hasValue()) {
|
|
var erroneousValue = this.value > (this.primaryObs.concept.hiAbsolute || 1 / 0) || this.value < (this.primaryObs.concept.lowAbsolute || 0),
|
|
valueInRange = this.value <= (this.primaryObs.concept.hiNormal || 1 / 0) && this.value >= (this.primaryObs.concept.lowNormal || 0);
|
|
this.abnormalObs.value = !valueInRange, this.abnormalObs.erroneousValue = erroneousValue
|
|
} else this.abnormalObs.value = void 0, this.abnormalObs.erroneousValue = void 0
|
|
},
|
|
setUnknown: function() {
|
|
this.primaryObs.atLeastOneValueSet() && this.primaryObs.hasValue() ? this.unknownObs.value = !1 : 0 == this.unknownObs.value && (this.unknownObs.value = void 0)
|
|
},
|
|
displayValue: function() {
|
|
if (!(this.possibleAnswers.length > 0)) return this.value;
|
|
for (var i = 0; i < this.possibleAnswers.length; i++)
|
|
if (this.possibleAnswers[i].uuid === this.value) return this.possibleAnswers[i].display
|
|
},
|
|
isGroup: function() {
|
|
return !1
|
|
},
|
|
getControlType: function() {
|
|
return isFreeTextAutocompleteType(this.conceptUIConfig) ? "freeTextAutocomplete" : this.conceptUIConfig.autocomplete ? "autocomplete" : this.isHtml5InputDataType() ? "html5InputDataType" : this.primaryObs.isText() ? "text" : this.conceptUIConfig.dropdown ? "dropdown" : "buttonselect"
|
|
},
|
|
isHtml5InputDataType: function() {
|
|
return ["Date", "Numeric", "Datetime"].indexOf(this.primaryObs.getDataTypeName()) != -1
|
|
},
|
|
_isDateTimeDataType: function() {
|
|
return "Datetime" === this.primaryObs.getDataTypeName()
|
|
},
|
|
isComputed: function() {
|
|
return this.primaryObs.isComputed()
|
|
},
|
|
isConciseText: function() {
|
|
return this.conceptUIConfig.conciseText === !0
|
|
},
|
|
isComputedAndEditable: function() {
|
|
return "Computed/Editable" === this.concept.conceptClass
|
|
},
|
|
atLeastOneValueSet: function() {
|
|
return this.primaryObs.hasValue()
|
|
},
|
|
doesNotHaveDuration: function() {
|
|
return !(!this.durationObs || !this.conceptUIConfig.durationRequired) && (!this.durationObs.value || this.durationObs.value < 0)
|
|
},
|
|
isValid: function(checkRequiredFields, conceptSetRequired) {
|
|
if (this.isNumeric() && (!this.isValidNumeric() || !this.isValidNumericValue())) return !1;
|
|
if (this.isGroup()) return this._hasValidChildren(checkRequiredFields, conceptSetRequired);
|
|
if (checkRequiredFields) {
|
|
if (conceptSetRequired && this.isRequired() && !this.primaryObs.hasValue()) return !1;
|
|
if (this.isRequired() && !this.primaryObs.hasValue()) return !1;
|
|
if ("freeTextAutocomplete" === this.getControlType()) return this.isValidFreeTextAutocomplete()
|
|
}
|
|
return "Date" === this.primaryObs.getDataTypeName() ? this.primaryObs.isValidDate() : (!this.primaryObs.hasValue() || !this.doesNotHaveDuration()) && ((!this.abnormalObs || !this.abnormalObs.erroneousValue) && (this.primaryObs.hasValue() && this.primaryObs._isDateTimeDataType() ? !this.hasInvalidDateTime() : "autocomplete" === this.getControlType() ? _.isEmpty(this.primaryObs.value) || _.isObject(this.primaryObs.value) : !this.primaryObs.hasValue() || !this.primaryObs.erroneousValue))
|
|
},
|
|
isValueInAbsoluteRange: function() {
|
|
return !(this.abnormalObs && this.abnormalObs.erroneousValue)
|
|
},
|
|
isValidFreeTextAutocomplete: function() {
|
|
return !("Coded" !== this.primaryObs.concept.dataType && !this.markedAsNonCoded && this.primaryObs.value)
|
|
},
|
|
isRequired: function() {
|
|
return this.disabled = !!this.disabled && this.disabled, this.conceptUIConfig.required === !0 && this.disabled === !1
|
|
},
|
|
isDurationRequired: function() {
|
|
return !!this.conceptUIConfig.durationRequired && !!this.primaryObs.value
|
|
},
|
|
isNumeric: function() {
|
|
return "Numeric" === this.primaryObs.getDataTypeName()
|
|
},
|
|
isDecimalAllowed: function() {
|
|
return this.primaryObs.concept.allowDecimal
|
|
},
|
|
isValidNumeric: function() {
|
|
return !(!this.isDecimalAllowed() && this.value && this.value.toString().indexOf(".") >= 0)
|
|
},
|
|
isValidNumericValue: function() {
|
|
var element = document.getElementById(this.uniqueId);
|
|
return "" !== this.value || !element || element.checkValidity()
|
|
},
|
|
_hasValidChildren: function(checkRequiredFields, conceptSetRequired) {
|
|
return this.groupMembers.every(function(member) {
|
|
return member.isValid(checkRequiredFields, conceptSetRequired)
|
|
})
|
|
},
|
|
markAsNonCoded: function() {
|
|
this.markedAsNonCoded = !this.markedAsNonCoded
|
|
},
|
|
toggleAbnormal: function() {
|
|
this.abnormalObs.value = !this.abnormalObs.value
|
|
},
|
|
toggleUnknown: function() {
|
|
this.unknownObs.value ? this.unknownObs.value = void 0 : this.unknownObs.value = !0
|
|
},
|
|
assignAddMoreButtonID: function() {
|
|
return this.concept.name.split(" ").join("_").toLowerCase() + "_addmore_" + this.uniqueId
|
|
},
|
|
canHaveComment: function() {
|
|
return !this.conceptUIConfig.disableAddNotes || !this.conceptUIConfig.disableAddNotes
|
|
},
|
|
hasInvalidDateTime: function() {
|
|
if (this.isComputed()) return !1;
|
|
var date = Bahmni.Common.Util.DateUtil.parse(this.value);
|
|
return !this.conceptUIConfig.allowFutureDates && moment() < date || "Invalid Datetime" === this.value
|
|
}
|
|
}
|
|
}(), Bahmni.ConceptSet.TabularObservations = function(obsGroups, parentObs, conceptUIConfig) {
|
|
this.parentObs = parentObs, this.concept = obsGroups[0] && obsGroups[0].concept, this.label = obsGroups[0] && obsGroups[0].label, this.conceptUIConfig = conceptUIConfig[this.concept.name] || {}, this.isTabularObs = !0, this.rows = _.map(obsGroups, function(group) {
|
|
return new Bahmni.ConceptSet.ObservationRow(group, conceptUIConfig)
|
|
}), this.columns = _.map(obsGroups[0].groupMembers, function(group) {
|
|
return group.concept
|
|
}), this.cloneNew = function() {
|
|
var old = this,
|
|
clone = new Bahmni.ConceptSet.TabularObservations(angular.copy(obsGroups), parentObs, conceptUIConfig);
|
|
return clone.rows = _.map(old.rows, function(row) {
|
|
return row.cloneNew()
|
|
}), clone.disabled = this.disabled, clone
|
|
}, this.addNew = function(row) {
|
|
var newRow = row.cloneNew();
|
|
this.rows.push(newRow), this.parentObs.groupMembers.push(newRow.obsGroup)
|
|
}, this.remove = function(row) {
|
|
row["void"](), this.rows.splice(this.rows.indexOf(row), 1), 0 == this.rows.length && this.addNew(row)
|
|
}, this.isFormElement = function() {
|
|
return !1
|
|
}, this.getControlType = function() {
|
|
return "tabular"
|
|
}, this.isValid = function(checkRequiredFields, conceptSetRequired) {
|
|
return _.every(this.rows, function(observationRow) {
|
|
return _.every(observationRow.cells, function(conceptSetObservation) {
|
|
return conceptSetObservation.isValid(checkRequiredFields, conceptSetRequired)
|
|
})
|
|
})
|
|
}, this.getConceptUIConfig = function() {
|
|
return this.conceptUIConfig || {}
|
|
}, this.canAddMore = function() {
|
|
return 1 == this.getConceptUIConfig().allowAddMore
|
|
}, this.atLeastOneValueSet = function() {
|
|
return this.rows.some(function(childNode) {
|
|
return childNode.obsGroup.atLeastOneValueSet()
|
|
})
|
|
}, this.isNumeric = function() {
|
|
return "Numeric" === this.concept.dataType
|
|
}, this.isValidNumericValue = function() {
|
|
var element = document.getElementById(this.uniqueId);
|
|
return "" !== this.value || !element || element.checkValidity()
|
|
}
|
|
}, Bahmni.ConceptSet.ObservationRow = function(obsGroup, conceptUIConfig) {
|
|
this.obsGroup = obsGroup, this.concept = obsGroup.concept, this.cells = obsGroup.groupMembers, this["void"] = function() {
|
|
this.obsGroup.voided = !0
|
|
}, this.cloneNew = function() {
|
|
var newObsGroup = this.obsGroup.cloneNew();
|
|
newObsGroup.hidden = !0;
|
|
var clone = new Bahmni.ConceptSet.ObservationRow(newObsGroup, conceptUIConfig);
|
|
return clone.disabled = this.disabled, clone
|
|
}
|
|
}, Bahmni.ConceptSet.CustomRepresentationBuilder = {
|
|
build: function(fields, childPropertyName, numberOfLevels) {
|
|
for (var childPropertyRep = childPropertyName + ":{{entity_fileds}}", singleEntityString = "(" + fields.concat(childPropertyRep).join(",") + ")", customRepresentation = singleEntityString, i = 0; i < numberOfLevels; i++) customRepresentation = customRepresentation.replace("{{entity_fileds}}", singleEntityString);
|
|
return customRepresentation = customRepresentation.replace("," + childPropertyRep, "")
|
|
}
|
|
}, Bahmni.ObservationForm = function(formUuid, user, formName, formVersion, observations, extension) {
|
|
function hide() {
|
|
self.isOpen = !1
|
|
}
|
|
|
|
function show() {
|
|
self.isOpen = !0
|
|
}
|
|
var self = this,
|
|
init = function() {
|
|
self.formUuid = formUuid, self.formVersion = formVersion, self.formName = formName, self.label = formName, self.conceptName = formName, self.collapseInnerSections = {
|
|
value: !1
|
|
}, self.alwaysShow = user.isFavouriteObsTemplate(self.conceptName), self.observations = [], _.each(observations, function(observation) {
|
|
var observationFormField = observation.formFieldPath ? observation.formFieldPath.split("/")[0].split(".") : null;
|
|
observationFormField && observationFormField[0] === formName && observationFormField[1] === formVersion && self.observations.push(observation)
|
|
}), self.isOpen = self.observations.length > 0, self.id = "concept-set-" + formUuid, self.options = extension ? extension.extensionParams || {} : {}
|
|
};
|
|
self.toggleDisplay = function() {
|
|
self.isOpen ? hide() : show()
|
|
}, self.clone = function() {
|
|
var clonedObservationFormSection = new Bahmni.ObservationForm(self.formUuid, user, self.formName, self.formVersion, []);
|
|
return clonedObservationFormSection.isOpen = !0, clonedObservationFormSection
|
|
}, self.isAvailable = function(context) {
|
|
return !0
|
|
}, self.show = function() {
|
|
self.isOpen = !0, self.isLoaded = !0
|
|
}, self.toggle = function() {
|
|
self.added = !self.added, self.added && self.show()
|
|
}, self.hasSomeValue = function() {
|
|
var observations = self.getObservationsForConceptSection();
|
|
return _.some(observations, function(observation) {
|
|
return atLeastOneValueSet(observation)
|
|
})
|
|
}, self.getObservationsForConceptSection = function() {
|
|
return self.observations.filter(function(observation) {
|
|
return observation.formFieldPath.split(".")[0] === self.formName
|
|
})
|
|
};
|
|
var atLeastOneValueSet = function(observation) {
|
|
return observation.groupMembers && observation.groupMembers.length > 0 ? observation.groupMembers.some(function(groupMember) {
|
|
return atLeastOneValueSet(groupMember)
|
|
}) : !(_.isUndefined(observation.value) || "" === observation.value)
|
|
};
|
|
self.isDefault = function() {
|
|
return !1
|
|
}, Object.defineProperty(self, "isAdded", {
|
|
get: function() {
|
|
return self.hasSomeValue() && (self.added = !0), self.added
|
|
},
|
|
set: function(value) {
|
|
self.added = value
|
|
}
|
|
}), self.maximizeInnerSections = function(event) {
|
|
event.stopPropagation(), self.collapseInnerSections = {
|
|
value: !1
|
|
}
|
|
}, self.minimizeInnerSections = function(event) {
|
|
event.stopPropagation(), self.collapseInnerSections = {
|
|
value: !0
|
|
}
|
|
}, init()
|
|
}, Bahmni.ConceptSet.ObservationMapper = function() {
|
|
function mapTabularObs(mappedGroupMembers, concept, obs, conceptSetConfig) {
|
|
var tabularObsGroups = _.filter(mappedGroupMembers, function(member) {
|
|
return conceptSetConfig[member.concept.name] && conceptSetConfig[member.concept.name].isTabular
|
|
});
|
|
if (tabularObsGroups.length > 0) {
|
|
var array = _.map(concept.setMembers, function(member) {
|
|
return member.name.name
|
|
});
|
|
tabularObsGroups.forEach(function(group) {
|
|
group.hidden = !0
|
|
});
|
|
var groupedObsGroups = _.groupBy(tabularObsGroups, function(group) {
|
|
return group.concept.name
|
|
});
|
|
_.values(groupedObsGroups).forEach(function(groups) {
|
|
var tabularObservations = new Bahmni.ConceptSet.TabularObservations(groups, obs, conceptSetConfig);
|
|
obs.groupMembers.push(tabularObservations)
|
|
});
|
|
var sortedGroupMembers = _.sortBy(obs.groupMembers, function(observation) {
|
|
return array.indexOf(observation.concept.name)
|
|
});
|
|
obs.groupMembers.length = 0, obs.groupMembers.push.apply(obs.groupMembers, sortedGroupMembers)
|
|
}
|
|
}
|
|
|
|
function buildObservation(concept, savedObs, mappedGroupMembers) {
|
|
var comment = savedObs ? savedObs.comment : null;
|
|
return {
|
|
concept: conceptMapper.map(concept),
|
|
units: concept.units,
|
|
label: getLabel(concept),
|
|
possibleAnswers: concept.answers,
|
|
groupMembers: mappedGroupMembers,
|
|
comment: comment,
|
|
showAddMoreButton: showAddMoreButton
|
|
}
|
|
}
|
|
var conceptMapper = new Bahmni.Common.Domain.ConceptMapper,
|
|
self = this;
|
|
this.getObservationsForView = function(observations, conceptSetConfig) {
|
|
return internalMapForDisplay(observations, conceptSetConfig)
|
|
};
|
|
var internalMapForDisplay = function(observations, conceptSetConfig) {
|
|
var observationsForDisplay = [];
|
|
return _.forEach(observations, function(savedObs) {
|
|
if (!savedObs.concept.conceptClass || savedObs.concept.conceptClass !== Bahmni.Common.Constants.conceptDetailsClassName && savedObs.concept.conceptClass.name !== Bahmni.Common.Constants.conceptDetailsClassName)
|
|
if (savedObs.concept.set)
|
|
if (conceptSetConfig[savedObs.concept.name] && conceptSetConfig[savedObs.concept.name].grid) savedObs.value = self.getGridObservationDisplayValue(savedObs), observationsForDisplay = observationsForDisplay.concat(createObservationForDisplay(savedObs, savedObs.concept));
|
|
else {
|
|
var groupMemberObservationsForDisplay = internalMapForDisplay(savedObs.groupMembers, conceptSetConfig);
|
|
observationsForDisplay = observationsForDisplay.concat(groupMemberObservationsForDisplay)
|
|
}
|
|
else {
|
|
var obsToDisplay = null;
|
|
if (savedObs.isMultiSelect) obsToDisplay = savedObs;
|
|
else if (!savedObs.hidden) {
|
|
var observation = newObservation(savedObs.concept, savedObs, []);
|
|
obsToDisplay = createObservationForDisplay(observation, observation.concept)
|
|
}
|
|
obsToDisplay && observationsForDisplay.push(obsToDisplay)
|
|
} else {
|
|
var observationNode = new Bahmni.ConceptSet.ObservationNode(savedObs, savedObs, [], savedObs.concept),
|
|
obsToDisplay = createObservationForDisplay(observationNode, observationNode.primaryObs.concept);
|
|
obsToDisplay && observationsForDisplay.push(obsToDisplay)
|
|
}
|
|
}), observationsForDisplay
|
|
};
|
|
this.map = function(observations, rootConcept, conceptSetConfig) {
|
|
var savedObs = findInSavedObservation(rootConcept, observations)[0];
|
|
return mapObservation(rootConcept, savedObs, conceptSetConfig || {})
|
|
};
|
|
var findInSavedObservation = function(concept, observations) {
|
|
return _.filter(observations, function(obs) {
|
|
return obs && obs.concept && concept.uuid === obs.concept.uuid
|
|
})
|
|
},
|
|
mapObservation = function(concept, savedObs, conceptSetConfig) {
|
|
var obs = null;
|
|
if (savedObs && (savedObs.isObservation || savedObs.isObservationNode)) return savedObs;
|
|
var mappedGroupMembers = concept && concept.set ? mapObservationGroupMembers(savedObs ? savedObs.groupMembers : [], concept, conceptSetConfig) : [];
|
|
return concept.conceptClass.name === Bahmni.Common.Constants.conceptDetailsClassName ? obs = newObservationNode(concept, savedObs, conceptSetConfig, mappedGroupMembers) : (obs = newObservation(concept, savedObs, conceptSetConfig, mappedGroupMembers), new Bahmni.ConceptSet.MultiSelectObservations(conceptSetConfig).map(mappedGroupMembers)), mapTabularObs(mappedGroupMembers, concept, obs, conceptSetConfig), obs
|
|
},
|
|
mapObservationGroupMembers = function(observations, parentConcept, conceptSetConfig) {
|
|
var observationGroupMembers = [],
|
|
conceptSetMembers = parentConcept.setMembers;
|
|
return conceptSetMembers.forEach(function(memberConcept) {
|
|
for (var savedObservations = findInSavedObservation(memberConcept, observations), configForConcept = conceptSetConfig[memberConcept.name.name] || {}, numberOfNodes = configForConcept.multiple || 1, i = savedObservations.length - 1; i >= 0; i--) observationGroupMembers.push(mapObservation(memberConcept, savedObservations[i], conceptSetConfig));
|
|
for (var i = 0; i < numberOfNodes - savedObservations.length; i++) observationGroupMembers.push(mapObservation(memberConcept, null, conceptSetConfig))
|
|
}), observationGroupMembers
|
|
},
|
|
getDatatype = function(concept) {
|
|
return concept.dataType ? concept.dataType : concept.datatype && concept.datatype.name
|
|
},
|
|
newObservation = function(concept, savedObs, conceptSetConfig, mappedGroupMembers) {
|
|
var observation = buildObservation(concept, savedObs, mappedGroupMembers),
|
|
obs = new Bahmni.ConceptSet.Observation(observation, savedObs, conceptSetConfig, mappedGroupMembers);
|
|
return "Boolean" == getDatatype(concept) && (obs = new Bahmni.ConceptSet.BooleanObservation(obs, conceptSetConfig)), obs
|
|
},
|
|
newObservationNode = function(concept, savedObsNode, conceptSetConfig, mappedGroupMembers) {
|
|
var observation = buildObservation(concept, savedObsNode, mappedGroupMembers);
|
|
return new Bahmni.ConceptSet.ObservationNode(observation, savedObsNode, conceptSetConfig, concept)
|
|
},
|
|
showAddMoreButton = function(rootObservation) {
|
|
var observation = this,
|
|
lastObservationByLabel = _.findLast(rootObservation.groupMembers, {
|
|
label: observation.label
|
|
});
|
|
return lastObservationByLabel.uuid === observation.uuid
|
|
},
|
|
createObservationForDisplay = function(observation, concept) {
|
|
if (null != observation.value) {
|
|
var observationValue = getObservationDisplayValue(observation);
|
|
return observationValue = observation.durationObs ? observationValue + " " + getDurationDisplayValue(observation.durationObs) : observationValue, {
|
|
value: observationValue,
|
|
abnormalObs: observation.abnormalObs,
|
|
duration: observation.durationObs,
|
|
provider: observation.provider,
|
|
label: getLabel(observation.concept),
|
|
observationDateTime: observation.observationDateTime,
|
|
concept: concept,
|
|
comment: observation.comment,
|
|
uuid: observation.uuid
|
|
}
|
|
}
|
|
},
|
|
getObservationDisplayValue = function(observation) {
|
|
if (observation.isBoolean || "Boolean" === observation.type) return observation.value === !0 ? "Yes" : "No";
|
|
if (!observation.value) return "";
|
|
if ("object" == typeof observation.value.name) {
|
|
var valueConcept = conceptMapper.map(observation.value);
|
|
return valueConcept.shortName || valueConcept.name
|
|
}
|
|
return observation.value.shortName || observation.value.name || observation.value
|
|
},
|
|
getDurationDisplayValue = function(duration) {
|
|
var durationForDisplay = Bahmni.Common.Util.DateUtil.convertToUnits(duration.value);
|
|
return durationForDisplay.value && durationForDisplay.unitName ? "since " + durationForDisplay.value + " " + durationForDisplay.unitName : ""
|
|
};
|
|
this.getGridObservationDisplayValue = function(observation) {
|
|
var memberValues = _.compact(_.map(observation.groupMembers, function(member) {
|
|
return getObservationDisplayValue(member)
|
|
}));
|
|
return memberValues.join(", ")
|
|
};
|
|
var getLabel = function(concept) {
|
|
var mappedConcept = conceptMapper.map(concept);
|
|
return mappedConcept.shortName || mappedConcept.name
|
|
}
|
|
}, angular.module("bahmni.common.conceptSet").factory("conceptService", ["$q", "$http", function($q, $http) {
|
|
var conceptMapper = new Bahmni.Common.Domain.ConceptMapper,
|
|
mapConceptOrGetDrug = function(conceptAnswer) {
|
|
return conceptAnswer.concept && conceptMapper.map(conceptAnswer.concept) || conceptAnswer.drug
|
|
},
|
|
getAnswersForConceptName = function(request) {
|
|
var params = {
|
|
q: request.term,
|
|
question: request.answersConceptName,
|
|
v: "custom:(concept:(uuid,name:(display,uuid,name,conceptNameType),names:(display,uuid,name,conceptNameType)),drug:(uuid,name,display))",
|
|
s: "byQuestion"
|
|
};
|
|
return $http.get(Bahmni.Common.Constants.bahmniConceptAnswerUrl, {
|
|
params: params
|
|
}).then(_.partial(_.get, _, "data.results")).then(function(conceptAnswers) {
|
|
return _(conceptAnswers).map(mapConceptOrGetDrug).uniqBy("uuid").value()
|
|
})
|
|
},
|
|
getAnswers = function(defaultConcept) {
|
|
var deferred = $q.defer(),
|
|
response = _(defaultConcept.answers).uniqBy("uuid").map(conceptMapper.map).value();
|
|
return deferred.resolve(response), deferred.promise
|
|
};
|
|
return {
|
|
getAnswersForConceptName: getAnswersForConceptName,
|
|
getAnswers: getAnswers
|
|
}
|
|
}]), angular.module("bahmni.common.conceptSet").factory("conceptSetUiConfigService", ["$http", "$q", "appService", function($http, $q, appService) {
|
|
var setConceptUuidInsteadOfName = function(config, conceptNameField, uuidField) {
|
|
var conceptName = config[conceptNameField];
|
|
if (null != conceptName) return $http.get(Bahmni.Common.Constants.conceptSearchByFullNameUrl, {
|
|
params: {
|
|
name: conceptName,
|
|
v: "custom:(uuid,name)"
|
|
}
|
|
}).then(function(response) {
|
|
var concept = response.data.results.filter(function(c) {
|
|
return c.name.name === conceptName
|
|
});
|
|
concept.length > 0 && (config[uuidField] = concept[0].uuid)
|
|
})
|
|
},
|
|
setExtraData = function(config) {
|
|
Object.getOwnPropertyNames(config).forEach(function(conceptConfigKey) {
|
|
var conceptConfig = config[conceptConfigKey];
|
|
conceptConfig.freeTextAutocomplete instanceof Object && (setConceptUuidInsteadOfName(conceptConfig.freeTextAutocomplete, "codedConceptName", "codedConceptUuid"), setConceptUuidInsteadOfName(conceptConfig.freeTextAutocomplete, "conceptSetName", "conceptSetUuid"))
|
|
})
|
|
},
|
|
getConfig = function() {
|
|
var config = appService.getAppDescriptor().getConfigValue("conceptSetUI") || {};
|
|
return setExtraData(config), config
|
|
};
|
|
return {
|
|
getConfig: getConfig
|
|
}
|
|
}]), angular.module("bahmni.common.conceptSet").directive("imageUpload", ["visitDocumentService", "messagingService", "spinner", function(visitDocumentService, messagingService, spinner) {
|
|
var link = function(scope, element) {
|
|
element.bind("change", function() {
|
|
var file = element[0].files[0],
|
|
reader = new FileReader;
|
|
reader.onload = function(event) {
|
|
var image = event.target.result,
|
|
fileType = scope.fileType || visitDocumentService.getFileType(file.type);
|
|
"not_supported" !== fileType ? spinner.forPromise(visitDocumentService.saveFile(image, scope.patientUuid, void 0, file.name, fileType).then(function(response) {
|
|
scope.url = response.data.url, element.val(null), "video" !== fileType && (scope.observation.conceptUIConfig.required = !1, cloneNew(scope.observation, scope.rootObservation))
|
|
})) : (messagingService.showMessage("error", "File type is not supported"), scope.$$phase || scope.$apply())
|
|
}, reader.readAsDataURL(file)
|
|
});
|
|
var cloneNew = function(observation, parentObservation) {
|
|
var newObs = observation.cloneNew();
|
|
newObs.scrollToElement = !0;
|
|
var index = parentObservation.groupMembers.indexOf(observation);
|
|
parentObservation.groupMembers.splice(index + 1, 0, newObs), messagingService.showMessage("info", "A new " + observation.label + " section has been added"), scope.$root.$broadcast("event:addMore", newObs)
|
|
}
|
|
};
|
|
return {
|
|
restrict: "A",
|
|
require: "ngModel",
|
|
scope: {
|
|
url: "=ngModel",
|
|
patientUuid: "=",
|
|
fileType: "=",
|
|
observation: "=",
|
|
rootObservation: "="
|
|
},
|
|
link: link
|
|
}
|
|
}]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.Logging = Bahmni.Common.Logging || {}, angular.module("bahmni.common.logging", []), angular.module("bahmni.common.logging").config(["$provide", function($provide) {
|
|
$provide.decorator("$exceptionHandler", function($delegate, $injector, $window, $log) {
|
|
var logError = function(exception, cause) {
|
|
try {
|
|
var messagingService = $injector.get("messagingService"),
|
|
loggingService = $injector.get("loggingService"),
|
|
errorMessage = exception.toString(),
|
|
stackTrace = printStackTrace({
|
|
e: exception
|
|
}),
|
|
errorDetails = {
|
|
timestamp: new Date,
|
|
browser: $window.navigator.userAgent,
|
|
errorUrl: $window.location.href,
|
|
errorMessage: errorMessage,
|
|
stackTrace: stackTrace,
|
|
cause: cause || ""
|
|
};
|
|
loggingService.log(errorDetails), messagingService.showMessage("error", errorMessage), exposeException(errorDetails)
|
|
} catch (loggingError) {
|
|
$log.warn("Error logging failed"), $log.log(loggingError)
|
|
}
|
|
},
|
|
exposeException = function(exceptionDetails) {
|
|
window.angular_exception = window.angular_exception || [], window.angular_exception.push(exceptionDetails)
|
|
};
|
|
return function(exception, cause) {
|
|
$delegate(exception, cause), logError(exception, cause)
|
|
}
|
|
})
|
|
}]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.Obs = Bahmni.Common.Obs || {}, angular.module("bahmni.common.obs", []), Bahmni.Common.Obs.Observation = function() {
|
|
var Observation = function(obs, conceptConfig) {
|
|
angular.extend(this, obs), this.concept = obs.concept, this.conceptConfig = conceptConfig
|
|
};
|
|
return Observation.prototype = {
|
|
isFormElement: function() {
|
|
return this.groupMembers && this.groupMembers.length <= 0
|
|
},
|
|
isImageConcept: function() {
|
|
return "Image" === this.concept.conceptClass
|
|
},
|
|
isVideoConcept: function() {
|
|
return "Video" === this.concept.conceptClass
|
|
},
|
|
hasPDFAsValue: function() {
|
|
return this.value.indexOf(".pdf") > 0
|
|
},
|
|
isComplexConcept: function() {
|
|
return "Complex" === this.concept.dataType
|
|
},
|
|
getComplexDataType: function() {
|
|
return this.complexData ? this.complexData.dataType : null
|
|
},
|
|
isLocationRef: function() {
|
|
return this.isComplexConcept() && "Location" === this.getComplexDataType()
|
|
},
|
|
isProviderRef: function() {
|
|
return this.isComplexConcept() && "Provider" === this.getComplexDataType()
|
|
},
|
|
getDisplayValue: function() {
|
|
var value;
|
|
if ("Boolean" === this.type || this.concept && "Boolean" === this.concept.dataType) return this.value === !0 ? "OBS_BOOLEAN_YES_KEY" : "OBS_BOOLEAN_NO_KEY";
|
|
if ("Datetime" === this.type || this.concept && "Datetime" === this.concept.dataType) {
|
|
var date = Bahmni.Common.Util.DateUtil.parseDatetime(this.value);
|
|
return null != date ? Bahmni.Common.Util.DateUtil.formatDateWithTime(date) : ""
|
|
}
|
|
if (this.conceptConfig && this.conceptConfig.displayMonthAndYear && (value = Bahmni.Common.Util.DateUtil.getDateInMonthsAndYears(this.value), null != value)) return value;
|
|
if ("Date" === this.type || this.concept && "Date" === this.concept.dataType) return this.value ? Bahmni.Common.Util.DateUtil.formatDateWithoutTime(this.value) : "";
|
|
if (this.isLocationRef()) return this.complexData.display;
|
|
if (this.isProviderRef()) return this.complexData.display;
|
|
value = this.value;
|
|
var displayValue = value && (value.shortName || value.name && (value.name.name || value.name) || value);
|
|
return this.duration && (displayValue = displayValue + " " + this.getDurationDisplayValue()), displayValue
|
|
},
|
|
getDurationDisplayValue: function() {
|
|
var durationForDisplay = Bahmni.Common.Util.DateUtil.convertToUnits(this.duration);
|
|
return "since " + durationForDisplay.value + " " + durationForDisplay.unitName
|
|
}
|
|
}, Observation
|
|
}(), Bahmni.Common.Obs.MultiSelectObservation = function() {
|
|
var MultiSelectObservation = function(groupMembers, conceptConfig) {
|
|
this.type = "multiSelect", this.concept = groupMembers[0].concept, this.encounterDateTime = groupMembers[0].encounterDateTime, this.groupMembers = groupMembers, this.conceptConfig = conceptConfig, this.observationDateTime = getLatestObservationDateTime(this.groupMembers), this.providers = groupMembers[0].providers, this.creatorName = groupMembers[0].creatorName
|
|
},
|
|
getLatestObservationDateTime = function(groupMembers) {
|
|
var latestObservationDateTime = groupMembers[0].observationDateTime;
|
|
return groupMembers.forEach(function(member) {
|
|
latestObservationDateTime = latestObservationDateTime < member.observationDateTime ? member.observationDateTime : latestObservationDateTime
|
|
}), latestObservationDateTime
|
|
};
|
|
return MultiSelectObservation.prototype = {
|
|
isFormElement: function() {
|
|
return !0
|
|
},
|
|
getDisplayValue: function() {
|
|
var getName = Bahmni.Common.Domain.ObservationValueMapper.getNameFor.Object;
|
|
return _.map(this.groupMembers, getName).join(", ")
|
|
}
|
|
}, MultiSelectObservation
|
|
}(), Bahmni.Common.Obs.GridObservation = function() {
|
|
var conceptMapper = new Bahmni.Common.Domain.ConceptMapper,
|
|
GridObservation = function(obs, conceptConfig) {
|
|
angular.extend(this, obs), this.type = "grid", this.conceptConfig = conceptConfig
|
|
},
|
|
getObservationDisplayValue = function(observation) {
|
|
if (observation.isBoolean || "Boolean" === observation.type) return observation.value === !0 ? "OBS_BOOLEAN_YES_KEY" : "OBS_BOOLEAN_NO_KEY";
|
|
if (!observation.value) return "";
|
|
if ("object" == typeof observation.value.name) {
|
|
var valueConcept = conceptMapper.map(observation.value);
|
|
return valueConcept.shortName || valueConcept.name
|
|
}
|
|
return observation.value.shortName || observation.value.name || observation.value
|
|
};
|
|
return GridObservation.prototype = {
|
|
isFormElement: function() {
|
|
return !0
|
|
},
|
|
getDisplayValue: function() {
|
|
var gridObservationDisplayValue = _.compact(_.map(this.groupMembers, function(member) {
|
|
return getObservationDisplayValue(member)
|
|
})).join(", ");
|
|
return gridObservationDisplayValue || this.value
|
|
}
|
|
}, GridObservation
|
|
}(), Bahmni.Common.Obs.ImageObservation = function(observation, concept, provider) {
|
|
this.concept = concept, this.imageObservation = observation, this.dateTime = observation.observationDateTime, this.provider = provider
|
|
}, Bahmni.Common.Obs.ObservationMapper = function() {
|
|
var conceptMapper = new Bahmni.Common.Domain.ConceptMapper;
|
|
this.map = function(bahmniObservations, allConceptsConfig, dontSortByObsDateTime) {
|
|
var mappedObservations = mapObservations(bahmniObservations, allConceptsConfig, dontSortByObsDateTime);
|
|
return mapUIObservations(mappedObservations, allConceptsConfig)
|
|
};
|
|
var mapObservations = function(bahmniObservations, allConceptsConfig, dontSortByObsDateTime) {
|
|
var mappedObservations = [];
|
|
return bahmniObservations = dontSortByObsDateTime ? _.flatten(bahmniObservations) : Bahmni.Common.Obs.ObservationUtil.sortSameConceptsWithObsDateTime(bahmniObservations), $.each(bahmniObservations, function(i, bahmniObservation) {
|
|
var conceptConfig = allConceptsConfig[bahmniObservation.concept.name] || [],
|
|
observation = new Bahmni.Common.Obs.Observation(bahmniObservation, conceptConfig);
|
|
observation.groupMembers && observation.groupMembers.length >= 0 && (observation.groupMembers = mapObservations(observation.groupMembers, allConceptsConfig, dontSortByObsDateTime)), mappedObservations.push(observation)
|
|
}), mappedObservations
|
|
},
|
|
mapUIObservations = function(observations, allConceptsConfig) {
|
|
var groupedObservations = _.groupBy(observations, function(observation) {
|
|
return observation.concept.name
|
|
}),
|
|
mappedObservations = [];
|
|
return $.each(groupedObservations, function(i, obsGroup) {
|
|
var conceptConfig = allConceptsConfig[obsGroup[0].concept.name] || [];
|
|
if (conceptConfig.multiSelect) {
|
|
var multiSelectObservations = {};
|
|
$.each(obsGroup, function(i, observation) {
|
|
if (multiSelectObservations[observation.encounterDateTime]) multiSelectObservations[observation.encounterDateTime].push(observation);
|
|
else {
|
|
var observations = [];
|
|
observations.push(observation), multiSelectObservations[observation.encounterDateTime] = observations
|
|
}
|
|
}), $.each(multiSelectObservations, function(i, observations) {
|
|
mappedObservations.push(new Bahmni.Common.Obs.MultiSelectObservation(observations, conceptConfig))
|
|
})
|
|
} else conceptConfig.grid ? mappedObservations.push(new Bahmni.Common.Obs.GridObservation(obsGroup[0], conceptConfig)) : $.each(obsGroup, function(i, obs) {
|
|
obs.groupMembers = mapUIObservations(obs.groupMembers, allConceptsConfig), mappedObservations.push(obs)
|
|
})
|
|
}), mappedObservations
|
|
};
|
|
this.getGridObservationDisplayValue = function(observationTemplate) {
|
|
var memberValues = _.compact(_.map(observationTemplate.bahmniObservations, function(observation) {
|
|
return getObservationDisplayValue(observation)
|
|
}));
|
|
return memberValues.join(", ")
|
|
};
|
|
var getObservationDisplayValue = function(observation) {
|
|
if (observation.isBoolean || "Boolean" === observation.type) return observation.value === !0 ? "Yes" : "No";
|
|
if (!observation.value) return "";
|
|
if ("object" == typeof observation.value.name) {
|
|
var valueConcept = conceptMapper.map(observation.value);
|
|
return valueConcept.shortName || valueConcept.name
|
|
}
|
|
return observation.value.shortName || observation.value.name || observation.value
|
|
}
|
|
}, Bahmni.Common.Obs.ObservationUtil = function() {
|
|
var sortSameConceptsWithObsDateTime = function(observation) {
|
|
for (var sortedObservations = [], i = 0; i < observation.length; i++)
|
|
if (i !== observation.length - 1)
|
|
if (observation[i].conceptUuid !== observation[i + 1].conceptUuid) sortedObservations.push(observation[i]);
|
|
else {
|
|
var sameConceptsSubArray = [],
|
|
j = i + 1;
|
|
for (sameConceptsSubArray.push(observation[i]); j < observation.length && observation[i].conceptUuid === observation[j].conceptUuid;) sameConceptsSubArray.push(observation[j++]);
|
|
sameConceptsSubArray = _.sortBy(sameConceptsSubArray, "observationDateTime"), sortedObservations.push(sameConceptsSubArray), i = j - 1
|
|
}
|
|
else sortedObservations.push(observation[i]);
|
|
return _.flatten(sortedObservations)
|
|
},
|
|
getValue = function(observation) {
|
|
if (observation.selectedObs) return observation.getValues();
|
|
var obsValue;
|
|
return obsValue = observation.value && observation.value.name && observation.value.name.name ? observation.value.name.name : observation.value && observation.value.name && !observation.value.name.name ? observation.value.name : observation.value, void 0 === obsValue || null === obsValue ? obsValue : obsValue.displayString || obsValue
|
|
},
|
|
collect = function(flattenedObservations, key, value) {
|
|
void 0 != value && (flattenedObservations[key] = flattenedObservations[key] ? _.uniq(_.flatten(_.union([flattenedObservations[key]], [value]))) : value)
|
|
},
|
|
findLeafObservations = function(flattenedObservations, observation) {
|
|
_.isEmpty(observation.groupMembers) ? collect(flattenedObservations, observation.concept.name, getValue(observation)) : _.each(observation.groupMembers, function(member) {
|
|
findLeafObservations(flattenedObservations, member)
|
|
})
|
|
},
|
|
flatten = function(observation) {
|
|
var flattenedObservation = {};
|
|
return _.isEmpty(observation) || findLeafObservations(flattenedObservation, observation), flattenedObservation
|
|
},
|
|
flattenObsToArray = function(observations) {
|
|
var flattened = [];
|
|
return flattened.push.apply(flattened, observations), observations.forEach(function(obs) {
|
|
obs.groupMembers && obs.groupMembers.length > 0 && flattened.push.apply(flattened, flattenObsToArray(obs.groupMembers))
|
|
}), flattened
|
|
};
|
|
return {
|
|
sortSameConceptsWithObsDateTime: sortSameConceptsWithObsDateTime,
|
|
flatten: flatten,
|
|
flattenObsToArray: flattenObsToArray
|
|
}
|
|
}(), angular.module("bahmni.common.obs").directive("showObservation", ["ngDialog", function(ngDialog) {
|
|
var controller = function($scope, $rootScope, $filter) {
|
|
$scope.toggle = function(observation) {
|
|
observation.showDetails = !observation.showDetails
|
|
}, $scope.print = $rootScope.isBeingPrinted || !1, $scope.dateString = function(observation) {
|
|
var filterName;
|
|
if ($scope.showDate && $scope.showTime) filterName = "bahmniDateTime";
|
|
else {
|
|
if ($scope.showDate || !$scope.showTime && void 0 !== $scope.showTime) return null;
|
|
filterName = "bahmniTime"
|
|
}
|
|
return $filter(filterName)(observation.observationDateTime)
|
|
}, $scope.openVideoInPopup = function(observation) {
|
|
ngDialog.open({
|
|
template: "../common/obs/views/showVideo.html",
|
|
closeByDocument: !1,
|
|
className: "ngdialog-theme-default",
|
|
showClose: !0,
|
|
data: {
|
|
observation: observation
|
|
}
|
|
})
|
|
}
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
scope: {
|
|
observation: "=?",
|
|
patient: "=",
|
|
showDate: "=?",
|
|
showTime: "=?",
|
|
showDetailsButton: "=?"
|
|
},
|
|
controller: controller,
|
|
template: "<ng-include src=\"'../common/obs/views/showObservation.html'\" />"
|
|
}
|
|
}]), angular.module("bahmni.common.obs").directive("editObservation", ["$q", "spinner", "$state", "$rootScope", "ngDialog", "messagingService", "encounterService", "configurations", "contextChangeHandler", "auditLogService", function($q, spinner, $state, $rootScope, ngDialog, messagingService, encounterService, configurations, contextChangeHandler, auditLogService) {
|
|
var controller = function($scope) {
|
|
var ObservationUtil = Bahmni.Common.Obs.ObservationUtil,
|
|
findEditableObs = function(observations) {
|
|
return _.find(observations, function(obs) {
|
|
return obs.uuid === $scope.observation.uuid
|
|
})
|
|
},
|
|
shouldEditSpecificObservation = function() {
|
|
return !!$scope.observation.uuid
|
|
},
|
|
contextChange = function() {
|
|
return contextChangeHandler.execute()
|
|
},
|
|
init = function() {
|
|
var consultationMapper = new Bahmni.ConsultationMapper(configurations.dosageFrequencyConfig(), configurations.dosageInstructionConfig(), configurations.consultationNoteConcept(), configurations.labOrderNotesConcept());
|
|
return encounterService.findByEncounterUuid($scope.observation.encounterUuid).then(function(reponse) {
|
|
var encounterTransaction = reponse.data;
|
|
if ($scope.encounter = consultationMapper.map(encounterTransaction), $scope.editableObservations = [], shouldEditSpecificObservation()) {
|
|
var editableObs = findEditableObs(ObservationUtil.flattenObsToArray($scope.encounter.observations));
|
|
editableObs ? $scope.editableObservations.push(editableObs) : messagingService.showMessage("error", "{{'CLINICAL_FORM_EDIT_ERROR_MESSAGE_KEY' | translate}}")
|
|
} else $scope.editableObservations = $scope.encounter.observations;
|
|
$scope.patient = {
|
|
uuid: $scope.encounter.patientUuid
|
|
}
|
|
})
|
|
};
|
|
spinner.forPromise(init());
|
|
var isFormValid = function() {
|
|
var contxChange = contextChange(),
|
|
shouldAllow = contxChange.allow;
|
|
if (!shouldAllow) {
|
|
var errorMessage = contxChange.errorMessage ? contxChange.errorMessage : "{{'CLINICAL_FORM_ERRORS_MESSAGE_KEY' | translate }}";
|
|
messagingService.showMessage("error", errorMessage)
|
|
}
|
|
return shouldAllow
|
|
};
|
|
$scope.$parent.resetContextChangeHandler = function() {
|
|
contextChangeHandler.reset()
|
|
}, $scope.save = function() {
|
|
if (!isFormValid()) return void $scope.$parent.$parent.$broadcast("event:errorsOnForm");
|
|
$scope.$parent.shouldPromptBeforeClose = !1, $scope.$parent.shouldPromptBrowserReload = !1;
|
|
var updateEditedObservation = function(observations) {
|
|
return _.map(observations, function(obs) {
|
|
return obs.uuid == $scope.editableObservations[0].uuid ? $scope.editableObservations[0] : (obs.groupMembers = updateEditedObservation(obs.groupMembers), obs)
|
|
})
|
|
},
|
|
getEditedObservation = function(observations) {
|
|
return _.find(observations, function(obs) {
|
|
return obs.uuid == $scope.editableObservations[0].uuid || getEditedObservation(obs.groupMembers)
|
|
})
|
|
};
|
|
if (shouldEditSpecificObservation()) {
|
|
var allObservations = updateEditedObservation($scope.encounter.observations);
|
|
$scope.encounter.observations = [getEditedObservation(allObservations)]
|
|
}
|
|
$scope.encounter.observations = (new Bahmni.Common.Domain.ObservationFilter).filter($scope.encounter.observations), $scope.encounter.orders = addOrdersToEncounter(), $scope.encounter.extensions = {};
|
|
var createPromise = encounterService.create($scope.encounter);
|
|
spinner.forPromise(createPromise).then(function(savedResponse) {
|
|
var messageParams = {
|
|
encounterUuid: savedResponse.data.encounterUuid,
|
|
encounterType: savedResponse.data.encounterType
|
|
};
|
|
auditLogService.log($scope.patient.uuid, "EDIT_ENCOUNTER", messageParams, "MODULE_LABEL_CLINICAL_KEY"), $rootScope.hasVisitedConsultation = !1, $state.go($state.current, {}, {
|
|
reload: !0
|
|
}), ngDialog.close(), messagingService.showMessage("info", "{{'CLINICAL_SAVE_SUCCESS_MESSAGE_KEY' | translate}}")
|
|
})
|
|
};
|
|
var addOrdersToEncounter = function() {
|
|
var modifiedOrders = _.filter($scope.encounter.orders, function(order) {
|
|
return order.hasBeenModified || order.isDiscontinued || !order.uuid
|
|
}),
|
|
tempOrders = modifiedOrders.map(function(order) {
|
|
return order.hasBeenModified && !order.isDiscontinued ? Bahmni.Clinical.Order.revise(order) : order.isDiscontinued ? Bahmni.Clinical.Order.discontinue(order) : {
|
|
uuid: order.uuid,
|
|
concept: {
|
|
name: order.concept.name,
|
|
uuid: order.concept.uuid
|
|
},
|
|
commentToFulfiller: order.commentToFulfiller
|
|
}
|
|
});
|
|
return tempOrders
|
|
}
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
scope: {
|
|
observation: "=",
|
|
conceptSetName: "@",
|
|
conceptDisplayName: "@"
|
|
},
|
|
controller: controller,
|
|
template: "<ng-include src=\"'../common/obs/views/editObservation.html'\" />"
|
|
}
|
|
}]), angular.module("bahmni.common.uiHelper").directive("autoScroll", ["$location", "$anchorScroll", "$timeout", function($location, $anchorScroll, $timeout) {
|
|
var heightOfNavigationBar = 55;
|
|
return {
|
|
scope: {
|
|
autoScrollEnabled: "="
|
|
},
|
|
link: function(scope, element, attrs) {
|
|
$timeout(function() {
|
|
scope.autoScrollEnabled && $("body").animate({
|
|
scrollTop: $("#" + attrs.autoScroll).offset().top - heightOfNavigationBar
|
|
}, 500)
|
|
}), scope.$on("$destroy", function() {
|
|
$timeout.cancel(), $("body").animate({
|
|
scrollTop: -1 * heightOfNavigationBar
|
|
}, 0)
|
|
})
|
|
}
|
|
}
|
|
}]), Bahmni.Common.DocumentImage = function(data) {
|
|
angular.extend(this, data), this.title = this.getTitle(), this.thumbnail = this.getThumbnail()
|
|
}, Bahmni.Common.DocumentImage.prototype = {
|
|
getTitle: function() {
|
|
var titleComponents = [];
|
|
return this.concept && titleComponents.push(this.concept.name), this.obsDatetime && titleComponents.push(moment(this.obsDatetime).format(Bahmni.Common.Constants.dateDisplayFormat)), titleComponents.join(", ")
|
|
},
|
|
getThumbnail: function() {
|
|
var src = this.src || this.encodedValue;
|
|
return src && src.replace(/(.*)\.(.*)$/, "$1_thumbnail.$2") || null
|
|
}
|
|
}, Bahmni.Common.VisitSummary = function(visitSummary) {
|
|
angular.extend(this, visitSummary), this.isAdmitted = function() {
|
|
return !(!this.admissionDetails || !this.admissionDetails.uuid)
|
|
}, this.isDischarged = function() {
|
|
return !(!this.dischargeDetails || !this.dischargeDetails.uuid)
|
|
}, this.getAdmissionEncounterUuid = function() {
|
|
return this.isAdmitted() ? this.admissionDetails.uuid : void 0
|
|
}, this.getDischargeEncounterUuid = function() {
|
|
return this.isDischarged() ? this.dischargeDetails.uuid : void 0
|
|
}, this.hasBeenAdmitted = function() {
|
|
return this.isAdmitted() && !this.isDischarged()
|
|
}
|
|
};
|
|
var debugUiRouter = function($rootScope) {
|
|
$rootScope.$on("$stateChangeStart", function(event, toState, toParams) {
|
|
console.log("$stateChangeStart to " + toState.to + "- fired when the transition begins. toState,toParams : \n", toState, toParams)
|
|
}), $rootScope.$on("$stateChangeError", function() {
|
|
console.log("$stateChangeError - fired when an error occurs during transition."), console.log(arguments)
|
|
}), $rootScope.$on("$stateChangeSuccess", function(event, toState) {
|
|
console.log("$stateChangeSuccess to " + toState.name + "- fired once the state transition is complete.")
|
|
}), $rootScope.$on("$viewContentLoaded", function(event) {
|
|
console.log("$viewContentLoaded - fired after dom rendered", event)
|
|
}), $rootScope.$on("$stateNotFound", function(event, unfoundState, fromState, fromParams) {
|
|
console.log("$stateNotFound " + unfoundState.to + " - fired when a state cannot be found by its name."), console.log(unfoundState, fromState, fromParams)
|
|
})
|
|
};
|
|
angular.module("bahmni.common.uiHelper").directive("singleClick", function() {
|
|
var ignoreClick = !1,
|
|
link = function(scope, element) {
|
|
var clickHandler = function() {
|
|
ignoreClick || (ignoreClick = !0, scope.singleClick()["finally"](function() {
|
|
ignoreClick = !1
|
|
}))
|
|
};
|
|
element.on("click", clickHandler), scope.$on("$destroy", function() {
|
|
element.off("click", clickHandler)
|
|
})
|
|
};
|
|
return {
|
|
scope: {
|
|
singleClick: "&"
|
|
},
|
|
restrict: "A",
|
|
link: link
|
|
}
|
|
}), angular.module("bahmni.common.uiHelper").directive("singleSubmit", function() {
|
|
var ignoreSubmit = !1,
|
|
link = function(scope, element) {
|
|
var submitHandler = function() {
|
|
ignoreSubmit || (ignoreSubmit = !0, scope.singleSubmit()["finally"](function() {
|
|
ignoreSubmit = !1
|
|
}))
|
|
};
|
|
element.on("submit", submitHandler), scope.$on("$destroy", function() {
|
|
element.off("submit", submitHandler)
|
|
})
|
|
};
|
|
return {
|
|
scope: {
|
|
singleSubmit: "&"
|
|
},
|
|
restrict: "A",
|
|
link: link
|
|
}
|
|
});
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.DisplayControl = Bahmni.Common.DisplayControl || {}, angular.module("bahmni.common.displaycontrol", []);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.DisplayControl = Bahmni.Common.DisplayControl || {}, Bahmni.Common.DisplayControl.Observation = Bahmni.Common.DisplayControl.Observation || {}, angular.module("bahmni.common.displaycontrol.observation", ["bahmni.common.conceptSet", "pascalprecht.translate"]), Bahmni.Common.DisplayControl.Observation.GroupingFunctions = function() {
|
|
var self = this,
|
|
observationGroupingFunction = function(obs) {
|
|
return Bahmni.Common.Util.DateUtil.getDateTimeWithoutSeconds(obs.encounterDateTime)
|
|
};
|
|
return self.groupByEncounterDate = function(bahmniObservations) {
|
|
var obsArray = [];
|
|
bahmniObservations = _.groupBy(bahmniObservations, observationGroupingFunction);
|
|
var sortWithInAConceptDateCombination = function(anObs, challengerObs) {
|
|
return anObs.encounterDateTime < challengerObs.encounterDateTime ? 1 : anObs.encounterDateTime > challengerObs.encounterDateTime ? -1 : anObs.conceptSortWeight < challengerObs.conceptSortWeight ? -1 : anObs.conceptSortWeight > challengerObs.conceptSortWeight ? 1 : 0
|
|
};
|
|
for (var obsKey in bahmniObservations) {
|
|
var dateTime = obsKey,
|
|
anObs = {
|
|
key: dateTime,
|
|
value: bahmniObservations[dateTime].sort(sortWithInAConceptDateCombination),
|
|
date: dateTime
|
|
};
|
|
obsArray.push(anObs)
|
|
}
|
|
return _.sortBy(obsArray, "date").reverse()
|
|
}, self.persistOrderOfConceptNames = function(bahmniObservations) {
|
|
var obsArray = [];
|
|
for (var obsKey in bahmniObservations) {
|
|
var anObs = {
|
|
key: obsKey,
|
|
value: [bahmniObservations[obsKey]],
|
|
date: bahmniObservations[obsKey].encounterDateTime
|
|
};
|
|
obsArray.push(anObs)
|
|
}
|
|
return obsArray
|
|
}, self
|
|
}, angular.module("bahmni.common.displaycontrol.observation").service("formHierarchyService", ["formService", function(formService) {
|
|
var self = this;
|
|
self.build = function(observations) {
|
|
var obs = self.preProcessMultipleSelectObsToObs(observations);
|
|
obs = self.createDummyObsGroupForObservationsForForm(obs), self.createDummyObsGroupForSectionsForForm(obs)
|
|
}, self.preProcessMultipleSelectObsToObs = function(observations) {
|
|
return _.forEach(observations, function(obs) {
|
|
_.forEach(obs.value, function(value, index) {
|
|
"multiSelect" == value.type && (obs.value.push(value.groupMembers[0]), obs.value.splice(index, 1))
|
|
})
|
|
}), observations
|
|
}, self.createDummyObsGroupForObservationsForForm = function(observations) {
|
|
return _.forEach(observations, function(obs) {
|
|
var newValues = [];
|
|
_.forEach(obs.value, function(value) {
|
|
if (!value.formFieldPath) return void newValues.push(value);
|
|
var dummyObsGroup = {
|
|
groupMembers: [],
|
|
concept: {
|
|
shortName: "",
|
|
conceptClass: null
|
|
},
|
|
encounterUuid: ""
|
|
};
|
|
dummyObsGroup.concept.shortName = value.formFieldPath.split(".")[0], dummyObsGroup.encounterUuid = value.encounterUuid;
|
|
var previousDummyObsGroupFound;
|
|
_.forEach(newValues, function(newValue) {
|
|
dummyObsGroup.concept.shortName == newValue.concept.shortName && (newValue.groupMembers.push(value), previousDummyObsGroupFound = !0)
|
|
}), previousDummyObsGroupFound || (dummyObsGroup.groupMembers.push(value), newValues.push(dummyObsGroup))
|
|
}), obs.value = newValues
|
|
}), observations
|
|
}, self.getFormVersion = function(members) {
|
|
var formVersion;
|
|
return _.forEach(members, function(member) {
|
|
if (member.formFieldPath) return formVersion = member.formFieldPath.split(".")[1].split("/")[0], !1
|
|
}), formVersion
|
|
}, self.getMemberFromFormByFormFieldPath = function(members, id) {
|
|
return _.filter(members, function(member) {
|
|
return member.formFieldPath.split(".")[1].split("/")[1].split("-")[0] == id
|
|
})
|
|
}, self.getFormByFormName = function(formList, formName, formVersion) {
|
|
return _.find(formList, function(form) {
|
|
return form.name == formName && form.version == formVersion
|
|
})
|
|
}, self.parseSection = function(members, controls, value) {
|
|
var sectionIsEmpty = !0;
|
|
return _.forEach(controls, function(control) {
|
|
var dummyObsGroup = {
|
|
groupMembers: [],
|
|
concept: {
|
|
shortName: "",
|
|
conceptClass: null
|
|
}
|
|
};
|
|
if ("section" == control.type) dummyObsGroup.concept.shortName = control.label.value, value.groupMembers.push(dummyObsGroup), self.parseSection(members, control.controls, dummyObsGroup) ? sectionIsEmpty = !1 : value.groupMembers.pop();
|
|
else {
|
|
var member = self.getMemberFromFormByFormFieldPath(members, control.id);
|
|
0 != member.length && (0 != member[0].formFieldPath.split("-")[1] && _.reverse(member), _.map(member, function(m) {
|
|
value.groupMembers.push(m)
|
|
}), sectionIsEmpty = !1)
|
|
}
|
|
}), sectionIsEmpty ? null : value
|
|
}, self.createSectionForSingleForm = function(obsFromSameForm, formDetails) {
|
|
var members = obsFromSameForm.groupMembers.slice();
|
|
return obsFromSameForm.groupMembers.splice(0, obsFromSameForm.groupMembers.length), self.parseSection(members, formDetails.controls, obsFromSameForm)
|
|
}, self.createDummyObsGroupForSectionsForForm = function(bahmniObservations) {
|
|
_.isEmpty(bahmniObservations) || formService.getAllForms().then(function(response) {
|
|
var allForms = response.data;
|
|
_.forEach(bahmniObservations, function(observation) {
|
|
var forms = [];
|
|
_.forEach(observation.value, function(form) {
|
|
if (form.concept.conceptClass) return void forms.push(form);
|
|
var observationForm = self.getFormByFormName(allForms, form.concept.shortName, self.getFormVersion(form.groupMembers));
|
|
observationForm && formService.getFormDetail(observationForm.uuid, {
|
|
v: "custom:(resources:(value))"
|
|
}).then(function(response) {
|
|
var formDetailsAsString = _.get(response, "data.resources[0].value");
|
|
if (formDetailsAsString) {
|
|
var formDetails = JSON.parse(formDetailsAsString);
|
|
forms.push(self.createSectionForSingleForm(form, formDetails))
|
|
}
|
|
observation.value = forms
|
|
})
|
|
})
|
|
})
|
|
})
|
|
}
|
|
}]), angular.module("bahmni.common.displaycontrol.observation").directive("bahmniObservation", ["observationsService", "appService", "$q", "spinner", "$rootScope", "formHierarchyService", "$translate", function(observationsService, appService, $q, spinner, $rootScope, formHierarchyService, $translate) {
|
|
var controller = function($scope) {
|
|
$scope.print = $rootScope.isBeingPrinted || !1, $scope.showGroupDateTime = $scope.config.showGroupDateTime !== !1;
|
|
var mapObservation = function(observations) {
|
|
var conceptsConfig = appService.getAppDescriptor().getConfigValue("conceptSetUI") || {};
|
|
observations = (new Bahmni.Common.Obs.ObservationMapper).map(observations, conceptsConfig), $scope.config.conceptNames && (observations = _.filter(observations, function(observation) {
|
|
return _.some($scope.config.conceptNames, function(conceptName) {
|
|
return _.toLower(conceptName) === _.toLower(_.get(observation, "concept.name"))
|
|
})
|
|
})), $scope.config.persistOrderOfConcepts ? $scope.bahmniObservations = (new Bahmni.Common.DisplayControl.Observation.GroupingFunctions).persistOrderOfConceptNames(observations) : $scope.bahmniObservations = (new Bahmni.Common.DisplayControl.Observation.GroupingFunctions).groupByEncounterDate(observations), _.isEmpty($scope.bahmniObservations) ? ($scope.noObsMessage = $translate.instant(Bahmni.Common.Constants.messageForNoObservation), $scope.$emit("no-data-present-event")) : $scope.showGroupDateTime ? $scope.bahmniObservations[0].isOpen = !0 : _.forEach($scope.bahmniObservations, function(bahmniObs) {
|
|
bahmniObs.isOpen = !0
|
|
});
|
|
var formObservations = _.filter(observations, function(obs) {
|
|
return obs.formFieldPath
|
|
});
|
|
formObservations.length > 0 && formHierarchyService.build($scope.bahmniObservations)
|
|
},
|
|
fetchObservations = function() {
|
|
if ($scope.observations) mapObservation($scope.observations, $scope.config), $scope.isFulfilmentDisplayControl = !0;
|
|
else if ($scope.config.observationUuid) $scope.initialization = observationsService.getByUuid($scope.config.observationUuid).then(function(response) {
|
|
mapObservation([response.data], $scope.config)
|
|
});
|
|
else if ($scope.config.encounterUuid) {
|
|
var fetchForEncounter = observationsService.fetchForEncounter($scope.config.encounterUuid, $scope.config.conceptNames);
|
|
$scope.initialization = fetchForEncounter.then(function(response) {
|
|
mapObservation(response.data, $scope.config)
|
|
})
|
|
} else $scope.enrollment ? $scope.initialization = observationsService.fetchForPatientProgram($scope.enrollment, $scope.config.conceptNames, $scope.config.scope, $scope.config.obsIgnoreList).then(function(response) {
|
|
mapObservation(response.data, $scope.config)
|
|
}) : $scope.initialization = observationsService.fetch($scope.patient.uuid, $scope.config.conceptNames, $scope.config.scope, $scope.config.numberOfVisits, $scope.visitUuid, $scope.config.obsIgnoreList, null).then(function(response) {
|
|
mapObservation(response.data, $scope.config)
|
|
})
|
|
};
|
|
$scope.toggle = function(element) {
|
|
element.isOpen = !element.isOpen
|
|
}, $scope.isClickable = function() {
|
|
return $scope.isOnDashboard && $scope.section.expandedViewConfig && ($scope.section.expandedViewConfig.pivotTable || $scope.section.expandedViewConfig.observationGraph)
|
|
}, fetchObservations(), $scope.dialogData = {
|
|
patient: $scope.patient,
|
|
section: $scope.section
|
|
}
|
|
},
|
|
link = function($scope, element) {
|
|
$scope.initialization && spinner.forPromise($scope.initialization, element)
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
controller: controller,
|
|
link: link,
|
|
templateUrl: "../common/displaycontrols/observation/views/observationDisplayControl.html",
|
|
scope: {
|
|
patient: "=",
|
|
visitUuid: "@",
|
|
section: "=?",
|
|
config: "=",
|
|
title: "=sectionTitle",
|
|
isOnDashboard: "=?",
|
|
observations: "=?",
|
|
message: "=?",
|
|
enrollment: "=?"
|
|
}
|
|
}
|
|
}]), angular.module("bahmni.common.displaycontrol.observation").controller("AllObservationDetailsController", ["$scope", function($scope) {
|
|
$scope.patient = $scope.ngDialogData.patient, $scope.section = $scope.ngDialogData.section, $scope.config = $scope.ngDialogData.section ? $scope.ngDialogData.section.expandedViewConfig : {}
|
|
}]), Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.DisplayControl = Bahmni.Common.DisplayControl || {}, Bahmni.Common.DisplayControl.Prescription = Bahmni.Common.DisplayControl.Prescription || {}, angular.module("bahmni.common.displaycontrol.prescription", []), angular.module("bahmni.common.displaycontrol.prescription").directive("prescription", ["treatmentService", "treatmentConfig", "$q", function(treatmentService, treatmentConfig, $q) {
|
|
var controller = function($scope) {
|
|
$q.all([treatmentConfig(), treatmentService.getPrescribedAndActiveDrugOrders($scope.patient.uuid, 1, !1, [$scope.visitUuid], "", "", "")]).then(function(results) {
|
|
var treatmentConfig = results[0],
|
|
drugOrderResponse = results[1].data,
|
|
createDrugOrderViewModel = function(drugOrder) {
|
|
return Bahmni.Clinical.DrugOrderViewModel.createFromContract(drugOrder, treatmentConfig)
|
|
};
|
|
for (var key in drugOrderResponse) drugOrderResponse[key] = drugOrderResponse[key].map(createDrugOrderViewModel);
|
|
var drugUtil = Bahmni.Clinical.DrugOrder.Util,
|
|
orderGroupOrders = _.groupBy(drugOrderResponse.visitDrugOrders, function(drugOrder) {
|
|
return drugOrder.orderGroupUuid ? "orderGroupOrders" : "drugOrders"
|
|
}),
|
|
drugOrdersSorted = drugUtil.sortDrugOrders(orderGroupOrders.drugOrders);
|
|
$scope.drugOrders = _(orderGroupOrders.orderGroupOrders).concat(drugOrdersSorted).uniqBy("uuid").value()
|
|
})
|
|
};
|
|
return {
|
|
restrict: "EA",
|
|
controller: controller,
|
|
templateUrl: "../common/displaycontrols/prescription/views/prescription.html",
|
|
scope: {
|
|
patient: "=",
|
|
visitDate: "=",
|
|
visitUuid: "="
|
|
}
|
|
}
|
|
}]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.DisplayControl = Bahmni.Common.DisplayControl || {}, Bahmni.Common.DisplayControl.PivotTable = Bahmni.Common.DisplayControl.PivotTable || {}, angular.module("bahmni.common.displaycontrol", []), angular.module("bahmni.common.displaycontrol.pivottable", []), angular.module("bahmni.common.displaycontrol.pivottable").directive("pivotTable", ["$rootScope", "$filter", "$stateParams", "spinner", "pivotTableService", "appService", "conceptSetUiConfigService", "$interval", function($rootScope, $filter, $stateParams, spinner, pivotTableService, appService, conceptSetUiConfigService, $interval) {
|
|
return {
|
|
scope: {
|
|
patientUuid: "=",
|
|
diseaseName: "=",
|
|
displayName: "=",
|
|
config: "=",
|
|
visitUuid: "=",
|
|
status: "=?"
|
|
},
|
|
link: function(scope, element) {
|
|
var tablescroll;
|
|
if (scope.config) {
|
|
scope.groupBy = scope.config.groupBy || "visits", scope.groupByEncounters = "encounters" === scope.groupBy, scope.groupByVisits = "visits" === scope.groupBy, scope.getOnlyDate = function(startdate) {
|
|
return Bahmni.Common.Util.DateUtil.formatDateWithoutTime(startdate)
|
|
}, scope.getOnlyTime = function(startDate) {
|
|
return Bahmni.Common.Util.DateUtil.formatTime(startDate)
|
|
}, scope.isLonger = function(value) {
|
|
return !!value && value.length > 13
|
|
}, scope.getColumnValue = function(value, conceptName) {
|
|
return conceptName && conceptSetUiConfigService.getConfig()[conceptName] && 1 == conceptSetUiConfigService.getConfig()[conceptName].displayMonthAndYear ? Bahmni.Common.Util.DateUtil.getDateInMonthsAndYears(value) : scope.isLonger(value) ? value.substring(0, 10) + "..." : value
|
|
}, scope.scrollLeft = function() {
|
|
return $("table.pivot-table tbody").animate({
|
|
scrollLeft: 0
|
|
}), !1
|
|
}, scope.scrollRight = function() {
|
|
return $("table.pivot-table tbody").animate({
|
|
scrollLeft: tablescroll
|
|
}), !1
|
|
};
|
|
var programConfig = appService.getAppDescriptor().getConfigValue("program") || {},
|
|
startDate = null,
|
|
endDate = null;
|
|
programConfig.showDetailsWithinDateRange && (startDate = $stateParams.dateEnrolled, endDate = $stateParams.dateCompleted);
|
|
var checkIfPivotTableLoaded = $interval(function() {
|
|
$("table.pivot-table tbody tr").length > 11 ? ($("table.pivot-table tbody").animate({
|
|
scrollLeft: "20000px"
|
|
}, 500), tablescroll = $("table.pivot-table tbody").scrollLeft(), clearInterval(checkIfPivotTableLoaded)) : $("table.pivot-table tbody tr").length < 12 && ($(".btn-scroll-right, .btn-scroll-left").attr("disabled", !0), clearInterval(checkIfPivotTableLoaded))
|
|
}, 1e3, 2),
|
|
pivotDataPromise = pivotTableService.getPivotTableFor(scope.patientUuid, scope.config, scope.visitUuid, startDate, endDate);
|
|
spinner.forPromise(pivotDataPromise, element), pivotDataPromise.then(function(response) {
|
|
var concepts = _.map(response.data.conceptDetails, function(conceptDetail) {
|
|
return {
|
|
name: conceptDetail.fullName,
|
|
shortName: conceptDetail.name,
|
|
lowNormal: conceptDetail.lowNormal,
|
|
hiNormal: conceptDetail.hiNormal,
|
|
units: conceptDetail.units
|
|
}
|
|
}),
|
|
tabluarDataInAscOrderByDate = _(response.data.tabularData).toPairs().sortBy(0).fromPairs().value();
|
|
scope.result = {
|
|
concepts: concepts,
|
|
tabularData: tabluarDataInAscOrderByDate
|
|
}, scope.hasData = !_.isEmpty(scope.result.tabularData), scope.status = scope.status || {}, scope.status.data = scope.hasData
|
|
}), scope.showOnPrint = !$rootScope.isBeingPrinted
|
|
}
|
|
},
|
|
templateUrl: "../common/displaycontrols/pivottable/views/pivotTable.html"
|
|
}
|
|
}]), angular.module("bahmni.common.displaycontrol.pivottable").service("pivotTableService", ["$http", function($http) {
|
|
this.getPivotTableFor = function(patientUuid, diseaseSummaryConfig, visitUuid, startDate, endDate) {
|
|
return $http.get(Bahmni.Common.Constants.diseaseSummaryPivotUrl, {
|
|
params: {
|
|
patientUuid: patientUuid,
|
|
visit: visitUuid,
|
|
numberOfVisits: diseaseSummaryConfig.numberOfVisits,
|
|
initialCount: diseaseSummaryConfig.initialCount,
|
|
latestCount: diseaseSummaryConfig.latestCount,
|
|
obsConcepts: diseaseSummaryConfig.obsConcepts,
|
|
drugConcepts: diseaseSummaryConfig.drugConcepts,
|
|
labConcepts: diseaseSummaryConfig.labConcepts,
|
|
groupBy: diseaseSummaryConfig.groupBy,
|
|
startDate: Bahmni.Common.Util.DateUtil.parseLongDateToServerFormat(startDate),
|
|
endDate: Bahmni.Common.Util.DateUtil.parseLongDateToServerFormat(endDate)
|
|
}
|
|
})
|
|
}
|
|
}]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.DisplayControl = Bahmni.Common.DisplayControl || {}, Bahmni.Common.DisplayControl.Disposition = Bahmni.Common.DisplayControl.Disposition || {}, angular.module("bahmni.common.displaycontrol.disposition", []), angular.module("bahmni.common.displaycontrol.disposition").directive("disposition", ["dispositionService", "spinner", function(dispositionService, spinner) {
|
|
var controller = function($scope) {
|
|
var fetchDispositionByPatient = function(patientUuid, numOfVisits) {
|
|
return dispositionService.getDispositionByPatient(patientUuid, numOfVisits).then(handleDispositionResponse)
|
|
},
|
|
handleDispositionResponse = function(response) {
|
|
$scope.dispositions = response.data, _.isEmpty($scope.dispositions) && ($scope.noDispositionsMessage = Bahmni.Common.Constants.messageForNoDisposition, $scope.$emit("no-data-present-event"))
|
|
},
|
|
fetchDispositionsByVisit = function(visitUuid) {
|
|
return dispositionService.getDispositionByVisit(visitUuid).then(handleDispositionResponse)
|
|
};
|
|
$scope.getNotes = function(disposition) {
|
|
return disposition.additionalObs[0] && disposition.additionalObs[0].value ? disposition.additionalObs[0].value : ""
|
|
}, $scope.showDetailsButton = function(disposition) {
|
|
return !$scope.getNotes(disposition) && $scope.params.showDetailsButton
|
|
}, $scope.toggle = function(element) {
|
|
return $scope.showDetailsButton(element) ? element.show = !element.show : element.show = !0, !1
|
|
}, $scope.visitUuid ? $scope.fetchDispositionPromise = fetchDispositionsByVisit($scope.visitUuid) : $scope.params.numberOfVisits && $scope.patientUuid && ($scope.fetchDispositionPromise = fetchDispositionByPatient($scope.patientUuid, $scope.params.numberOfVisits))
|
|
},
|
|
link = function(scope, element) {
|
|
spinner.forPromise(scope.fetchDispositionPromise, element)
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
controller: controller,
|
|
link: link,
|
|
templateUrl: "../common/displaycontrols/disposition/views/disposition.html",
|
|
scope: {
|
|
params: "=",
|
|
patientUuid: "=?",
|
|
visitUuid: "=?"
|
|
}
|
|
}
|
|
}]), angular.module("bahmni.common.displaycontrol.conditionsList", []), angular.module("bahmni.common.displaycontrol.conditionsList").directive("conditionsList", ["conditionsService", "ngDialog", function(conditionsService, ngDialog) {
|
|
var controller = function($scope) {
|
|
return $scope.statuses = ["ACTIVE", "HISTORY_OF"], $scope.openSummaryDialog = function() {
|
|
ngDialog.open({
|
|
template: "../common/displaycontrols/conditionsList/views/conditionsList.html",
|
|
className: "ngdialog-theme-default ng-dialog-all-details-page",
|
|
data: {
|
|
conditions: $scope.conditions
|
|
},
|
|
controller: function($scope) {
|
|
$scope.hideTitle = !0, $scope.statuses = ["ACTIVE", "HISTORY_OF", "INACTIVE"], $scope.conditions = $scope.ngDialogData.conditions
|
|
}
|
|
})
|
|
}, conditionsService.getConditions($scope.patient.uuid).then(function(conditions) {
|
|
$scope.conditions = conditions
|
|
})
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
controller: controller,
|
|
templateUrl: "../common/displaycontrols/conditionsList/views/conditionsList.html",
|
|
scope: {
|
|
params: "=",
|
|
patient: "="
|
|
}
|
|
}
|
|
}]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.DisplayControl = Bahmni.Common.DisplayControl || {}, Bahmni.Common.DisplayControl.Dashboard = Bahmni.Common.DisplayControl.Dashboard || {}, angular.module("bahmni.common.displaycontrol.dashboard", []), angular.module("bahmni.common.displaycontrol.dashboard").directive("dashboardSection", function() {
|
|
var controller = function($scope) {
|
|
$scope.$on("no-data-present-event", function() {
|
|
$scope.section.isDataAvailable = !$scope.section.hideEmptyDisplayControl
|
|
})
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
controller: controller,
|
|
templateUrl: "../common/displaycontrols/dashboard/views/dashboardSection.html"
|
|
}
|
|
}), angular.module("bahmni.common.displaycontrol.dashboard").directive("dashboard", [function() {
|
|
var controller = function($scope, $filter) {
|
|
var init = function() {
|
|
$scope.dashboard = Bahmni.Common.DisplayControl.Dashboard.create($scope.config || {}, $filter)
|
|
},
|
|
checkDisplayType = function(sections, typeToCheck, index) {
|
|
return sections[index] && sections[index].displayType && sections[index].displayType === typeToCheck
|
|
},
|
|
isDisplayTypeWrong = function(sections) {
|
|
var allDisplayTypes = ["Full-Page", "LAYOUT_75_25", "LAYOUT_25_75", "Half-Page"];
|
|
return allDisplayTypes.indexOf(sections[0].displayType) <= -1
|
|
};
|
|
$scope.isFullPageSection = function(sections) {
|
|
return checkDisplayType(sections, "Full-Page", 0)
|
|
}, $scope.hasThreeFourthPageSection = function(sections, index) {
|
|
return checkDisplayType(sections, "LAYOUT_75_25", index)
|
|
}, $scope.isOneFourthPageSection = function(sections) {
|
|
return checkDisplayType(sections, "LAYOUT_25_75", 0)
|
|
}, $scope.isHalfPageSection = function(sections) {
|
|
return sections[0] && (checkDisplayType(sections, "Half-Page", 0) || isDisplayTypeWrong(sections) || !sections[0].displayType)
|
|
}, $scope.containsThreeFourthPageSection = function(sections) {
|
|
var hasThreeFourthSection = this.hasThreeFourthPageSection(sections, 0) || this.hasThreeFourthPageSection(sections, 1);
|
|
return 1 == sections.length ? this.hasThreeFourthPageSection(sections, 0) : hasThreeFourthSection
|
|
}, $scope.filterOdd = function(index) {
|
|
return function() {
|
|
return index++ % 2 === 0
|
|
}
|
|
}, $scope.filterEven = function(index) {
|
|
return function() {
|
|
return index++ % 2 === 1
|
|
}
|
|
};
|
|
var unbindWatch = $scope.$watch("config", init);
|
|
$scope.$on("$stateChangeStart", unbindWatch)
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
controller: controller,
|
|
templateUrl: "../common/displaycontrols/dashboard/views/dashboard.html",
|
|
scope: {
|
|
config: "=",
|
|
patient: "=",
|
|
diseaseTemplates: "=",
|
|
sectionGroups: "=",
|
|
visitHistory: "=",
|
|
activeVisitUuid: "=",
|
|
visitSummary: "=",
|
|
enrollment: "="
|
|
}
|
|
}
|
|
}]), Bahmni.Common.DisplayControl.Dashboard = function(config, $filter) {
|
|
(config.startDate || config.endDate) && _.each(config.sections, function(section) {
|
|
section.startDate = config.startDate, section.endDate = config.endDate
|
|
});
|
|
var _sections = _.sortBy(_.map(config.sections, function(section) {
|
|
return Bahmni.Common.DisplayControl.Dashboard.Section.create(section, $filter)
|
|
}), function(section) {
|
|
return section.displayOrder
|
|
});
|
|
this.getSectionByType = function(name) {
|
|
return _.find(_sections, function(section) {
|
|
return section.type === name
|
|
}) || {}
|
|
}, this.getSections = function(diseaseTemplates) {
|
|
var sections = _.filter(_sections, function(section) {
|
|
return "diseaseTemplate" !== section.type || _.find(diseaseTemplates, function(diseaseTemplate) {
|
|
return diseaseTemplate.name === section.templateName && diseaseTemplate.obsTemplates.length > 0
|
|
})
|
|
});
|
|
return this.groupSectionsByType(sections)
|
|
}, this.groupSectionsByType = function(sections) {
|
|
var sectionGroups = [
|
|
[]
|
|
];
|
|
for (var sectionId in sections) {
|
|
var section = sections[sectionId],
|
|
nextSection = sectionId < sections.length ? sections[++sectionId] : null,
|
|
lastElement = sectionGroups.length - 1;
|
|
this.isFullPageSection(section) ? (_.isEmpty(sectionGroups[lastElement]) && sectionGroups.pop(), sectionGroups.push([section]), sectionGroups.push([])) : sectionGroups = this.groupSectionsIfNotFullPage(section, sectionGroups, lastElement, nextSection)
|
|
}
|
|
return sectionGroups
|
|
}, this.isFullPageSection = function(section) {
|
|
return this.checkDisplayType(section, "Full-Page")
|
|
}, this.isThreeFourthPageSection = function(section) {
|
|
return this.checkDisplayType(section, "LAYOUT_75_25")
|
|
}, this.isOneFourthPageSection = function(section) {
|
|
return this.checkDisplayType(section, "LAYOUT_25_75")
|
|
}, this.isHalfPageSection = function(section) {
|
|
return this.checkDisplayType(section, "Half-Page") || this.isDisplayTypeWrong(section) || !section.displayType
|
|
}, this.isDisplayTypeWrong = function(section) {
|
|
var allDisplayTypes = ["Full-Page", "LAYOUT_75_25", "LAYOUT_25_75", "Half-Page"];
|
|
return allDisplayTypes.indexOf(section.displayType) <= -1
|
|
}, this.checkDisplayType = function(section, typeToCheck) {
|
|
return section && section.displayType && section.displayType === typeToCheck
|
|
}, this.groupSectionsIfNotFullPage = function(section, sectionGroups, lastElement, nextSection) {
|
|
var lastSection = sectionGroups[lastElement],
|
|
lastSectionIndex = _.isEmpty(lastSection) ? 0 : lastSection.length - 1;
|
|
return sectionGroups = this.isThreeFourthPageSection(section) ? this.groupThreeFourthPageSection(lastSection, lastElement, lastSectionIndex, section, sectionGroups) : this.isOneFourthPageSection(section) ? this.groupOneFourthPageSection(lastSection, lastElement, lastSectionIndex, section, sectionGroups, nextSection) : this.groupHalfPageSection(lastSection, lastElement, lastSectionIndex, section, sectionGroups)
|
|
}, this.groupThreeFourthPageSection = function(lastSection, lastElement, lastSectionIndex, section, sectionGroups) {
|
|
var lastSectionLength = lastSection.length,
|
|
isLastSectionOneFourth = 1 == lastSectionLength && this.isOneFourthPageSection(lastSection[lastSectionIndex]);
|
|
return _.isEmpty(lastSection) || isLastSectionOneFourth ? sectionGroups[lastElement].push(section) : sectionGroups.push([section]), sectionGroups
|
|
}, this.groupOneFourthPageSection = function(lastSection, lastElement, lastSectionIndex, section, sectionGroups, nextSection) {
|
|
return this.addOneFourthElementToLastSection(lastSection, lastElement, lastSectionIndex, nextSection) ? sectionGroups[lastElement].push(section) : sectionGroups.push([section]), sectionGroups
|
|
}, this.addOneFourthElementToLastSection = function(lastSection, lastElement, lastSectionIndex, nextSection) {
|
|
var lastSectionLength = lastSection.length,
|
|
isNextSectionThreeFourth = !!nextSection && this.isThreeFourthPageSection(nextSection),
|
|
isLastSectionNotThreeFourth = !this.isThreeFourthPageSection(lastSection[lastSectionIndex]) && !this.isThreeFourthPageSection(lastSection[0]);
|
|
return lastSection.length <= 1 && (this.isThreeFourthPageSection(lastSection[0]) || !isNextSectionThreeFourth) || lastSectionLength >= 2 && isLastSectionNotThreeFourth && !isNextSectionThreeFourth
|
|
}, this.groupHalfPageSection = function(lastSection, lastElement, lastSectionIndex, section, sectionGroups) {
|
|
var lastSectionLength = lastSection.length,
|
|
isLastSectionNotThreeFourth = !this.isThreeFourthPageSection(lastSection[lastSectionIndex]) && !this.isThreeFourthPageSection(lastSection[0]);
|
|
return _.isEmpty(lastSection) || lastSectionLength > 2 || isLastSectionNotThreeFourth ? sectionGroups[lastElement].push(section) : sectionGroups.push([section]), sectionGroups
|
|
}
|
|
}, Bahmni.Common.DisplayControl.Dashboard.create = function(config, $filter) {
|
|
return new Bahmni.Common.DisplayControl.Dashboard(config, $filter)
|
|
},
|
|
function() {
|
|
var OBSERVATION_SECTION_URL = "../common/displaycontrols/dashboard/views/sections/observationSection.html",
|
|
COMMON_DISPLAY_CONTROL_URL = "../common/displaycontrols/dashboard/views/sections/SECTION_NAME.html",
|
|
CLINICAL_DISPLAY_CONTROL_URL = "../clinical/dashboard/views/dashboardSections/SECTION_NAME.html",
|
|
commonDisplayControlNames = ["admissionDetails", "bacteriologyResultsControl", "chronicTreatmentChart", "custom", "diagnosis", "disposition", "drugOrderDetails", "forms", "observationGraph", "obsToObsFlowSheet", "pacsOrders", "patientInformation", "conditionsList"],
|
|
getViewUrl = function(section) {
|
|
if (section.isObservation) return OBSERVATION_SECTION_URL;
|
|
var isCommonDisplayControl = _.includes(commonDisplayControlNames, section.type);
|
|
return isCommonDisplayControl ? COMMON_DISPLAY_CONTROL_URL.replace("SECTION_NAME", section.type) : CLINICAL_DISPLAY_CONTROL_URL.replace("SECTION_NAME", section.type)
|
|
},
|
|
getId = function(section, $filter) {
|
|
if ("custom" !== section.type) {
|
|
var key = section.translationKey || section.title;
|
|
return !_.isUndefined($filter) && key ? $filter("titleTranslate")(key).toValidId() : key
|
|
}
|
|
};
|
|
Bahmni.Common.DisplayControl.Dashboard.Section = function(section, $filter) {
|
|
angular.extend(this, section), this.displayOrder = section.displayOrder, this.data = section.data || {}, this.isObservation = !!section.isObservation, this.patientAttributes = section.patientAttributes || [], this.viewName = getViewUrl(this), this.hideEmptyDisplayControl = void 0 != section.hideEmptyDisplayControl && section.hideEmptyDisplayControl, this.isDataAvailable = !0, this.id = getId(this, $filter)
|
|
}, Bahmni.Common.DisplayControl.Dashboard.Section.create = function(section, $filter) {
|
|
return new Bahmni.Common.DisplayControl.Dashboard.Section(section, $filter)
|
|
}
|
|
}();
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.DisplayControl = Bahmni.Common.DisplayControl || {}, Bahmni.Common.DisplayControl.PatientProfile = Bahmni.Common.DisplayControl.PatientProfile || {}, angular.module("bahmni.common.displaycontrol.patientprofile", []), angular.module("bahmni.common.displaycontrol.patientprofile").filter("titleCase", function() {
|
|
return function(input) {
|
|
return input = input || "", input.replace(/\w\S*/g, function(txt) {
|
|
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()
|
|
})
|
|
}
|
|
}), angular.module("bahmni.common.displaycontrol.patientprofile").filter("booleanFilter", function() {
|
|
return function(value) {
|
|
return value === !0 ? "Yes" : value === !1 ? "No" : value
|
|
}
|
|
}),
|
|
function() {
|
|
var getAddress = function($scope) {
|
|
var patient = $scope.patient,
|
|
address = [];
|
|
return void 0 != $scope.config.addressFields && 0 != $scope.config.addressFields.length ? $scope.config.addressFields.forEach(function(addressField) {
|
|
patient.address[addressField] && address.push(patient.address[addressField])
|
|
}) : _.includes($scope.config, "cityVillage") || address.push(patient.address.cityVillage), address.join(", ")
|
|
},
|
|
getPatientAttributeTypes = function($scope) {
|
|
var patient = $scope.patient;
|
|
$scope.config.hasOwnProperty("ageLimit") && patient.age >= $scope.config.ageLimit && (patient.ageText = patient.age.toString() + " <span> years </span>");
|
|
var patientAttributeTypes = [patient.genderText, patient.ageText];
|
|
return patient.bloodGroupText && patientAttributeTypes.push(patient.bloodGroupText), patientAttributeTypes.join(", ")
|
|
},
|
|
isAdmitted = function(admissionStatus) {
|
|
return "Admitted" === _.get(admissionStatus, "value")
|
|
};
|
|
angular.module("bahmni.common.displaycontrol.patientprofile").directive("patientProfile", ["patientService", "spinner", "$sce", "$rootScope", "$stateParams", "$window", "$translate", "configurations", "$q", "visitService", function(patientService, spinner, $sce, $rootScope, $stateParams, $window, $translate, configurations, $q, visitService) {
|
|
var controller = function($scope) {
|
|
$scope.isProviderRelationship = function(relationship) {
|
|
return _.includes($rootScope.relationshipTypeMap.provider, relationship.relationshipType.aIsToB)
|
|
}, $scope.openPatientDashboard = function(patientUuid) {
|
|
var configName = $stateParams.configName || Bahmni.Common.Constants.defaultExtensionName;
|
|
$window.open("../clinical/#/" + configName + "/patient/" + patientUuid + "/dashboard")
|
|
};
|
|
var assignPatientDetails = function() {
|
|
var patientMapper = new Bahmni.PatientMapper(configurations.patientConfig(), $rootScope, $translate);
|
|
return patientService.getPatient($scope.patientUuid).then(function(response) {
|
|
var openMrsPatient = response.data;
|
|
$scope.patient = patientMapper.map(openMrsPatient)
|
|
})
|
|
},
|
|
assignRelationshipDetails = function() {
|
|
return patientService.getRelationships($scope.patientUuid).then(function(response) {
|
|
$scope.relationships = response.data.results
|
|
})
|
|
},
|
|
assignAdmissionDetails = function() {
|
|
var REP = "custom:(attributes:(value,attributeType:(display,name)))",
|
|
ADMISSION_STATUS_ATTRIBUTE = "Admission Status";
|
|
return visitService.getVisit($scope.visitUuid, REP).then(function(response) {
|
|
var attributes = response.data.attributes,
|
|
admissionStatus = _.find(attributes, {
|
|
attributeType: {
|
|
name: ADMISSION_STATUS_ATTRIBUTE
|
|
}
|
|
});
|
|
$scope.hasBeenAdmitted = isAdmitted(admissionStatus)
|
|
})
|
|
},
|
|
setHasBeenAdmittedOnVisitUuidChange = function() {
|
|
$scope.$watch("visitUuid", function(visitUuid) {
|
|
_.isEmpty(visitUuid) || assignAdmissionDetails()
|
|
})
|
|
},
|
|
setDirectiveAsReady = function() {
|
|
$scope.isDirectiveReady = !0
|
|
},
|
|
onDirectiveReady = function() {
|
|
$scope.addressLine = getAddress($scope), $scope.patientAttributeTypes = $sce.trustAsHtml(getPatientAttributeTypes($scope)), $scope.showBirthDate = $scope.config.showDOB !== !1, $scope.showBirthDate = $scope.showBirthDate && !!$scope.patient.birthdate
|
|
},
|
|
initPromise = $q.all([assignPatientDetails(), assignRelationshipDetails()]);
|
|
initPromise.then(onDirectiveReady), initPromise.then(setHasBeenAdmittedOnVisitUuidChange), initPromise.then(setDirectiveAsReady), $scope.initialization = initPromise
|
|
},
|
|
link = function($scope, element) {
|
|
spinner.forPromise($scope.initialization, element)
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
controller: controller,
|
|
link: link,
|
|
scope: {
|
|
patientUuid: "@",
|
|
visitUuid: "@",
|
|
config: "="
|
|
},
|
|
templateUrl: "../common/displaycontrols/patientprofile/views/patientProfile.html"
|
|
}
|
|
}])
|
|
}(), angular.module("bahmni.common.displaycontrol", []), angular.module("bahmni.common.displaycontrol.documents", []), angular.module("bahmni.common.displaycontrol.documents").directive("bmDocuments", ["encounterService", "spinner", "configurations", function(encounterService, spinner, configurations) {
|
|
var controller = function($scope, $filter) {
|
|
var encounterTypeUuid = configurations.encounterConfig().getEncounterTypeUuid($scope.encounterType);
|
|
$scope.initialization = function() {
|
|
return encounterService.getEncountersForEncounterType($scope.patient.uuid, encounterTypeUuid).then(function(response) {
|
|
$scope.records = (new Bahmni.Clinical.PatientFileObservationsMapper).map(response.data.results), $scope.config.visitUuids && ($scope.records = _.filter($scope.records, function(record) {
|
|
return $scope.config.visitUuids.indexOf(record.visitUuid) != -1
|
|
})), $scope.recordGroups = (new Bahmni.Clinical.RecordsMapper).map($scope.records), $scope.isDataPresent = function() {
|
|
return 0 != $scope.recordGroups.length || ($scope.$emit("no-data-present-event"), !1)
|
|
}
|
|
})
|
|
}, $scope.shouldShowActiveVisitStar = function(records) {
|
|
return (!$scope.config.visitUuids || 1 !== $scope.config.visitUuids.length) && _.some(records, function(record) {
|
|
return !record.visitStopDate
|
|
})
|
|
}
|
|
},
|
|
link = function($scope, element) {
|
|
spinner.forPromise($scope.initialization(), element)
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
controller: controller,
|
|
scope: {
|
|
patient: "=",
|
|
config: "=",
|
|
encounterType: "="
|
|
},
|
|
link: link,
|
|
templateUrl: "../common/displaycontrols/documents/views/bmDocuments.html"
|
|
}
|
|
}]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.DisplayControl = Bahmni.Common.DisplayControl || {}, Bahmni.Common.DisplayControl.navigationLinks = Bahmni.Common.DisplayControl.navigationLinks || {}, angular.module("bahmni.common.displaycontrol.navigationlinks", ["ui.router", "ui.router.util"]), angular.module("bahmni.common.displaycontrol.navigationlinks").directive("navigationLinks", ["$state", "appService", function($state, appService) {
|
|
var controller = function($scope) {
|
|
(!$scope.params.showLinks && !$scope.params.customLinks || $scope.params.showLinks && $scope.params.customLinks && 0 == $scope.params.showLinks.length && 0 == $scope.params.customLinks.length) && ($scope.noNavigationLinksMessage = Bahmni.Common.Constants.noNavigationLinksMessage), $scope.standardLinks = [{
|
|
name: "home",
|
|
translationKey: "HOME_DASHBOARD_KEY",
|
|
url: "../home/#/dashboard"
|
|
}, {
|
|
name: "visit",
|
|
url: "../clinical/#/default/patient/{{patientUuid}}/dashboard/visit/{{visitUuid}}/?encounterUuid=active",
|
|
translationKey: "PATIENT_VISIT_PAGE_KEY"
|
|
}, {
|
|
name: "inpatient",
|
|
translationKey: "PATIENT_ADT_PAGE_KEY",
|
|
url: "../adt/#/patient/{{patientUuid}}/visit/{{visitUuid}}/"
|
|
}, {
|
|
name: "enrolment",
|
|
translationKey: "PROGRAM_MANAGEMENT_PAGE_KEY",
|
|
url: "../clinical/#/programs/patient/{{patientUuid}}/consultationContext"
|
|
}, {
|
|
name: "visitAttribute",
|
|
translationKey: "PATIENT_VISIT_ATTRIBUTES_PAGE_KEY",
|
|
url: "../registration/#/patient/{{patientUuid}}/visit"
|
|
}, {
|
|
name: "registration",
|
|
translationKey: "PATIENT_REGISTRATION_PAGE_KEY",
|
|
url: "../registration/#/patient/{{patientUuid}}"
|
|
}];
|
|
var filterLinks = function(links, showLinks) {
|
|
var linksSpecifiedInShowLinks = function() {
|
|
return _.filter(links, function(link) {
|
|
return showLinks.indexOf(link.name) > -1
|
|
})
|
|
};
|
|
return showLinks && linksSpecifiedInShowLinks()
|
|
};
|
|
$scope.getLinks = function() {
|
|
return _.union(filterLinks($scope.standardLinks, $scope.params.showLinks), $scope.params.customLinks)
|
|
}, $scope.getUrl = function(link) {
|
|
var url = getFormattedURL(link);
|
|
window.open(url, link.title)
|
|
}, $scope.showUrl = function(link) {
|
|
var isPropertyNotPresentInLinkParams, params = getParamsToBeReplaced(link.url);
|
|
for (var i in params) {
|
|
var property = params[i];
|
|
if (isPropertyNotPresentInLinkParams = _.isEmpty($scope.linkParams[property])) return !1
|
|
}
|
|
return !0
|
|
};
|
|
var getFormattedURL = function(link) {
|
|
return appService.getAppDescriptor().formatUrl(link.url, $scope.linkParams)
|
|
},
|
|
getParamsToBeReplaced = function(link) {
|
|
var pattern = /{{([^}]*)}}/g,
|
|
matches = link.match(pattern),
|
|
params = [];
|
|
return matches && matches.forEach(function(el) {
|
|
var key = el.replace("{{", "").replace("}}", "");
|
|
params.push(key)
|
|
}), params
|
|
}
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
controller: controller,
|
|
templateUrl: "../common/displaycontrols/navigationlinks/views/navigationLinks.html",
|
|
scope: {
|
|
params: "=",
|
|
linkParams: "="
|
|
}
|
|
}
|
|
}]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.DisplayControl = Bahmni.Common.DisplayControl || {}, Bahmni.Common.DisplayControl.PacsOrders = Bahmni.Common.DisplayControl.PacsOrders || {}, angular.module("bahmni.common.displaycontrol.pacsOrders", []), angular.module("bahmni.common.displaycontrol.pacsOrders").directive("pacsOrders", ["orderService", "orderTypeService", "spinner", "messagingService", "$window", function(orderService, orderTypeService, spinner, messagingService, $window) {
|
|
var controller = function($scope) {
|
|
$scope.orderTypeUuid = orderTypeService.getOrderTypeUuid($scope.orderType);
|
|
var includeAllObs = !0,
|
|
getOrders = function() {
|
|
var params = {
|
|
patientUuid: $scope.patient.uuid,
|
|
orderTypeUuid: $scope.orderTypeUuid,
|
|
conceptNames: $scope.config.conceptNames,
|
|
includeObs: includeAllObs,
|
|
numberOfVisits: $scope.config.numberOfVisits,
|
|
obsIgnoreList: $scope.config.obsIgnoreList,
|
|
visitUuid: $scope.visitUuid,
|
|
orderUuid: $scope.orderUuid
|
|
};
|
|
return orderService.getOrders(params).then(function(response) {
|
|
$scope.bahmniOrders = response.data, _.each($scope.bahmniOrders, function(order) {
|
|
order.pacsImageUrl = ($scope.config.pacsImageUrl || "").replace("{{patientID}}", $scope.patient.identifier).replace("{{orderNumber}}", order.orderNumber)
|
|
})
|
|
})
|
|
},
|
|
init = function() {
|
|
return getOrders().then(function() {
|
|
_.isEmpty($scope.bahmniOrders) && ($scope.noOrdersMessage = $scope.orderType, $scope.$emit("no-data-present-event"))
|
|
})
|
|
};
|
|
$scope.getUrl = function(orderNumber) {
|
|
var pacsImageTemplate = $scope.config.pacsImageUrl || "";
|
|
return pacsImageTemplate.replace("{{patientID}}", $scope.patient.identifier).replace("{{orderNumber}}", orderNumber)
|
|
}, $scope.getLabel = function(bahmniOrder) {
|
|
return bahmniOrder.concept.shortName || bahmniOrder.concept.name
|
|
}, $scope.openImage = function(bahmniOrder) {
|
|
var url = bahmniOrder.pacsImageUrl;
|
|
spinner.forAjaxPromise($.ajax({
|
|
type: "HEAD",
|
|
url: url,
|
|
async: !1
|
|
}).then(function() {
|
|
$window.open(url, "_blank")
|
|
}, function() {
|
|
messagingService.showMessage("info", "No image available yet for order: " + $scope.getLabel(bahmniOrder))
|
|
}))
|
|
}, $scope.initialization = init()
|
|
},
|
|
link = function($scope, element) {
|
|
spinner.forPromise($scope.initialization, element)
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
controller: controller,
|
|
link: link,
|
|
templateUrl: "../common/displaycontrols/pacsOrders/views/pacsOrders.html",
|
|
scope: {
|
|
patient: "=",
|
|
section: "=",
|
|
orderType: "=",
|
|
orderUuid: "=",
|
|
config: "=",
|
|
visitUuid: "="
|
|
}
|
|
}
|
|
}]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.DisplayControl = Bahmni.Common.DisplayControl || {}, Bahmni.Common.DisplayControl.Custom = Bahmni.Common.DisplayControl.Custom || {}, angular.module("bahmni.common.displaycontrol.custom", []), angular.module("bahmni.common.displaycontrol.custom").directive("customDisplayControl", [function() {
|
|
return {
|
|
restrict: "E",
|
|
template: '<div compile-html="config.template"></div>',
|
|
scope: {
|
|
patient: "=",
|
|
visitUuid: "=",
|
|
section: "=",
|
|
config: "=",
|
|
enrollment: "=",
|
|
params: "=",
|
|
visitSummary: "="
|
|
}
|
|
}
|
|
}]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.UIControls = Bahmni.Common.UIControls || {}, angular.module("bahmni.common.uicontrols", []);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.UIControls = Bahmni.Common.UIControls || {}, Bahmni.Common.UIControls.ProgramManagement = Bahmni.Common.UIControls.ProgramManagement || {}, angular.module("bahmni.common.uicontrols.programmanagment", []), angular.module("bahmni.common.uicontrols.programmanagment").controller("ManageProgramController", ["$scope", "retrospectiveEntryService", "$window", "programService", "spinner", "messagingService", "$stateParams", "$q", "confirmBox", function($scope, retrospectiveEntryService, $window, programService, spinner, messagingService, $stateParams, $q, confirmBox) {
|
|
var DateUtil = Bahmni.Common.Util.DateUtil;
|
|
$scope.programSelected = {}, $scope.workflowStateSelected = {}, $scope.allPrograms = [], $scope.programWorkflowStates = [], $scope.workflowStatesWithoutCurrentState = [], $scope.outComesForProgram = [], $scope.configName = $stateParams.configName, $scope.today = DateUtil.getDateWithoutTime(DateUtil.now());
|
|
var id = "#programEnrollmentContainer",
|
|
updateActiveProgramsList = function() {
|
|
spinner.forPromise(programService.getPatientPrograms($scope.patient.uuid).then(function(programs) {
|
|
$scope.activePrograms = programs.activePrograms, _.each($scope.activePrograms, function(patientProgram) {
|
|
populateDefaultSelectedState(patientProgram)
|
|
}), $scope.activePrograms.showProgramSection = !0, $scope.endedPrograms = programs.endedPrograms, $scope.endedPrograms.showProgramSection = !0
|
|
}).then(function() {
|
|
formatProgramDates()
|
|
}), id)
|
|
},
|
|
populateDefaultSelectedState = function(patientProgram) {
|
|
var activePatientProgramState = getActivePatientProgramState(patientProgram.states);
|
|
patientProgram.selectedState = activePatientProgramState ? activePatientProgramState.state : null
|
|
},
|
|
formatProgramDates = function() {
|
|
_.each($scope.activePrograms, function(activeProgram) {
|
|
activeProgram.fromDate = Bahmni.Common.Util.DateUtil.parseLongDateToServerFormat(activeProgram.dateEnrolled), activeProgram.toDate = Bahmni.Common.Util.DateUtil.parseLongDateToServerFormat(activeProgram.dateCompleted)
|
|
}), _.each($scope.endedPrograms, function(endedProgram) {
|
|
endedProgram.fromDate = Bahmni.Common.Util.DateUtil.parseLongDateToServerFormat(endedProgram.dateEnrolled), endedProgram.toDate = Bahmni.Common.Util.DateUtil.parseLongDateToServerFormat(endedProgram.dateCompleted)
|
|
})
|
|
},
|
|
getCurrentDate = function() {
|
|
var retrospectiveDate = retrospectiveEntryService.getRetrospectiveDate();
|
|
return DateUtil.parseLongDateToServerFormat(retrospectiveDate)
|
|
},
|
|
init = function() {
|
|
spinner.forPromise(programService.getAllPrograms().then(function(programs) {
|
|
$scope.allPrograms = programs, $scope.allPrograms.showProgramSection = !0
|
|
}), id), spinner.forPromise(programService.getProgramAttributeTypes().then(function(programAttributeTypes) {
|
|
$scope.programAttributeTypes = programAttributeTypes
|
|
}), id), $scope.programSelected = null, $scope.patientProgramAttributes = {}, $scope.programEnrollmentDate = null, updateActiveProgramsList()
|
|
},
|
|
successCallback = function() {
|
|
messagingService.showMessage("info", "CLINICAL_SAVE_SUCCESS_MESSAGE_KEY"), $scope.programSelected = null, $scope.workflowStateSelected = null, $scope.patientProgramAttributes = {}, $scope.programEnrollmentDate = null, updateActiveProgramsList(), $scope.patientProgram && ($scope.patientProgram.editing = !1)
|
|
},
|
|
failureCallback = function(error) {
|
|
var fieldErrorMsg = findFieldErrorIfAny(error),
|
|
errorMsg = _.isUndefined(fieldErrorMsg) ? "Failed to Save" : fieldErrorMsg;
|
|
messagingService.showMessage("error", errorMsg)
|
|
},
|
|
findFieldErrorIfAny = function(error) {
|
|
var stateFieldError = objectDeepFind(error, "data.error.fieldErrors.states"),
|
|
errorField = stateFieldError && stateFieldError[0];
|
|
return errorField && errorField.message
|
|
},
|
|
objectDeepFind = function(obj, path) {
|
|
if (!_.isUndefined(obj)) {
|
|
var i, paths = path.split("."),
|
|
current = obj;
|
|
for (i = 0; i < paths.length; ++i) {
|
|
if (void 0 == current[paths[i]]) return;
|
|
current = current[paths[i]]
|
|
}
|
|
return current
|
|
}
|
|
},
|
|
isThePatientAlreadyEnrolled = function() {
|
|
return _.map($scope.activePrograms, function(program) {
|
|
return program.program.uuid
|
|
}).indexOf($scope.programSelected.uuid) > -1
|
|
},
|
|
isProgramSelected = function() {
|
|
return $scope.programSelected && $scope.programSelected.uuid
|
|
};
|
|
$scope.hasPatientEnrolledToSomePrograms = function() {
|
|
return !_.isEmpty($scope.activePrograms)
|
|
}, $scope.hasPatientAnyPastPrograms = function() {
|
|
return !_.isEmpty($scope.endedPrograms)
|
|
}, $scope.enrollPatient = function() {
|
|
if (!isProgramSelected()) return messagingService.showMessage("error", "PROGRAM_MANAGEMENT_SELECT_PROGRAM_MESSAGE_KEY"), $q.when({});
|
|
if (isThePatientAlreadyEnrolled()) return messagingService.showMessage("error", "PROGRAM_MANAGEMENT_ALREADY_ENROLLED_PROGRAM_MESSAGE_KEY"), $q.when({});
|
|
var stateUuid = $scope.workflowStateSelected && $scope.workflowStateSelected.uuid ? $scope.workflowStateSelected.uuid : null;
|
|
return spinner.forPromise(programService.enrollPatientToAProgram($scope.patient.uuid, $scope.programSelected.uuid, $scope.programEnrollmentDate, stateUuid, $scope.patientProgramAttributes, $scope.programAttributeTypes).then(successCallback, failureCallback))
|
|
};
|
|
var isProgramStateChanged = function(patientProgram, activePatientProgramState) {
|
|
return !(!_.isEmpty(activePatientProgramState) || void 0 == patientProgram.selectedState) || patientProgram.selectedState && patientProgram.selectedState.uuid != activePatientProgramState.state.uuid
|
|
},
|
|
isOutcomeSelected = function(patientProgram) {
|
|
return !_.isEmpty(objectDeepFind(patientProgram, "outcomeData.uuid"))
|
|
},
|
|
getActivePatientProgramState = function(states) {
|
|
return _.find(states, function(state) {
|
|
return null == state.endDate && !state.voided
|
|
})
|
|
};
|
|
$scope.updatePatientProgram = function(patientProgram) {
|
|
$scope.patientProgram = patientProgram;
|
|
var activePatientProgramState = getActivePatientProgramState(patientProgram.states),
|
|
activeStateDate = activePatientProgramState ? DateUtil.parse(activePatientProgramState.startDate) : null,
|
|
dateCompleted = null;
|
|
if (isProgramStateChanged(patientProgram, activePatientProgramState)) {
|
|
var startDate = getCurrentDate();
|
|
if (activePatientProgramState && DateUtil.isBeforeDate(startDate, activeStateDate)) return void messagingService.showMessage("error", "PROGRAM_MANAGEMENT_STATE_CANT_START_BEFORE_KEY (" + DateUtil.formatDateWithoutTime(activeStateDate) + ")");
|
|
patientProgram.states.push({
|
|
state: {
|
|
uuid: patientProgram.selectedState.uuid
|
|
},
|
|
startDate: startDate
|
|
})
|
|
}
|
|
return isOutcomeSelected(patientProgram) && (dateCompleted = DateUtil.getDateWithoutTime(getCurrentDate()), activePatientProgramState && DateUtil.isBeforeDate(dateCompleted, activeStateDate)) ? void messagingService.showMessage("error", "PROGRAM_MANAGEMENT_PROGRAM_CANT_END_BEFORE_KEY (" + DateUtil.formatDateWithoutTime(activeStateDate) + ")") : void spinner.forPromise(programService.updatePatientProgram(patientProgram, $scope.programAttributeTypes, dateCompleted).then(successCallback, failureCallback))
|
|
};
|
|
var voidPatientProgram = function(patientProgram, closeConfirmBox) {
|
|
patientProgram.voided = !0;
|
|
var promise = programService.updatePatientProgram(patientProgram, $scope.programAttributeTypes).then(successCallback, failureCallback).then(closeConfirmBox);
|
|
spinner.forPromise(promise)
|
|
},
|
|
unVoidPatientProgram = function(patientProgram, closeConfirmBox) {
|
|
delete patientProgram.voidReason, delete patientProgram.voided, patientProgram.deleting = !1, closeConfirmBox()
|
|
};
|
|
$scope.confirmDeletion = function(patientProgram) {
|
|
var scope = {};
|
|
scope.message = "Are you sure, you want to delete " + patientProgram.display + "?", scope.cancel = _.partial(unVoidPatientProgram, patientProgram, _), scope["delete"] = _.partial(voidPatientProgram, patientProgram, _), confirmBox({
|
|
scope: scope,
|
|
actions: [{
|
|
name: "cancel",
|
|
display: "cancel"
|
|
}, {
|
|
name: "delete",
|
|
display: "delete"
|
|
}],
|
|
className: "ngdialog-theme-default delete-program-popup"
|
|
})
|
|
}, $scope.toggleDelete = function(program) {
|
|
program.deleting = !program.deleting
|
|
}, $scope.toggleEdit = function(program) {
|
|
$scope.tempProgram = angular.copy(program), program.editing = !program.editing
|
|
}, $scope.cancelChange = function(program) {
|
|
populateDefaultSelectedState(program), program.patientProgramAttributes = $scope.tempProgram.patientProgramAttributes, program.editing = !program.editing
|
|
}, $scope.setWorkflowStates = function(program) {
|
|
$scope.patientProgramAttributes = {}, $scope.programWorkflowStates = $scope.getStates(program)
|
|
}, $scope.getStates = function(program) {
|
|
var states = [];
|
|
return program && program.allWorkflows && program.allWorkflows.length && program.allWorkflows[0].states.length && (states = program.allWorkflows[0].states), states
|
|
}, $scope.canRemovePatientState = function(state) {
|
|
return null == state.endDate
|
|
}, $scope.removePatientState = function(patientProgram) {
|
|
var currProgramState = getActivePatientProgramState(patientProgram.states),
|
|
currProgramStateUuid = objectDeepFind(currProgramState, "uuid");
|
|
spinner.forPromise(programService.deletePatientState(patientProgram.uuid, currProgramStateUuid).then(successCallback, failureCallback))
|
|
}, $scope.hasStates = function(program) {
|
|
return program && !_.isEmpty(program.allWorkflows) && !_.isEmpty($scope.programWorkflowStates)
|
|
}, $scope.hasProgramWorkflowStates = function(patientProgram) {
|
|
return !_.isEmpty($scope.getStates(patientProgram.program))
|
|
}, $scope.hasOutcomes = function(program) {
|
|
return program.outcomesConcept && !_.isEmpty(program.outcomesConcept.setMembers)
|
|
}, $scope.getCurrentStateDisplayName = function(program) {
|
|
var currentState = getActivePatientProgramState(program.states);
|
|
return _.get(currentState, "state.concept.display")
|
|
}, $scope.getMaxAllowedDate = function(states) {
|
|
var minStartDate = DateUtil.getDateWithoutTime(new Date);
|
|
if (states && angular.isArray(states))
|
|
for (var stateIndex = 0; stateIndex < states.length; stateIndex++) states[stateIndex].startDate < minStartDate && (minStartDate = states[stateIndex].startDate);
|
|
return minStartDate
|
|
}, $scope.isIncluded = function(attribute) {
|
|
return !($scope.programSelected && _.includes(attribute.excludeFrom, $scope.programSelected.name))
|
|
}, init()
|
|
}]), angular.module("bahmni.common.uicontrols.programmanagment").service("programHelper", ["appService", function(appService) {
|
|
function shouldDisplayAllAttributes(programDisplayControlConfig) {
|
|
return programDisplayControlConfig && void 0 == programDisplayControlConfig.programAttributes || void 0 == programDisplayControlConfig
|
|
}
|
|
var self = this,
|
|
programConfiguration = appService.getAppDescriptor().getConfig("program") && appService.getAppDescriptor().getConfig("program").value,
|
|
isAttributeRequired = function(attribute) {
|
|
var attributeName = attribute.attributeType.display;
|
|
return programConfiguration && programConfiguration[attributeName] && programConfiguration[attributeName].required
|
|
};
|
|
this.filterRetiredPrograms = function(programs) {
|
|
return _.filter(programs, function(program) {
|
|
return !program.retired
|
|
})
|
|
}, this.filterRetiredWorkflowsAndStates = function(workflows) {
|
|
var allWorkflows = _.filter(workflows, function(workflow) {
|
|
return !workflow.retired
|
|
});
|
|
return _.forEach(allWorkflows, function(workflow) {
|
|
workflow.states = _.filter(workflow.states, function(state) {
|
|
return !state.retired
|
|
})
|
|
}), allWorkflows
|
|
}, this.filterRetiredOutcomes = function(outcomes) {
|
|
return _.filter(outcomes, function(outcome) {
|
|
return !outcome.retired
|
|
})
|
|
};
|
|
var mapAttributes = function(attribute) {
|
|
attribute.name = attribute.attributeType.description ? attribute.attributeType.description : attribute.name, attribute.value = attribute.value, attribute.required = isAttributeRequired(attribute)
|
|
},
|
|
mapPrograms = function(program) {
|
|
program.dateEnrolled = Bahmni.Common.Util.DateUtil.parseServerDateToDate(program.dateEnrolled), program.dateCompleted = Bahmni.Common.Util.DateUtil.parseServerDateToDate(program.dateCompleted), program.program.allWorkflows = self.filterRetiredWorkflowsAndStates(program.program.allWorkflows), _.forEach(program.attributes, function(attribute) {
|
|
mapAttributes(attribute)
|
|
})
|
|
};
|
|
this.filterProgramAttributes = function(patientPrograms, programAttributeTypes) {
|
|
var programDisplayControlConfig = appService.getAppDescriptor().getConfigValue("programDisplayControl"),
|
|
config = programDisplayControlConfig ? programDisplayControlConfig.programAttributes : [],
|
|
configAttrList = [];
|
|
return configAttrList = shouldDisplayAllAttributes(programDisplayControlConfig) ? programAttributeTypes : programAttributeTypes.filter(function(each) {
|
|
return config && config.indexOf(each.name) !== -1
|
|
}), _.isEmpty(configAttrList) ? patientPrograms.map(function(patientProgram) {
|
|
return patientProgram.attributes = [], patientProgram
|
|
}) : (patientPrograms.forEach(function(program) {
|
|
var attrsToBeDisplayed = [];
|
|
configAttrList.forEach(function(configAttr) {
|
|
var attr = _.find(program.attributes, function(progAttr) {
|
|
return progAttr.attributeType.display === configAttr.name
|
|
});
|
|
attr = attr ? attr : {
|
|
value: ""
|
|
}, attr.attributeType = configAttr, attr.attributeType.display = configAttr.name, attrsToBeDisplayed.push(attr)
|
|
}), program.attributes = attrsToBeDisplayed
|
|
}), patientPrograms)
|
|
}, this.groupPrograms = function(patientPrograms) {
|
|
var activePrograms = [],
|
|
endedPrograms = [],
|
|
groupedPrograms = {};
|
|
if (patientPrograms) {
|
|
var filteredPrograms = this.filterRetiredPrograms(patientPrograms);
|
|
_.forEach(filteredPrograms, function(program) {
|
|
mapPrograms(program), program.dateCompleted ? endedPrograms.push(program) : activePrograms.push(program)
|
|
}), groupedPrograms.activePrograms = _.sortBy(activePrograms, function(program) {
|
|
return moment(program.dateEnrolled).toDate()
|
|
}).reverse(), groupedPrograms.endedPrograms = _.sortBy(endedPrograms, function(program) {
|
|
return moment(program.dateCompleted).toDate()
|
|
}).reverse()
|
|
}
|
|
return groupedPrograms
|
|
}
|
|
}]), angular.module("bahmni.common.uicontrols.programmanagment").directive("managePrograms", function() {
|
|
return {
|
|
templateUrl: "../common/uicontrols/programmanagement/views/programEnrollment.html",
|
|
controller: "ManageProgramController",
|
|
scope: {
|
|
patient: "="
|
|
}
|
|
}
|
|
}), angular.module("bahmni.common.uicontrols.programmanagment").controller("ProgramAttributesController", ["$scope", function($scope) {
|
|
var program = $scope.patientProgram.program;
|
|
$scope.getProgramAttributesMap = function() {
|
|
var programAttributesMap = {},
|
|
programAttributes = $scope.patientProgram.attributes;
|
|
return _.forEach($scope.programAttributeTypes, function(programAttributeType) {
|
|
var programAttribute = getProgramAttributeByType(programAttributes, programAttributeType);
|
|
void 0 == programAttribute || programAttribute.voided || (programAttributesMap[programAttributeType.name] = programAttribute.value, isCodedConceptFormat(programAttributeType.format) ? programAttributesMap[programAttributeType.name] = programAttribute.value && programAttribute.value.uuid : isDateFormat(programAttributeType.format) && (programAttributesMap[programAttributeType.name] = Bahmni.Common.Util.DateUtil.parseServerDateToDate(programAttributesMap[programAttributeType.name])))
|
|
}), programAttributesMap
|
|
}, $scope.getValueForAttributeType = function(attributeType) {
|
|
var programAttributesMap = $scope.patientProgram.patientProgramAttributes;
|
|
if (isDateFormat(attributeType.format)) return programAttributesMap[attributeType.name] ? Bahmni.Common.Util.DateUtil.formatDateWithoutTime(programAttributesMap[attributeType.name]) : "";
|
|
if (isCodedConceptFormat(attributeType.format)) {
|
|
var mrsAnswer = _.find(attributeType.answers, function(answer) {
|
|
return answer.conceptId == programAttributesMap[attributeType.name]
|
|
});
|
|
return mrsAnswer ? mrsAnswer.description : ""
|
|
}
|
|
return programAttributesMap[attributeType.name]
|
|
}, $scope.isIncluded = function(attribute) {
|
|
return !(program && _.includes(attribute.excludeFrom, program.name))
|
|
};
|
|
var getProgramAttributeByType = function(programAttributes, attributeType) {
|
|
return _.find(programAttributes, function(programAttribute) {
|
|
return programAttribute.attributeType.uuid == attributeType.uuid
|
|
})
|
|
},
|
|
isDateFormat = function(format) {
|
|
return "org.openmrs.util.AttributableDate" == format || "org.openmrs.customdatatype.datatype.DateDatatype" == format
|
|
},
|
|
isCodedConceptFormat = function(format) {
|
|
return "org.bahmni.module.bahmnicore.customdatatype.datatype.CodedConceptDatatype" == format
|
|
};
|
|
$scope.patientProgram.patientProgramAttributes = $scope.getProgramAttributesMap()
|
|
}]).directive("programAttributes", function() {
|
|
return {
|
|
controller: "ProgramAttributesController",
|
|
templateUrl: "../common/uicontrols/programmanagement/views/programAttributes.html",
|
|
scope: {
|
|
patientProgram: "=",
|
|
programAttributeTypes: "="
|
|
}
|
|
}
|
|
}), angular.module("bahmni.common.uicontrols.programmanagment").directive("timeline", ["$timeout", function($timeout) {
|
|
var link = function($scope, $element) {
|
|
$timeout(function() {
|
|
var dateUtil = Bahmni.Common.Util.DateUtil,
|
|
data = getDataModel($scope.program),
|
|
svg = d3.select($element[0]).select(".timeline-view").append("svg"),
|
|
elementDimension = $element[0].getBoundingClientRect(),
|
|
sortedDates = _.map(data.states, "date"),
|
|
xMin = 0,
|
|
xMax = elementDimension.width - 15,
|
|
endDate = $scope.program.dateCompleted ? dateUtil.parse($scope.program.dateCompleted) : new Date,
|
|
dateFormatter = d3.time.format("%_d %b%y"),
|
|
timeScale = d3.time.scale().domain([sortedDates[0], endDate]).range([xMin, xMax]),
|
|
states = svg.selectAll(".states").data(data.states),
|
|
stateGroup = states.enter().append("g").classed("states", !0),
|
|
tooltipEl = d3.select($element[0]).select(".tool-tip"),
|
|
showTooltip = function(d) {
|
|
var eventEl = this;
|
|
tooltipEl.html(function() {
|
|
return dateFormatter(d.date) + " | " + d.state
|
|
}).style("left", function() {
|
|
var tooltipWidth = $(this).width(),
|
|
eventX = eventEl.getBBox().x,
|
|
posX = eventX + tooltipWidth > elementDimension.width ? elementDimension.width - tooltipWidth : eventX;
|
|
return posX + "px"
|
|
}).style("visibility", "visible")
|
|
};
|
|
stateGroup.append("rect").classed("label-bg", !0), stateGroup.append("text").classed("label", !0), stateGroup.append("rect").classed("date-bg", !0), stateGroup.append("line").classed("date-line", !0), stateGroup.append("text").classed("date", !0);
|
|
var stateBar = {
|
|
y: 5,
|
|
height: 23,
|
|
textPaddingX: 6
|
|
},
|
|
dateBar = {
|
|
y: 30,
|
|
height: 30,
|
|
xPadding: -4,
|
|
textPaddingY: 53
|
|
},
|
|
dateTick = {
|
|
y: 0,
|
|
height: 40
|
|
};
|
|
states.select(".label-bg").attr("x", function(d) {
|
|
return timeScale(d.date)
|
|
}).attr("y", stateBar.y).attr("height", stateBar.height).attr("width", function(d) {
|
|
return xMax - timeScale(d.date)
|
|
}), states.select(".label").attr("x", function(d) {
|
|
return timeScale(d.date) + stateBar.textPaddingX
|
|
}).attr("y", stateBar.y + .7 * stateBar.height).text(function(d) {
|
|
return d.state
|
|
}), states.select(".date-bg").attr("x", function(d) {
|
|
return timeScale(d.date) + dateBar.xPadding
|
|
}).attr("y", dateBar.y).attr("height", dateBar.height).attr("width", xMax), states.select(".date-line").attr("x1", function(d) {
|
|
return timeScale(d.date)
|
|
}).attr("y1", dateTick.y).attr("x2", function(d) {
|
|
return timeScale(d.date)
|
|
}).attr("y2", dateTick.y + dateTick.height), states.select(".date").attr("x", function(d) {
|
|
return timeScale(d.date)
|
|
}).attr("y", dateBar.textPaddingY).text(function(d) {
|
|
return dateFormatter(d.date)
|
|
}), states.select(".label-bg").on("mouseenter", showTooltip), states.select(".label-bg").on("click", showTooltip), states.select(".label-bg").on("mouseout", function() {
|
|
tooltipEl.style("visibility", "hidden")
|
|
}), data.completed || _.isEmpty(data.states) || svg.append("polygon").attr("points", xMax + "," + stateBar.y + " " + (xMax + 12) + "," + (stateBar.y + stateBar.height / 2) + " " + (xMax - 1) + "," + (stateBar.y + stateBar.height))
|
|
}, 0)
|
|
},
|
|
getActiveProgramStates = function(patientProgram) {
|
|
return _.reject(patientProgram.states, function(st) {
|
|
return st.voided
|
|
})
|
|
},
|
|
getDataModel = function(program) {
|
|
var states = _.sortBy(_.map(getActiveProgramStates(program), function(stateObject) {
|
|
return {
|
|
state: stateObject.state.concept.display,
|
|
date: moment(stateObject.startDate).toDate()
|
|
}
|
|
}), "date"),
|
|
completed = isProgramCompleted(program);
|
|
return {
|
|
states: states,
|
|
completed: completed
|
|
}
|
|
},
|
|
isProgramCompleted = function(program) {
|
|
return !_.isEmpty(program.dateCompleted)
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
templateUrl: "../common/uicontrols/programmanagement/views/timeline.html",
|
|
link: link,
|
|
scope: {
|
|
program: "="
|
|
}
|
|
}
|
|
}]), Bahmni.Common.Domain.PatientProgramMapper = function() {
|
|
this.map = function(patientProgram, programAttributeTypes, dateCompleted) {
|
|
var attributeFormatter = new Bahmni.Common.Domain.AttributeFormatter;
|
|
return {
|
|
dateEnrolled: moment(Bahmni.Common.Util.DateUtil.getDateWithoutTime(patientProgram.dateEnrolled)).format(Bahmni.Common.Constants.ServerDateTimeFormat),
|
|
states: patientProgram.states,
|
|
uuid: patientProgram.uuid,
|
|
dateCompleted: dateCompleted ? moment(dateCompleted).format(Bahmni.Common.Constants.ServerDateTimeFormat) : null,
|
|
outcome: patientProgram.outcomeData ? patientProgram.outcomeData.uuid : null,
|
|
attributes: attributeFormatter.getMrsAttributesForUpdate(patientProgram.patientProgramAttributes, programAttributeTypes, patientProgram.attributes),
|
|
voided: !!patientProgram.voided,
|
|
voidReason: patientProgram.voidReason
|
|
}
|
|
}
|
|
},
|
|
function() {
|
|
var constructSearchResult = function(concept) {
|
|
var conceptName = concept.shortName || concept.name.name || concept.name;
|
|
return {
|
|
label: conceptName,
|
|
value: conceptName,
|
|
concept: concept,
|
|
uuid: concept.uuid,
|
|
name: conceptName
|
|
}
|
|
},
|
|
find = function(allAnswers, savedAnswer) {
|
|
return _.find(allAnswers, function(answer) {
|
|
return savedAnswer && savedAnswer.uuid === answer.concept.uuid
|
|
})
|
|
},
|
|
toBeInjected = ["conceptService"],
|
|
conceptDropdown = function(conceptService) {
|
|
var controller = function($scope) {
|
|
$scope.onChange = $scope.onChange();
|
|
var response = function(answers) {
|
|
$scope.answers = answers, $scope.selectedAnswer = find(answers, $scope.selectedAnswer)
|
|
};
|
|
return !$scope.answersConceptName && $scope.defaultConcept ? void conceptService.getAnswers($scope.defaultConcept).then(function(results) {
|
|
return _.map(results, constructSearchResult)
|
|
}).then(response) : void conceptService.getAnswersForConceptName({
|
|
answersConceptName: $scope.answersConceptName
|
|
}).then(function(results) {
|
|
return _.map(results, constructSearchResult)
|
|
}).then(response)
|
|
};
|
|
return {
|
|
controller: controller,
|
|
restrict: "E",
|
|
scope: {
|
|
selectedAnswer: "=model",
|
|
answersConceptName: "=?",
|
|
defaultConcept: "=",
|
|
onChange: "&",
|
|
onInvalidClass: "@",
|
|
isValid: "=",
|
|
ngDisabled: "="
|
|
},
|
|
templateUrl: "../common/uicontrols/concept-dropdown/views/conceptDropdown.html"
|
|
}
|
|
};
|
|
conceptDropdown.$inject = toBeInjected, angular.module("bahmni.common.uicontrols").directive("conceptDropdown", conceptDropdown)
|
|
}(), angular.module("bahmni.common.domain").factory("programService", ["$http", "programHelper", "appService", function($http, programHelper, appService) {
|
|
var PatientProgramMapper = new Bahmni.Common.Domain.PatientProgramMapper,
|
|
getAllPrograms = function() {
|
|
return $http.get(Bahmni.Common.Constants.programUrl, {
|
|
params: {
|
|
v: "default"
|
|
}
|
|
}).then(function(response) {
|
|
var allPrograms = programHelper.filterRetiredPrograms(response.data.results);
|
|
return _.forEach(allPrograms, function(program) {
|
|
program.allWorkflows = programHelper.filterRetiredWorkflowsAndStates(program.allWorkflows), program.outcomesConcept && (program.outcomesConcept.setMembers = programHelper.filterRetiredOutcomes(program.outcomesConcept.setMembers))
|
|
}), allPrograms
|
|
})
|
|
},
|
|
enrollPatientToAProgram = function(patientUuid, programUuid, dateEnrolled, stateUuid, patientProgramAttributes, programAttributeTypes) {
|
|
var attributeFormatter = new Bahmni.Common.Domain.AttributeFormatter,
|
|
req = {
|
|
url: Bahmni.Common.Constants.programEnrollPatientUrl,
|
|
content: {
|
|
patient: patientUuid,
|
|
program: programUuid,
|
|
dateEnrolled: moment(dateEnrolled).format(Bahmni.Common.Constants.ServerDateTimeFormat),
|
|
attributes: attributeFormatter.removeUnfilledAttributes(attributeFormatter.getMrsAttributes(patientProgramAttributes, programAttributeTypes || []))
|
|
},
|
|
headers: {
|
|
"Content-Type": "application/json"
|
|
}
|
|
};
|
|
return _.isEmpty(stateUuid) || (req.content.states = [{
|
|
state: stateUuid,
|
|
startDate: moment(dateEnrolled).format(Bahmni.Common.Constants.ServerDateTimeFormat)
|
|
}]), $http.post(req.url, req.content, req.headers)
|
|
},
|
|
getPatientPrograms = function(patientUuid, filterAttributesForProgramDisplayControl, patientProgramUuid) {
|
|
var params = {
|
|
v: "full",
|
|
patientProgramUuid: patientProgramUuid,
|
|
patient: patientUuid
|
|
};
|
|
return $http.get(Bahmni.Common.Constants.programEnrollPatientUrl, {
|
|
params: params
|
|
}).then(function(response) {
|
|
var patientPrograms = response.data.results;
|
|
return getProgramAttributeTypes().then(function(programAttributeTypes) {
|
|
return filterAttributesForProgramDisplayControl && (patientPrograms = programHelper.filterProgramAttributes(response.data.results, programAttributeTypes)), programHelper.groupPrograms(patientPrograms)
|
|
})
|
|
})
|
|
},
|
|
savePatientProgram = function(patientProgramUuid, content) {
|
|
var req = {
|
|
url: Bahmni.Common.Constants.programEnrollPatientUrl + "/" + patientProgramUuid,
|
|
content: content,
|
|
headers: {
|
|
"Content-Type": "application/json"
|
|
}
|
|
};
|
|
return $http.post(req.url, req.content, req.headers)
|
|
},
|
|
deletePatientState = function(patientProgramUuid, patientStateUuid) {
|
|
var req = {
|
|
url: Bahmni.Common.Constants.programStateDeletionUrl + "/" + patientProgramUuid + "/state/" + patientStateUuid,
|
|
content: {
|
|
"!purge": "",
|
|
reason: "User deleted the state."
|
|
},
|
|
headers: {
|
|
"Content-Type": "application/json"
|
|
}
|
|
};
|
|
return $http["delete"](req.url, req.content, req.headers)
|
|
},
|
|
getProgramAttributeTypes = function() {
|
|
return $http.get(Bahmni.Common.Constants.programAttributeTypes, {
|
|
params: {
|
|
v: "custom:(uuid,name,description,datatypeClassname,datatypeConfig,concept)"
|
|
}
|
|
}).then(function(response) {
|
|
var programAttributesConfig = appService.getAppDescriptor().getConfigValue("program"),
|
|
mandatoryProgramAttributes = [];
|
|
for (var attributeName in programAttributesConfig) programAttributesConfig[attributeName].required && mandatoryProgramAttributes.push(attributeName);
|
|
return (new Bahmni.Common.Domain.AttributeTypeMapper).mapFromOpenmrsAttributeTypes(response.data.results, mandatoryProgramAttributes, programAttributesConfig).attributeTypes
|
|
})
|
|
},
|
|
updatePatientProgram = function(patientProgram, programAttributeTypes, dateCompleted) {
|
|
return savePatientProgram(patientProgram.uuid, PatientProgramMapper.map(patientProgram, programAttributeTypes, dateCompleted))
|
|
},
|
|
getProgramStateConfig = function() {
|
|
var config = appService.getAppDescriptor().getConfigValue("programDisplayControl");
|
|
return !!config && config.showProgramStateInTimeline
|
|
},
|
|
getEnrollmentInfoFor = function(patientUuid, representation) {
|
|
var params = {
|
|
patient: patientUuid,
|
|
v: representation
|
|
};
|
|
return $http.get(Bahmni.Common.Constants.programEnrollPatientUrl, {
|
|
params: params
|
|
}).then(function(response) {
|
|
return response.data.results
|
|
})
|
|
};
|
|
return {
|
|
getAllPrograms: getAllPrograms,
|
|
enrollPatientToAProgram: enrollPatientToAProgram,
|
|
getPatientPrograms: getPatientPrograms,
|
|
savePatientProgram: savePatientProgram,
|
|
updatePatientProgram: updatePatientProgram,
|
|
deletePatientState: deletePatientState,
|
|
getProgramAttributeTypes: getProgramAttributeTypes,
|
|
getProgramStateConfig: getProgramStateConfig,
|
|
getEnrollmentInfoFor: getEnrollmentInfoFor
|
|
}
|
|
}]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Clinical = Bahmni.Clinical || {}, Bahmni.Clinical.DisplayControl = Bahmni.Clinical.DisplayControl || {}, angular.module("bahmni.clinical", ["bahmni.common.config", "bahmni.common.domain", "bahmni.common.conceptSet", "bahmni.common.uiHelper", "bahmni.common.gallery", "bahmni.common.logging"]), Bahmni.Clinical.ResultGrouper = function() {}, Bahmni.Clinical.ResultGrouper.prototype.group = function(inputArray, groupKeyFunction, nameForGroupedValue, nameForKey) {
|
|
var result = [],
|
|
arrayInObjectForm = {};
|
|
return nameForKey = nameForKey || "key", nameForGroupedValue = nameForGroupedValue || "values", inputArray.forEach(function(obj) {
|
|
arrayInObjectForm[groupKeyFunction(obj)] ? arrayInObjectForm[groupKeyFunction(obj)].values.push(obj) : arrayInObjectForm[groupKeyFunction(obj)] = {
|
|
values: [obj]
|
|
}
|
|
}), angular.forEach(arrayInObjectForm, function(item, key) {
|
|
var group = {};
|
|
group[nameForKey] = key, group[nameForGroupedValue] = item.values, result.push(group)
|
|
}), result
|
|
}, Bahmni.Clinical.DrugOrder = function() {
|
|
var DateUtil = Bahmni.Common.Util.DateUtil,
|
|
DrugOrder = function(drugOrderData) {
|
|
angular.extend(this, drugOrderData)
|
|
};
|
|
return DrugOrder.create = function(drugOrderData) {
|
|
return new DrugOrder(drugOrderData)
|
|
}, DrugOrder.createFromUIObject = function(drugOrderData) {
|
|
var dateUtil = Bahmni.Common.Util.DateUtil,
|
|
getDosingInstructions = function(drugOrderData) {
|
|
var dosingInstructions = {};
|
|
return dosingInstructions.instructions = drugOrderData.instructions && drugOrderData.instructions, dosingInstructions.additionalInstructions = drugOrderData.additionalInstructions, drugOrderData.frequencyType === Bahmni.Clinical.Constants.dosingTypes.variable ? (dosingInstructions.morningDose = drugOrderData.variableDosingType.morningDose, dosingInstructions.afternoonDose = drugOrderData.variableDosingType.afternoonDose, dosingInstructions.eveningDose = drugOrderData.variableDosingType.eveningDose, drugOrderData["continue"] ? dosingInstructions["continue"] = !0 : dosingInstructions["continue"] = !1) : drugOrderData["continue"] ? dosingInstructions["continue"] = !0 : dosingInstructions["continue"] = !1, JSON.stringify(dosingInstructions)
|
|
},
|
|
frequency = drugOrderData.isUniformDosingType() && !drugOrderData.isCurrentDosingTypeEmpty() && drugOrderData.uniformDosingType.frequency,
|
|
route = drugOrderData.route,
|
|
drugOrder = new DrugOrder({
|
|
careSetting: "OUTPATIENT",
|
|
drug: drugOrderData.drug,
|
|
drugNonCoded: drugOrderData.drugNonCoded,
|
|
orderType: "Drug Order",
|
|
dosingInstructionType: Bahmni.Clinical.Constants.flexibleDosingInstructionsClass,
|
|
dosingInstructions: {
|
|
dose: drugOrderData.uniformDosingType.dose,
|
|
doseUnits: drugOrderData.doseUnits,
|
|
route: route,
|
|
frequency: frequency,
|
|
asNeeded: drugOrderData.asNeeded,
|
|
administrationInstructions: getDosingInstructions(drugOrderData),
|
|
quantity: drugOrderData.quantity,
|
|
quantityUnits: drugOrderData.quantityUnit,
|
|
numberOfRefills: 0
|
|
},
|
|
duration: drugOrderData.duration,
|
|
durationUnits: drugOrderData.durationUnit,
|
|
scheduledDate: dateUtil.parse(drugOrderData.scheduledDate),
|
|
autoExpireDate: dateUtil.parse(drugOrderData.autoExpireDate),
|
|
previousOrderUuid: drugOrderData.previousOrderUuid,
|
|
action: drugOrderData.action,
|
|
orderReasonConcept: drugOrderData.orderReasonConcept,
|
|
orderReasonText: drugOrderData.orderReasonText,
|
|
dateStopped: dateUtil.parse(drugOrderData.dateStopped),
|
|
concept: drugOrderData.concept,
|
|
sortWeight: drugOrderData.sortWeight,
|
|
orderGroup: {
|
|
uuid: drugOrderData.orderGroupUuid,
|
|
orderSet: {
|
|
uuid: drugOrderData.orderSetUuid
|
|
}
|
|
}
|
|
});
|
|
return drugOrder.dosingInstructions.quantityUnits || (drugOrder.dosingInstructions.quantityUnits = "Unit(s)"), drugOrder
|
|
}, DrugOrder.prototype = {
|
|
isActiveOnDate: function(date) {
|
|
return date >= DateUtil.getDate(this.effectiveStartDate) && date <= DateUtil.getDate(this.effectiveStopDate)
|
|
},
|
|
getStatusOnDate: function(date) {
|
|
return DateUtil.isSameDate(this.dateStopped, date) ? "stopped" : this.isActiveOnDate(date) ? "active" : "inactive"
|
|
},
|
|
isActive: function() {
|
|
return this.isActiveOnDate(DateUtil.today())
|
|
}
|
|
}, DrugOrder
|
|
}();
|
|
var constructDrugNameDisplay = function(drug) {
|
|
if (!_.isEmpty(drug)) return drug.name + " (" + drug.form + ")"
|
|
};
|
|
Bahmni.Clinical.DrugOrderViewModel = function(config, proto, encounterDate) {
|
|
angular.copy(proto, this);
|
|
var DateUtil = Bahmni.Common.Util.DateUtil,
|
|
self = this;
|
|
config = config || {};
|
|
var inputOptionsConfig = config.inputOptionsConfig || {},
|
|
drugFormDefaults = inputOptionsConfig.drugFormDefaults || {},
|
|
durationUnits = config.durationUnits || [],
|
|
now = DateUtil.now(),
|
|
today = function() {
|
|
return DateUtil.parse(self.encounterDate)
|
|
};
|
|
Object.defineProperty(this, "effectiveStartDate", {
|
|
get: function() {
|
|
return self._effectiveStartDate
|
|
},
|
|
set: function(value) {
|
|
self._effectiveStartDate = value, DateUtil.parse(value) > today() ? self.scheduledDate = self._effectiveStartDate : self.scheduledDate = null
|
|
},
|
|
enumerable: !0
|
|
}), Object.defineProperty(this, "doseUnits", {
|
|
enumerable: !0,
|
|
get: function() {
|
|
return this.isUniformDosingType() ? this.uniformDosingType.doseUnits : this.isVariableDosingType() ? this.variableDosingType.doseUnits : null
|
|
},
|
|
set: function(value) {
|
|
this.isUniformDosingType() ? this.uniformDosingType.doseUnits = value : this.isVariableDosingType() && (this.variableDosingType.doseUnits = value)
|
|
}
|
|
});
|
|
var getDosingType = function() {
|
|
return self.isUniformDosingType() ? self.uniformDosingType : self.variableDosingType
|
|
},
|
|
destructureReal = function(number) {
|
|
var mantissa = parseFloat((number - Math.floor(number)).toFixed(2)),
|
|
abscissa = Math.ceil(number - mantissa),
|
|
result = _.result(_.find(config.getDoseFractions(), function(item) {
|
|
return item.value === mantissa
|
|
}), "label"),
|
|
response = {
|
|
dose: number,
|
|
fraction: null
|
|
};
|
|
return result && (response.dose = abscissa, response.fraction = {
|
|
label: result,
|
|
value: mantissa
|
|
}), response
|
|
};
|
|
if (this.encounterDate = encounterDate ? encounterDate : now, this.asNeeded = this.asNeeded || !1, this.route = this.route || void 0, this.durationUnit = this.durationUnit || inputOptionsConfig.defaultDurationUnit, this.simpleDrugForm = this.simpleDrugForm || inputOptionsConfig.simpleDrugForm || !1, this.instructions = this.instructions || inputOptionsConfig.defaultInstructions, this.autoExpireDate = this.autoExpireDate || void 0, this.frequencyType = this.frequencyType || Bahmni.Clinical.Constants.dosingTypes.uniform, this.uniformDosingType = this.uniformDosingType || {}, this.uniformDosingType.dose && config.getDoseFractions && !_.isEmpty(config.getDoseFractions())) {
|
|
var destructredNumber = destructureReal(this.uniformDosingType.dose);
|
|
this.uniformDosingType.dose = 0 === destructredNumber.dose ? "" : destructredNumber.dose, destructredNumber.fraction && (this.uniformDosingType.doseFraction = destructredNumber.fraction)
|
|
}
|
|
this.variableDosingType = this.variableDosingType || {}, this.durationInDays = this.durationInDays || 0, this.isDiscontinuedAllowed = this.isDiscontinuedAllowed || !0, this.isEditAllowed = this.isEditAllowed || !0, this.quantityEnteredViaEdit = this.quantityEnteredViaEdit || !1, this.quantityEnteredManually = this.quantityEnteredManually || !1, this.quantityUnitEnteredManually = this.quantityUnitEnteredManually || !1, this.isBeingEdited = this.isBeingEdited || !1, this.orderAttributes = [], this.isNonCodedDrug = this.isNonCodedDrug || !1, this.isDurationRequired = !inputOptionsConfig.duration || 0 != inputOptionsConfig.duration.required, inputOptionsConfig.defaultStartDate !== !1 || this.effectiveStartDate ? this.effectiveStartDate = this.effectiveStartDate || this.encounterDate : this.effectiveStartDate = null, this.isUniformFrequency = !1, this.variableDosingType.morningDose = this.variableDosingType.morningDose || 0, this.variableDosingType.afternoonDose = this.variableDosingType.afternoonDose || 0, this.variableDosingType.eveningDose = this.variableDosingType.eveningDose || 0, this.showExtraInfo = !1, this.overlappingScheduledWith = function(otherDrugOrder) {
|
|
var dateUtil = Bahmni.Common.Util.DateUtil;
|
|
return !otherDrugOrder.effectiveStopDate && !this.effectiveStopDate || (otherDrugOrder.effectiveStopDate ? this.effectiveStopDate ? dateUtil.diffInSeconds(this.effectiveStartDate, otherDrugOrder.effectiveStopDate) <= 0 && dateUtil.diffInSeconds(this.effectiveStopDate, otherDrugOrder.effectiveStartDate) > -1 : dateUtil.diffInSeconds(this.effectiveStartDate, otherDrugOrder.effectiveStartDate) > -1 && dateUtil.diffInSeconds(this.effectiveStartDate, otherDrugOrder.effectiveStopDate) < 1 : dateUtil.diffInSeconds(this.effectiveStopDate, otherDrugOrder.effectiveStartDate) > -1)
|
|
};
|
|
var morphToMixedFraction = function(number) {
|
|
var mantissa = parseFloat((number - Math.floor(number)).toFixed(2)),
|
|
abscissa = Math.ceil(number - mantissa);
|
|
if (!config.getDoseFractions || _.isEmpty(config.getDoseFractions()) || 0 === mantissa) return number;
|
|
var result = _.result(_.find(config.getDoseFractions(), function(item) {
|
|
return item.value === mantissa
|
|
}), "label");
|
|
return result ? abscissa ? "" + abscissa + result : "" + result : number
|
|
},
|
|
simpleDoseAndFrequency = function() {
|
|
var doseAndUnits, uniformDosingType = self.uniformDosingType,
|
|
mantissa = self.uniformDosingType.doseFraction ? self.uniformDosingType.doseFraction.value : 0,
|
|
dose = uniformDosingType.dose ? uniformDosingType.dose : 0;
|
|
return (uniformDosingType.dose || mantissa) && (doseAndUnits = blankIfFalsy(morphToMixedFraction(parseFloat(dose) + mantissa)) + " " + blankIfFalsy(self.doseUnits)), addDelimiter(blankIfFalsy(doseAndUnits), ", ") + addDelimiter(blankIfFalsy(uniformDosingType.frequency), ", ")
|
|
},
|
|
numberBasedDoseAndFrequency = function() {
|
|
var variableDosingType = self.variableDosingType,
|
|
variableDosingString = addDelimiter(morphToMixedFraction(variableDosingType.morningDose || 0) + "-" + morphToMixedFraction(variableDosingType.afternoonDose || 0) + "-" + morphToMixedFraction(variableDosingType.eveningDose || 0), " ");
|
|
if (!self.isVariableDoseEmpty(variableDosingType)) return addDelimiter((variableDosingString + blankIfFalsy(self.doseUnits)).trim(), ", ")
|
|
};
|
|
this.isVariableDoseEmpty = function(variableDosingType) {
|
|
return !variableDosingType.morningDose && !variableDosingType.afternoonDose && !variableDosingType.eveningDose
|
|
};
|
|
var asNeeded = function(asNeeded) {
|
|
return asNeeded && config.translate ? config.translate(null, "MEDICATION_AS_NEEDED") : asNeeded ? "sos" : ""
|
|
},
|
|
blankIfFalsy = function(value) {
|
|
return value ? value.toString().trim() : ""
|
|
},
|
|
getDoseAndFrequency = function() {
|
|
return self.frequencyType === Bahmni.Clinical.Constants.dosingTypes.uniform ? simpleDoseAndFrequency() : numberBasedDoseAndFrequency()
|
|
},
|
|
addDelimiter = function(item, delimiter) {
|
|
return item && item.length > 0 ? item + delimiter : item
|
|
},
|
|
getInstructions = function() {
|
|
if (self.instructions !== Bahmni.Clinical.Constants.asDirectedInstruction) return self.instructions
|
|
},
|
|
getOtherDescription = function(withRoute, withDuration) {
|
|
var otherDescription = addDelimiter(blankIfFalsy(getInstructions()), ", ") + addDelimiter(blankIfFalsy(asNeeded(self.asNeeded)), ", ");
|
|
return withRoute ? otherDescription += addDelimiter(blankIfFalsy(self.route), " - ") : (otherDescription = otherDescription.substring(0, otherDescription.length - 2), otherDescription = addDelimiter(blankIfFalsy(otherDescription), " - ")), withDuration && self.duration && 0 != self.duration && (otherDescription = otherDescription + addDelimiter(blankIfFalsy(self.duration), " ") + addDelimiter(blankIfFalsy(self.durationUnit), ", ")), otherDescription = otherDescription.substring(0, otherDescription.length - 2)
|
|
};
|
|
this.getDoseInformation = function() {
|
|
return getDoseAndFrequency()
|
|
}, this.getDisplayName = function() {
|
|
return this.drugNameDisplay ? this.drugNameDisplay : constructDrugNameDisplay(this.drug)
|
|
}, this.getDrugOrderName = function(showDrugForm) {
|
|
return showDrugForm ? this.getDisplayName() : self.drugNonCoded ? self.drugNonCoded : self.drug.name
|
|
}, this.getDescription = function() {
|
|
return addDelimiter(blankIfFalsy(getDoseAndFrequency()), " ") + getOtherDescription(!0, !0)
|
|
}, this.getDescriptionWithoutRoute = function() {
|
|
return addDelimiter(blankIfFalsy(getDoseAndFrequency()), " ") + getOtherDescription(!1, !0)
|
|
}, this.getDescriptionWithoutRouteAndDuration = function() {
|
|
var otherDescription = getOtherDescription(!1, !1),
|
|
description = addDelimiter(blankIfFalsy(getDoseAndFrequency()), " ");
|
|
return otherDescription ? description + otherDescription : description.substring(0, description.length - 2)
|
|
}, this.getDescriptionWithoutDuration = function() {
|
|
var otherDescription = getOtherDescription(!0, !1),
|
|
description = addDelimiter(blankIfFalsy(getDoseAndFrequency()), " ");
|
|
return otherDescription ? description + otherDescription : description.substring(0, description.length - 2)
|
|
}, this.getDescriptionWithQuantity = function() {
|
|
var description = self.getDescription(),
|
|
qtywithUnit = self.getQuantityWithUnit();
|
|
return _.isEmpty(qtywithUnit) ? description : addDelimiter(description, "(") + addDelimiter(qtywithUnit, ")")
|
|
}, this.getQuantityWithUnit = function() {
|
|
return this.simpleDrugForm === !0 || 0 === self.quantity ? "" : addDelimiter(blankIfFalsy(self.quantity), " ") + blankIfFalsy(quantityUnitsFrom(self.quantityUnit))
|
|
};
|
|
var getFrequencyPerDay = function() {
|
|
var frequency = self.isUniformDosingType() && _.find(config.frequencies, function(frequency) {
|
|
return self.uniformDosingType.frequency && frequency.name === self.uniformDosingType.frequency
|
|
});
|
|
return frequency && frequency.frequencyPerDay
|
|
},
|
|
findAnElement = function(array, element) {
|
|
var found = _.find(array, function(arrayElement) {
|
|
return arrayElement.name === element
|
|
});
|
|
return found ? element : void 0
|
|
},
|
|
getDoseUnits = function(doseUnit) {
|
|
return findAnElement(config.doseUnits, doseUnit)
|
|
},
|
|
getRoute = function(route) {
|
|
return findAnElement(config.routes, route)
|
|
};
|
|
this.changeDrug = function(drug) {
|
|
if (this.drug = drug, drug) {
|
|
var defaults = drugFormDefaults[this.drug.form];
|
|
defaults && (this.doseUnits = getDoseUnits(defaults.doseUnits), this.route = getRoute(defaults.route))
|
|
}
|
|
}, this.calculateDurationUnit = function() {
|
|
if (self.frequencyType === Bahmni.Clinical.Constants.dosingTypes.uniform && null != self.uniformDosingType.frequency) {
|
|
var defaultDurationUnitMap = inputOptionsConfig.frequencyDefaultDurationUnitsMap || [];
|
|
defaultDurationUnitMap.forEach(function(range) {
|
|
var minFrequency = eval(range.minFrequency),
|
|
maxFrequency = eval(range.maxFrequency);
|
|
(!minFrequency || minFrequency < getFrequencyPerDay()) && (!maxFrequency || getFrequencyPerDay() <= maxFrequency) && (self.durationUnit = range.defaultDurationUnit)
|
|
})
|
|
}
|
|
}, this.setFrequencyType = function(type) {
|
|
self.frequencyType = type, self.frequencyType === Bahmni.Clinical.Constants.dosingTypes.variable ? (self.uniformDosingType.doseUnits && (self.variableDosingType.doseUnits = self.uniformDosingType.doseUnits), self.uniformDosingType = {}) : (self.variableDosingType.doseUnits && (self.uniformDosingType.doseUnits = self.variableDosingType.doseUnits), self.variableDosingType = {})
|
|
}, this.toggleFrequency = function() {
|
|
this.isUniformFrequency ? (self.frequencyType = Bahmni.Clinical.Constants.dosingTypes.variable, self.setFrequencyType(self.frequencyType), this.isUniformFrequency = !1) : (self.frequencyType = Bahmni.Clinical.Constants.dosingTypes.uniform, self.setFrequencyType(self.frequencyType), this.isUniformFrequency = !0)
|
|
}, this.toggleExtraInfo = function() {
|
|
this.showExtraInfo = !this.showExtraInfo
|
|
}, this.isCurrentDosingTypeEmpty = function() {
|
|
var dosingType = getDosingType();
|
|
return _.every(dosingType, function(element) {
|
|
return !element
|
|
})
|
|
}, this.isVariableDosingType = function() {
|
|
return self.isFrequencyType(Bahmni.Clinical.Constants.dosingTypes.variable)
|
|
}, this.isUniformDosingType = function() {
|
|
return self.isFrequencyType(Bahmni.Clinical.Constants.dosingTypes.uniform)
|
|
}, this.isFrequencyType = function(type) {
|
|
return self.frequencyType === type
|
|
}, this.setQuantityEnteredManually = function() {
|
|
self.quantityEnteredManually = !0
|
|
}, this.setQuantityUnitEnteredManually = function() {
|
|
self.quantityUnitEnteredManually = !0
|
|
}, this.calculateDurationInDays = function() {
|
|
var durationUnitFromConfig = _.find(durationUnits, function(unit) {
|
|
return unit.name === self.durationUnit
|
|
});
|
|
self.durationInDays = self.duration ? self.duration * (durationUnitFromConfig && durationUnitFromConfig.factor || 1) : Number.NaN
|
|
};
|
|
var quantityUnitsFrom = function(doseUnit) {
|
|
return doseUnit
|
|
},
|
|
modifyForReverseSyncIfRequired = function(drugOrder) {
|
|
drugOrder.reverseSynced && (drugOrder.uniformDosingType = {}, drugOrder.quantity = void 0, drugOrder.quantityUnit = void 0, drugOrder.doseUnits = void 0, drugOrder.changeDrug(drugOrder.drug))
|
|
};
|
|
this.calculateQuantityAndUnit = function() {
|
|
if (self.calculateDurationInDays(), self.variableDosingType.morningDose > 0 || self.variableDosingType.afternoonDose > 0 || self.variableDosingType.eveningDose > 0 ? self.frequencyType = "variable" : self.frequencyType = "uniform", !self.quantityEnteredManually && !self.quantityEnteredViaEdit) {
|
|
if (self.frequencyType === Bahmni.Clinical.Constants.dosingTypes.uniform) {
|
|
var mantissa = self.uniformDosingType.doseFraction ? self.uniformDosingType.doseFraction.value : 0,
|
|
dose = self.uniformDosingType.dose ? self.uniformDosingType.dose : 0;
|
|
self.quantity = (dose + mantissa) * (self.uniformDosingType.frequency ? getFrequencyPerDay() : 0) * self.durationInDays
|
|
} else if (self.frequencyType === Bahmni.Clinical.Constants.dosingTypes.variable) {
|
|
var dose = self.variableDosingType;
|
|
self.quantity = (dose.morningDose + dose.afternoonDose + dose.eveningDose) * self.durationInDays
|
|
}
|
|
self.quantity % 1 !== 0 && (self.quantity = self.quantity - self.quantity % 1 + 1)
|
|
}
|
|
self.quantityEnteredViaEdit && self.quantityUnit || self.quantityUnitEnteredManually ? self.quantityUnit = quantityUnitsFrom(self.quantityUnit) : self.quantityUnit = quantityUnitsFrom(self.doseUnits), self.quantityEnteredViaEdit = !1, self.quantityUnitEnteredViaEdit = !1
|
|
}, this.isStopped = function() {
|
|
return !!self.dateStopped
|
|
}, this.isScheduled = function() {
|
|
return !self.isDiscontinuedOrStopped() && self.scheduledDate && self.scheduledDate > today()
|
|
}, this.isActive = function() {
|
|
return !self.isDiscontinuedOrStopped() && (!self.effectiveStopDate || self.effectiveStopDate >= today())
|
|
}, this.discontinued = function() {
|
|
return self.action === Bahmni.Clinical.Constants.orderActions.discontinue
|
|
}, this.isDiscontinuedOrStopped = function() {
|
|
return (self.isStopped() || self.discontinued()) && void 0 === self.isMarkedForDiscontinue
|
|
};
|
|
var defaultQuantityUnit = function(drugOrder) {
|
|
drugOrder.quantityUnit || (drugOrder.quantityUnit = "Unit(s)")
|
|
};
|
|
this.getSpanDetails = function() {
|
|
var valueString = "- ";
|
|
return _.forEach(this.span, function(value, key) {
|
|
value && (valueString += value + " " + key + " + ")
|
|
}), valueString.substring(0, valueString.length - 3)
|
|
}, this.getDurationAndDurationUnits = function() {
|
|
return self.duration ? self.duration + " " + self.durationUnit : ""
|
|
}, this.refill = function(existingOrderStopDate) {
|
|
var newDrugOrder = new Bahmni.Clinical.DrugOrderViewModel(config, this);
|
|
newDrugOrder.previousOrderUuid = void 0, newDrugOrder.action = Bahmni.Clinical.Constants.orderActions["new"], newDrugOrder.uuid = void 0, newDrugOrder.dateActivated = void 0;
|
|
var oldEffectiveStopDate = existingOrderStopDate ? new Date(existingOrderStopDate) : new Date(self.effectiveStopDate);
|
|
return newDrugOrder.effectiveStartDate = oldEffectiveStopDate >= today() ? DateUtil.addSeconds(oldEffectiveStopDate, 1) : today(), newDrugOrder.calculateDurationInDays(), newDrugOrder.effectiveStopDate = DateUtil.addDays(DateUtil.parse(newDrugOrder.effectiveStartDate), newDrugOrder.durationInDays), modifyForReverseSyncIfRequired(newDrugOrder), defaultQuantityUnit(newDrugOrder), newDrugOrder.orderReasonText = null, newDrugOrder.orderReasonConcept = null, newDrugOrder.orderSetUuid = self.orderSetUuid, newDrugOrder.orderGroupUuid = void 0, newDrugOrder.isNewOrderSet = !1, newDrugOrder
|
|
}, this.revise = function() {
|
|
var newDrugOrder = new Bahmni.Clinical.DrugOrderViewModel(config, this);
|
|
return newDrugOrder.previousOrderUuid = self.uuid, self.calculateDurationInDays(), newDrugOrder.previousOrderDurationInDays = self.durationInDays, newDrugOrder.action = Bahmni.Clinical.Constants.orderActions.revise, newDrugOrder.uuid = void 0, newDrugOrder.dateActivated = void 0, newDrugOrder.drugNameDisplay = constructDrugNameDisplay(self.drug) || self.drugNonCoded || self.concept.name, newDrugOrder.quantityEnteredViaEdit = !0, newDrugOrder.isBeingEdited = !0, newDrugOrder.orderSetUuid = self.orderSetUuid, newDrugOrder.orderGroupUuid = self.orderGroupUuid, newDrugOrder.isNewOrderSet = !1, newDrugOrder.effectiveStartDate <= today() && (newDrugOrder.effectiveStartDate = today()), modifyForReverseSyncIfRequired(newDrugOrder), defaultQuantityUnit(newDrugOrder), newDrugOrder
|
|
}, this.cloneForEdit = function(index, config) {
|
|
var editableDrugOrder = new Bahmni.Clinical.DrugOrderViewModel(config, this);
|
|
return editableDrugOrder.currentIndex = index, editableDrugOrder.isBeingEdited = !0, editableDrugOrder.quantityEnteredViaEdit = !0, editableDrugOrder.orderSetUuid = self.orderSetUuid, editableDrugOrder.orderGroupUuid = self.orderGroupUuid, defaultQuantityUnit(editableDrugOrder), editableDrugOrder.frequencyType === Bahmni.Clinical.Constants.dosingTypes.variable && (editableDrugOrder.isUniformFrequency = !1), editableDrugOrder
|
|
}, this.isDoseMandatory = function() {
|
|
return inputOptionsConfig.routesToMakeDoseSectionNonMandatory = inputOptionsConfig.routesToMakeDoseSectionNonMandatory || [], !(inputOptionsConfig.routesToMakeDoseSectionNonMandatory.indexOf(this.route) !== -1 || _.isEmpty(self.uniformDosingType.doseUnits) && _.isEmpty(self.variableDosingType.doseUnits))
|
|
}, this.isMantissaRequired = function() {
|
|
return this.isDoseMandatory() && this.isUniformFrequency && !this.uniformDosingType.dose;
|
|
}, this.isUniformDoseUnitRequired = function() {
|
|
return this.uniformDosingType.dose || this.uniformDosingType.doseFraction || this.isUniformFrequency && this.isDoseMandatory()
|
|
}, this.isUniformDoseRequired = function() {
|
|
return this.isUniformFrequency && this.isDoseMandatory() && !this.uniformDosingType.doseFraction
|
|
}, this.isVariableDoseRequired = function() {
|
|
if (!this.isUniformFrequency) return !!this.isDoseMandatory() || (self.variableDosingType.morningDose || self.variableDosingType.afternoonDose || self.variableDosingType.eveningDose)
|
|
}, this.loadOrderAttributes = function(drugOrderResponse) {
|
|
if (config && config.orderAttributes) {
|
|
var findOrderAttribute = function(drugOrder, orderAttribute) {
|
|
return _.find(drugOrder.orderAttributes, function(drugOrderAttribute) {
|
|
return orderAttribute.name === drugOrderAttribute.name
|
|
})
|
|
};
|
|
config.orderAttributes.forEach(function(orderAttributeInConfig) {
|
|
var orderAttributeInDrugOrder = findOrderAttribute(drugOrderResponse, orderAttributeInConfig),
|
|
existingOrderAttribute = findOrderAttribute(self, orderAttributeInConfig),
|
|
orderAttribute = existingOrderAttribute || {};
|
|
orderAttribute.name = orderAttributeInConfig.name, orderAttribute.shortName = orderAttributeInConfig.shortName, orderAttribute.conceptUuid = orderAttributeInConfig.uuid, orderAttribute.value = orderAttributeInDrugOrder && "true" === orderAttributeInDrugOrder.value, orderAttribute.obsUuid = orderAttributeInDrugOrder ? orderAttributeInDrugOrder.obsUuid : void 0, orderAttribute.encounterUuid = orderAttributeInDrugOrder ? orderAttributeInDrugOrder.encounterUuid : void 0, existingOrderAttribute || self.orderAttributes.push(orderAttribute)
|
|
})
|
|
}
|
|
}, this.getOrderAttributesAsObs = function() {
|
|
if (self.orderAttributes) {
|
|
var orderAttributesWithValues = self.orderAttributes.filter(function(orderAttribute) {
|
|
return orderAttribute.value || orderAttribute.obsUuid
|
|
});
|
|
return orderAttributesWithValues.map(function(orderAttribute) {
|
|
return {
|
|
uuid: orderAttribute.obsUuid,
|
|
value: !!orderAttribute.value,
|
|
orderUuid: self.uuid,
|
|
concept: {
|
|
uuid: orderAttribute.conceptUuid
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}, this.loadOrderAttributes({});
|
|
var calculateUniformDose = function() {
|
|
var mantissa = self.uniformDosingType.doseFraction ? self.uniformDosingType.doseFraction.value : 0,
|
|
dose = self.uniformDosingType.dose ? self.uniformDosingType.dose : 0;
|
|
return self.uniformDosingType.doseFraction = void 0, dose || mantissa ? dose + mantissa : null
|
|
};
|
|
this.setUniformDoseFraction = function() {
|
|
"uniform" === self.frequencyType && (self.uniformDosingType.dose = calculateUniformDose())
|
|
}, this.getDoseAndUnits = function() {
|
|
var variableDosingType = self.variableDosingType,
|
|
variableDosingString = addDelimiter(morphToMixedFraction(variableDosingType.morningDose || 0) + "-" + morphToMixedFraction(variableDosingType.afternoonDose || 0) + "-" + morphToMixedFraction(variableDosingType.eveningDose || 0), " ");
|
|
if (self.frequencyType === Bahmni.Clinical.Constants.dosingTypes.uniform) {
|
|
var value = morphToMixedFraction(calculateUniformDose());
|
|
return value ? value + " " + blankIfFalsy(self.doseUnits) : ""
|
|
}
|
|
return (variableDosingString + blankIfFalsy(self.doseUnits)).trim()
|
|
}, this.getFrequency = function() {
|
|
return self.frequencyType === Bahmni.Clinical.Constants.dosingTypes.uniform ? blankIfFalsy(self.uniformDosingType.frequency) : ""
|
|
}, this.calculateEffectiveStopDate = function() {
|
|
this.durationInDays && (this.effectiveStopDate = DateUtil.addDays(DateUtil.parse(this.effectiveStartDate), this.durationInDays))
|
|
}
|
|
}, Bahmni.Clinical.DrugOrderViewModel.createFromContract = function(drugOrderResponse, config) {
|
|
var DateUtil = Bahmni.Common.Util.DateUtil;
|
|
drugOrderResponse.dosingInstructions = drugOrderResponse.dosingInstructions || {};
|
|
var administrationInstructions = JSON.parse(drugOrderResponse.dosingInstructions.administrationInstructions || "{}"),
|
|
viewModel = new Bahmni.Clinical.DrugOrderViewModel(config);
|
|
return viewModel.asNeeded = !!drugOrderResponse.dosingInstructions.asNeeded && drugOrderResponse.dosingInstructions.asNeeded, viewModel.route = drugOrderResponse.dosingInstructions.route, drugOrderResponse.effectiveStartDate && (viewModel.effectiveStartDate = DateUtil.parse(drugOrderResponse.effectiveStartDate)), viewModel.effectiveStopDate = drugOrderResponse.effectiveStopDate, viewModel.durationUnit = drugOrderResponse.durationUnits, viewModel.scheduledDate = drugOrderResponse.effectiveStartDate, viewModel.duration = drugOrderResponse.duration, drugOrderResponse.dosingInstructions.frequency || drugOrderResponse.dosingInstructions.dose ? (viewModel.frequencyType = Bahmni.Clinical.Constants.dosingTypes.uniform, viewModel.uniformDosingType = {
|
|
dose: drugOrderResponse.dosingInstructions.dose,
|
|
doseUnits: drugOrderResponse.dosingInstructions.doseUnits,
|
|
frequency: drugOrderResponse.dosingInstructions.frequency
|
|
}) : administrationInstructions.morningDose || administrationInstructions.afternoonDose || administrationInstructions.eveningDose ? (viewModel.frequencyType = Bahmni.Clinical.Constants.dosingTypes.variable, viewModel.variableDosingType = {
|
|
morningDose: administrationInstructions.morningDose,
|
|
afternoonDose: administrationInstructions.afternoonDose,
|
|
eveningDose: administrationInstructions.eveningDose,
|
|
doseUnits: drugOrderResponse.dosingInstructions.doseUnits
|
|
}) : (viewModel.frequencyType = Bahmni.Clinical.Constants.dosingTypes.uniform, viewModel.reverseSynced = !0, viewModel.uniformDosingType = {
|
|
dose: parseFloat(administrationInstructions.dose),
|
|
doseUnits: administrationInstructions.doseUnits
|
|
}), viewModel.instructions = administrationInstructions.instructions, viewModel.additionalInstructions = administrationInstructions.additionalInstructions, viewModel.quantity = drugOrderResponse.dosingInstructions.quantity, viewModel.quantityUnit = drugOrderResponse.dosingInstructions.quantityUnits, viewModel.drug = drugOrderResponse.drug, viewModel.provider = drugOrderResponse.provider, viewModel.creatorName = drugOrderResponse.creatorName, viewModel.action = drugOrderResponse.action, viewModel.concept = drugOrderResponse.concept, viewModel.dateStopped = drugOrderResponse.dateStopped, viewModel.uuid = drugOrderResponse.uuid, viewModel.previousOrderUuid = drugOrderResponse.previousOrderUuid, viewModel.dateActivated = drugOrderResponse.dateActivated, viewModel.encounterUuid = drugOrderResponse.encounterUuid, drugOrderResponse.orderReasonConcept && (viewModel.orderReasonConcept = drugOrderResponse.orderReasonConcept), viewModel.orderReasonText = drugOrderResponse.orderReasonText, viewModel.orderNumber = drugOrderResponse.orderNumber && parseInt(drugOrderResponse.orderNumber.replace("ORD-", "")), viewModel.drugNonCoded = drugOrderResponse.drugNonCoded, viewModel.isNonCodedDrug = !!drugOrderResponse.drugNonCoded, viewModel.drugNameDisplay = viewModel.drugNonCoded || constructDrugNameDisplay(viewModel.drug) || _.get(viewModel, "concept.name"), config ? viewModel.loadOrderAttributes(drugOrderResponse) : viewModel.orderAttributes = drugOrderResponse.orderAttributes, viewModel.visit = drugOrderResponse.visit, viewModel.voided = drugOrderResponse.voided, viewModel.dosage = viewModel.getDoseAndUnits(), viewModel.isDrugRetired = drugOrderResponse.retired, drugOrderResponse.orderGroup && (viewModel.orderGroupUuid = drugOrderResponse.orderGroup.uuid, viewModel.orderSetUuid = drugOrderResponse.orderGroup.orderSet.uuid, viewModel.sortWeight = drugOrderResponse.sortWeight), viewModel
|
|
},
|
|
function() {
|
|
var DateUtil = Bahmni.Common.Util.DateUtil,
|
|
Drug = function(name, orders) {
|
|
this.name = name, this.orders = orders || []
|
|
};
|
|
Bahmni.Clinical.DrugSchedule = function(fromDate, toDate, drugOrders) {
|
|
this.fromDate = fromDate, this.toDate = toDate, this.drugOrders = drugOrders, this.days = this.getDays(), this.drugs = this.getDrugs()
|
|
}, Bahmni.Clinical.DrugSchedule.prototype = {
|
|
getDays: function() {
|
|
return DateUtil.createDays(this.fromDate, this.toDate)
|
|
},
|
|
getDrugs: function() {
|
|
var drugOrders = this.drugOrders.map(Bahmni.Clinical.DrugOrder.create),
|
|
allOrderedDrugs = [];
|
|
return _.each(drugOrders, function(order) {
|
|
var drugAlreadyOrdered = _.find(allOrderedDrugs, order.drugNonCoded ? {
|
|
name: order.drugNonCoded
|
|
} : {
|
|
name: order.drug && order.drug.name || order.concept.name
|
|
});
|
|
drugAlreadyOrdered || (drugAlreadyOrdered = new Drug(order.drugNonCoded ? order.drugNonCoded : order.drug && order.drug.name || order.concept.name), allOrderedDrugs.push(drugAlreadyOrdered)), drugAlreadyOrdered.orders.push(order)
|
|
}), allOrderedDrugs
|
|
},
|
|
hasDrugOrders: function() {
|
|
return this.drugOrders.length > 0
|
|
}
|
|
}, Bahmni.Clinical.DrugSchedule.create = function(fromDate, toDate, drugOrders) {
|
|
var drugOrdersDuringIpd = drugOrders.filter(function(drugOrder) {
|
|
var orderStartDate = DateUtil.parse(drugOrder.effectiveStartDate),
|
|
orderStopDate = DateUtil.parse(drugOrder.effectiveStopDate);
|
|
return orderStartDate < toDate && orderStopDate >= fromDate
|
|
});
|
|
return new this(fromDate, toDate, drugOrdersDuringIpd)
|
|
}, Drug.prototype = {
|
|
isActiveOnDate: function(date) {
|
|
return this.orders.some(function(order) {
|
|
return order.isActiveOnDate(date)
|
|
})
|
|
},
|
|
getStatusOnDate: function(date) {
|
|
var activeDrugOrders = _.filter(this.orders, function(order) {
|
|
return order.isActiveOnDate(date)
|
|
});
|
|
return 0 === activeDrugOrders.length ? "inactive" : _.every(activeDrugOrders, function(order) {
|
|
return "stopped" === order.getStatusOnDate(date)
|
|
}) ? "stopped" : "active"
|
|
},
|
|
isActive: function() {
|
|
return this.orders.some(function(order) {
|
|
return order.isActive()
|
|
})
|
|
}
|
|
}, Bahmni.Clinical.DrugSchedule.Drug = Drug
|
|
}(), Bahmni.Clinical.Order = function() {
|
|
var Order = function(data) {
|
|
angular.extend(this, data), this.dateCreated = data.dateCreated
|
|
},
|
|
getName = function(test) {
|
|
var name = _.find(test.names, {
|
|
conceptNameType: "SHORT"
|
|
}) || _.find(test.names, {
|
|
conceptNameType: "FULLY_SPECIFIED"
|
|
});
|
|
return name ? name.name : void 0
|
|
};
|
|
return Order.create = function(test) {
|
|
var order = new Order({
|
|
uuid: void 0,
|
|
concept: {
|
|
uuid: test.uuid,
|
|
displayName: getName(test)
|
|
}
|
|
});
|
|
return order
|
|
}, Order.revise = function(order) {
|
|
var revisedOrder = new Order({
|
|
concept: order.concept,
|
|
action: Bahmni.Clinical.Constants.orderActions.revise,
|
|
previousOrderUuid: order.uuid,
|
|
isDiscontinued: !1,
|
|
commentToFulfiller: order.commentToFulfiller,
|
|
urgency: order.urgency
|
|
});
|
|
return revisedOrder
|
|
}, Order.discontinue = function(order) {
|
|
var discontinuedOrder = new Order({
|
|
concept: order.concept,
|
|
action: Bahmni.Clinical.Constants.orderActions.discontinue,
|
|
previousOrderUuid: order.uuid,
|
|
commentToFulfiller: order.commentToFulfiller,
|
|
urgency: order.urgency
|
|
});
|
|
return discontinuedOrder
|
|
}, Order
|
|
}(), Bahmni.Clinical.TabConfig = function(tabs) {
|
|
var self = this;
|
|
this.tabs = _.filter(tabs, function(tab) {
|
|
return angular.isObject(tab)
|
|
}), this.identifierKey = null;
|
|
var initDisplayByDefaultTabs = function() {
|
|
self.visibleTabs = _.filter(self.tabs, function(tab) {
|
|
return tab.displayByDefault
|
|
})
|
|
},
|
|
init = function() {
|
|
initDisplayByDefaultTabs(), self.currentTab = self.getFirstTab(), self.currentTab && self.currentTab.translationKey && (self.identifierKey = "translationKey")
|
|
},
|
|
isTabClosed = function(tab) {
|
|
return !_.find(self.visibleTabs, function(visibleTab) {
|
|
return visibleTab[self.identifierKey] === tab[self.identifierKey]
|
|
})
|
|
};
|
|
this.getTab = function(id) {
|
|
return _.find(self.tabs, function(tab) {
|
|
return tab[self.identifierKey] === id
|
|
})
|
|
}, this.getFirstTab = function() {
|
|
return self.visibleTabs[0]
|
|
}, this.switchTab = function(tab) {
|
|
this.currentTab = tab, isTabClosed(tab) && this.visibleTabs.push(tab)
|
|
}, this.showTabs = function() {
|
|
return this.tabs.length > 1
|
|
}, this.closeTab = function(tab) {
|
|
tab.displayByDefault || (_.remove(self.visibleTabs, function(visibleTab) {
|
|
return tab[self.identifierKey] === visibleTab[self.identifierKey]
|
|
}), this.switchTab(this.getFirstTab()))
|
|
}, this.getUnOpenedTabs = function() {
|
|
return _.difference(this.tabs, this.visibleTabs)
|
|
}, this.isCurrentTab = function(tab) {
|
|
return this.currentTab && this.currentTab[self.identifierKey] === tab[self.identifierKey]
|
|
}, this.showPrint = function() {
|
|
return !_.isEmpty(this.currentTab.printing)
|
|
}, this.getPrintConfigForCurrentTab = function() {
|
|
return this.currentTab.printing
|
|
}, init()
|
|
}, Bahmni.Clinical.VisitTabConfig = function(tabs) {
|
|
var tabConfig = new Bahmni.Clinical.TabConfig(tabs);
|
|
tabConfig.identifierKey || (tabConfig.identifierKey = "title"), angular.extend(this, tabConfig), this.setVisitUuidsAndPatientUuidToTheSections = function(visitUuids, patientUuid) {
|
|
_.each(this.tabs, function(tab) {
|
|
_.each(tab.sections, function(section) {
|
|
section.config.visitUuids = visitUuids, section.config.patientUuid = patientUuid
|
|
})
|
|
})
|
|
}
|
|
}, Bahmni.Clinical.VisitDrugOrder = function() {
|
|
var VisitDrugOrder = function(orders, ipdOrders, orderGroup) {
|
|
this.orders = orders, this.ipdDrugSchedule = ipdOrders, this.orderGroup = orderGroup
|
|
};
|
|
return VisitDrugOrder.prototype = {
|
|
hasIPDDrugSchedule: function() {
|
|
return this.ipdDrugSchedule && this.ipdDrugSchedule.hasDrugOrders()
|
|
},
|
|
getDrugOrderGroups: function() {
|
|
return this.orderGroup
|
|
},
|
|
getIPDDrugs: function() {
|
|
return this.ipdDrugSchedule.drugs
|
|
}
|
|
}, VisitDrugOrder.create = function(encounterTransactions, admissionDate, dischargeDate) {
|
|
var nameToSort = function(drugOrder) {
|
|
return drugOrder.drugNonCoded ? drugOrder.drugNonCoded : drugOrder.drug.name
|
|
},
|
|
drugOrders = new Bahmni.Clinical.OrdersMapper(nameToSort).map(encounterTransactions, "drugOrders"),
|
|
prescribedDrugOrders = _.map(drugOrders, Bahmni.Clinical.DrugOrderViewModel.createFromContract);
|
|
return this.createFromDrugOrders(prescribedDrugOrders, admissionDate, dischargeDate)
|
|
}, VisitDrugOrder.createFromDrugOrders = function(drugOrders, admissionDate, dischargeDate) {
|
|
drugOrders = _.filter(drugOrders, function(drugOrder) {
|
|
return !drugOrder.voided && drugOrder.action !== Bahmni.Clinical.Constants.orderActions.discontinue
|
|
}), drugOrders = _.filter(drugOrders, function(drugOrder) {
|
|
return !_.some(drugOrders, function(otherDrugOrder) {
|
|
return otherDrugOrder.action === Bahmni.Clinical.Constants.orderActions.revise && otherDrugOrder.encounterUuid === drugOrder.encounterUuid && otherDrugOrder.previousOrderUuid === drugOrder.uuid
|
|
})
|
|
});
|
|
var ipdOrders = null;
|
|
admissionDate && (ipdOrders = Bahmni.Clinical.DrugSchedule.create(admissionDate, dischargeDate, drugOrders));
|
|
var orderGroup = (new Bahmni.Clinical.OrdersMapper).group(drugOrders, "date");
|
|
return new this(drugOrders, ipdOrders, orderGroup)
|
|
}, VisitDrugOrder
|
|
}(), Bahmni.Clinical.ConceptWeightBasedSorter = function(allTestAndPanelsConcept) {
|
|
var sortedConcepts = allTestAndPanelsConcept ? allTestAndPanelsConcept.setMembers : [],
|
|
sortedNames = sortedConcepts.map(function(concept) {
|
|
return concept.name.name
|
|
});
|
|
this.sort = function(conceptHolders, nameToSort) {
|
|
return conceptHolders ? (conceptHolders.forEach(function(conceptHolder) {
|
|
var index = sortedNames.indexOf(nameToSort ? nameToSort(conceptHolder) : conceptHolder.concept.name);
|
|
conceptHolder.sortWeight = index === -1 ? 999 : index
|
|
}), _.sortBy(conceptHolders, "sortWeight")) : []
|
|
}, this.sortTestResults = function(labOrderResults) {
|
|
return labOrderResults ? (labOrderResults.forEach(function(labOrderResult) {
|
|
var index = sortedNames.indexOf(labOrderResult.orderName || labOrderResult.testName);
|
|
labOrderResult.sortWeight = index === -1 ? 999 : index, labOrderResult.isPanel && (labOrderResult.tests.forEach(function(test) {
|
|
var index = sortedNames.indexOf(test.testName);
|
|
test.sortWeight = index === -1 ? 999 : index
|
|
}), labOrderResult.tests = _.sortBy(labOrderResult.tests, "sortWeight"))
|
|
}), _.sortBy(labOrderResults, "sortWeight")) : []
|
|
}
|
|
}, Bahmni.Clinical.ObsGroupingHelper = function(conceptSetUiConfigService) {
|
|
var conceptSetUiConfigSvc = conceptSetUiConfigService;
|
|
this.groupObservations = function(observations) {
|
|
var groupedObservationsArray = [],
|
|
obsWithoutFieldPath = _.filter(observations, function(obs) {
|
|
return !obs.formFieldPath
|
|
}),
|
|
obsWithFieldPath = _.filter(observations, function(obs) {
|
|
return obs.formFieldPath
|
|
}),
|
|
groupedObsByFieldPath = _.groupBy(obsWithFieldPath, function(obs) {
|
|
return obs.formFieldPath.split(".")[0]
|
|
});
|
|
return obsWithoutFieldPath.forEach(function(observation) {
|
|
var temp = [observation],
|
|
conceptSetName = observation.concept.shortName || observation.concept.name,
|
|
observationsByGroup = groupObservations(conceptSetName, temp);
|
|
observationsByGroup.groupMembers.length && groupedObservationsArray.push(observationsByGroup)
|
|
}), _.each(groupedObsByFieldPath, function(observations, formName) {
|
|
var observationsByGroup = groupObservations(formName, observations);
|
|
observationsByGroup.groupMembers.length && groupedObservationsArray.push(observationsByGroup)
|
|
}), groupedObservationsArray
|
|
};
|
|
var groupObservations = function(conceptSetName, obs) {
|
|
var observationsByGroup = {
|
|
conceptSetName: conceptSetName,
|
|
groupMembers: (new Bahmni.ConceptSet.ObservationMapper).getObservationsForView(obs, conceptSetUiConfigSvc.getConfig())
|
|
};
|
|
return observationsByGroup
|
|
}
|
|
}, Bahmni.Clinical.AccessionNotesMapper = function(encounterConfig) {
|
|
var isValidationEncounter = function(encounterTransaction) {
|
|
return encounterTransaction.encounterTypeUuid === encounterConfig.getValidationEncounterTypeUuid()
|
|
},
|
|
addAccessionNote = function(accessions, accessionNote) {
|
|
var accession = _.find(accessions, {
|
|
accessionUuid: accessionNote.accessionUuid
|
|
});
|
|
accession && (accession.accessionNotes = accession.accessionNotes || [], accession.accessionNotes.push(accessionNote))
|
|
};
|
|
this.map = function(encounters, accessions) {
|
|
var validationEncounters = encounters.filter(isValidationEncounter),
|
|
accessionNotes = _(validationEncounters).map("accessionNotes").flatten().value();
|
|
return accessionNotes.forEach(function(accessionNote) {
|
|
addAccessionNote(accessions, accessionNote)
|
|
}), accessions.forEach(function() {
|
|
accessions.accessionNotes = _.sortBy(accessions.accessionNotes, "dateTime").reverse()
|
|
}), accessions
|
|
}
|
|
}, Bahmni.Clinical.EncounterTransactionToObsMapper = function() {
|
|
this.map = function(encounterTransactions, invalidEncounterTypes, conceptSetUIConfig) {
|
|
var allObs, validObservation = function(observation) {
|
|
return !observation.voided && (!isObservationAgroup(observation) || isObservationAgroup(observation) && observation.groupMembers.some(validObservation))
|
|
},
|
|
setProvider = function(provider) {
|
|
var setProviderToObservation = function(observation) {
|
|
observation.provider = provider, angular.forEach(observation.groupMembers, setProviderToObservation)
|
|
};
|
|
return setProviderToObservation
|
|
},
|
|
setProviderToObservations = function(observations, provider) {
|
|
var setProviderFunction = setProvider(provider);
|
|
angular.forEach(observations, function(observation) {
|
|
setProviderFunction(observation)
|
|
})
|
|
},
|
|
createMultiSelectObs = function(obsList) {
|
|
conceptSetUIConfig && (obsList.forEach(function(obs) {
|
|
createMultiSelectObs(obs.groupMembers)
|
|
}), new Bahmni.ConceptSet.MultiSelectObservations(conceptSetUIConfig).map(obsList))
|
|
},
|
|
flatten = function(transactions, item) {
|
|
return transactions.reduce(function(result, transaction) {
|
|
return setProviderToObservations(transaction[item], transaction.providers[0]), createMultiSelectObs(transaction.observations), result.concat(transaction[item])
|
|
}, [])
|
|
},
|
|
isObservationAgroup = function(observation) {
|
|
return observation.groupMembers && observation.groupMembers.length > 0
|
|
},
|
|
removeInvalidGroupMembers = function(observation) {
|
|
angular.forEach(observation.groupMembers, removeInvalidGroupMembers), observation.groupMembers && (observation.groupMembers = observation.groupMembers.filter(validObservation))
|
|
},
|
|
removeInvalidEncounterTypes = function(encounterTransaction) {
|
|
return invalidEncounterTypes.indexOf(encounterTransaction.encounterTypeUuid) === -1
|
|
};
|
|
return encounterTransactions = encounterTransactions.filter(removeInvalidEncounterTypes), allObs = flatten(encounterTransactions, "observations").filter(validObservation), allObs.forEach(removeInvalidGroupMembers), allObs
|
|
}
|
|
}, Bahmni.Clinical.PatientFileObservationsMapper = function() {
|
|
var DateUtil = Bahmni.Common.Util.DateUtil;
|
|
this.map = function(encounters) {
|
|
var conceptMapper = new Bahmni.Common.Domain.ConceptMapper,
|
|
observationMapper = new Bahmni.Common.Domain.ObservationMapper,
|
|
providerMapper = new Bahmni.Common.Domain.ProviderMapper,
|
|
patientFileRecords = [];
|
|
return encounters.forEach(function(encounter) {
|
|
var visitUuid = encounter.visit && encounter.visit.uuid;
|
|
encounter.obs.forEach(function(parentObservation) {
|
|
parentObservation.groupMembers.forEach(function(member) {
|
|
patientFileRecords.push({
|
|
id: member.id,
|
|
concept: conceptMapper.map(parentObservation.concept),
|
|
imageObservation: observationMapper.map(member),
|
|
visitUuid: visitUuid,
|
|
provider: providerMapper.map(encounter.provider),
|
|
visitStartDate: encounter.visit.startDatetime,
|
|
visitStopDate: encounter.visit.stopDatetime,
|
|
comment: member.comment
|
|
})
|
|
})
|
|
})
|
|
}), patientFileRecords.sort(function(record1, record2) {
|
|
return record1.imageObservation.observationDateTime !== record2.imageObservation.observationDateTime ? DateUtil.parse(record1.imageObservation.observationDateTime) - DateUtil.parse(record2.imageObservation.observationDateTime) : record1.id - record2.id
|
|
}), patientFileRecords
|
|
}
|
|
}, Bahmni.Clinical.OrdersMapper = function(nameToSort) {
|
|
this.nameToSort = nameToSort
|
|
}, Bahmni.Clinical.OrdersMapper.prototype.group = function(orders, groupingParameter) {
|
|
var getGroupingFunction = function(groupingParameter) {
|
|
return "date" === groupingParameter ? function(order) {
|
|
return order.startDate ? Bahmni.Common.Util.DateUtil.getDate(order.startDate) : Bahmni.Common.Util.DateUtil.getDate(order.effectiveStartDate)
|
|
} : function(order) {
|
|
return order[groupingParameter]
|
|
}
|
|
};
|
|
groupingParameter = groupingParameter || "date";
|
|
var groupingFunction = getGroupingFunction(groupingParameter),
|
|
groupedOrders = (new Bahmni.Clinical.ResultGrouper).group(orders, groupingFunction, "orders", groupingParameter);
|
|
return "date" === groupingParameter ? groupedOrders.map(function(order) {
|
|
return {
|
|
date: Bahmni.Common.Util.DateUtil.parse(order.date),
|
|
orders: _.sortBy(order.orders, "orderNumber")
|
|
}
|
|
}).sort(function(first, second) {
|
|
return first.date < second.date ? 1 : -1
|
|
}) : groupedOrders.map(function(order) {
|
|
var returnObj = {};
|
|
return returnObj[groupingParameter] = order[groupingParameter], returnObj.orders = order.orders, returnObj
|
|
})
|
|
}, Bahmni.Clinical.OrdersMapper.prototype.create = function(encounterTransactions, ordersName, filterFunction, groupingParameter, allTestAndPanels) {
|
|
filterFunction = filterFunction || function() {
|
|
return !0
|
|
};
|
|
var filteredOrders = this.map(encounterTransactions, ordersName, allTestAndPanels).filter(filterFunction);
|
|
return this.group(filteredOrders, groupingParameter)
|
|
}, Bahmni.Clinical.OrdersMapper.prototype.map = function(encounterTransactions, ordersName, allTestAndPanels) {
|
|
var allTestsPanelsConcept = new Bahmni.Clinical.ConceptWeightBasedSorter(allTestAndPanels),
|
|
orderObservationsMapper = new Bahmni.Clinical.OrderObservationsMapper,
|
|
setOrderProvider = function(encounter) {
|
|
encounter[ordersName].forEach(function(order) {
|
|
order.provider = encounter.providers[0], order.accessionUuid = encounter.encounterUuid, order.encounterUuid = encounter.encounterUuid, order.visitUuid = encounter.visitUuid
|
|
})
|
|
};
|
|
encounterTransactions.forEach(setOrderProvider);
|
|
var flattenedOrders = _(encounterTransactions).map(ordersName).flatten().value(),
|
|
ordersWithoutVoidedOrders = flattenedOrders.filter(function(order) {
|
|
return !order.voided
|
|
}),
|
|
allObservations = _(encounterTransactions).map("observations").flatten().value();
|
|
orderObservationsMapper.map(allObservations, ordersWithoutVoidedOrders);
|
|
var sortedOrders = allTestsPanelsConcept.sort(ordersWithoutVoidedOrders, this.nameToSort);
|
|
return sortedOrders.forEach(function(order) {
|
|
order.observations.forEach(function(obs) {
|
|
obs.groupMembers = allTestsPanelsConcept.sort(obs.groupMembers)
|
|
})
|
|
}), sortedOrders
|
|
}, Bahmni.Clinical.OrderObservationsMapper = function() {}, Bahmni.Clinical.OrderObservationsMapper.prototype.map = function(observations, orders) {
|
|
var makeCommentsAsAdditionalObs = function(observation) {
|
|
if (angular.forEach(observation.groupMembers, makeCommentsAsAdditionalObs), observation.groupMembers) {
|
|
var additionalObs = [],
|
|
testObservation = [];
|
|
angular.forEach(observation.groupMembers, function(obs) {
|
|
obs.concept.name === Bahmni.Clinical.Constants.commentConceptName ? additionalObs.push(obs) : testObservation.push(obs)
|
|
}), observation.groupMembers = testObservation, observation.groupMembers[0] && additionalObs.length > 0 && (observation.groupMembers[0].additionalObs = additionalObs)
|
|
}
|
|
},
|
|
getObservationForOrderIfExist = function(observations, order, obs) {
|
|
angular.forEach(observations, function(observation) {
|
|
order.uuid === observation.orderUuid ? (makeCommentsAsAdditionalObs(observation), obs.push(observation)) : null === observation.orderUuid && observation.groupMembers.length > 0 && getObservationForOrderIfExist(observation.groupMembers, order, obs)
|
|
})
|
|
},
|
|
mapOrderWithObs = function(observations, order) {
|
|
var orderObservations = [];
|
|
getObservationForOrderIfExist(observations, order, orderObservations), order.observations = orderObservations
|
|
};
|
|
orders.forEach(function(order) {
|
|
mapOrderWithObs(observations, order)
|
|
})
|
|
}, angular.module("bahmni.clinical").service("visitTabConfig", ["$q", "appService", function($q, appService) {
|
|
var mandatoryConfigPromise = function() {
|
|
return appService.loadMandatoryConfig(Bahmni.Clinical.Constants.mandatoryVisitConfigUrl)
|
|
},
|
|
configPromise = function() {
|
|
return appService.loadConfig("visit.json")
|
|
};
|
|
this.load = function() {
|
|
return $q.all([mandatoryConfigPromise(), configPromise()]).then(function(results) {
|
|
results[0].data.sections = _.sortBy(results[0].data.sections, function(section) {
|
|
return section.displayOrder
|
|
});
|
|
for (var tab in results[1]) {
|
|
var sortedSections = _.sortBy(results[1][tab].sections, function(section) {
|
|
return section.displayOrder
|
|
});
|
|
sortedSections.length > 0 && (results[1][tab].sections = sortedSections)
|
|
}
|
|
var mandatoryConfig = results[0].data,
|
|
tabs = _.values(results[1]),
|
|
firstTabWithDefaultSection = _.find(tabs, function(tab) {
|
|
return tab.defaultSections
|
|
});
|
|
_.find(mandatoryConfig.sections, {
|
|
title: "Treatments"
|
|
}) && _.find(firstTabWithDefaultSection.sections, {
|
|
title: "Treatments"
|
|
}) && (mandatoryConfig.sections = _.filter(mandatoryConfig.sections, function(section) {
|
|
return "Treatments" !== section.title
|
|
}));
|
|
var mandatorySections = _.map(_.values(mandatoryConfig.sections), function(item) {
|
|
return _.assign(item, _.find(_.values(firstTabWithDefaultSection.sections), ["type", item.type]))
|
|
});
|
|
return firstTabWithDefaultSection.sections = _.unionWith(_.values(mandatorySections), _.values(firstTabWithDefaultSection.sections), _.isEqual), firstTabWithDefaultSection.sections = _.sortBy(firstTabWithDefaultSection.sections, function(section) {
|
|
return section.displayOrder
|
|
}), new Bahmni.Clinical.VisitTabConfig(tabs)
|
|
})
|
|
}
|
|
}]), angular.module("bahmni.clinical").factory("visitActionsService", ["printer", function(printer) {
|
|
return {
|
|
printPrescription: function(patient, visitDate, visitUuid) {
|
|
printer.print("common/views/prescriptionPrint.html", {
|
|
patient: patient,
|
|
visitDate: visitDate,
|
|
visitUuid: visitUuid
|
|
})
|
|
}
|
|
}
|
|
}]), angular.module("bahmni.clinical").service("clinicalAppConfigService", ["appService", "urlHelper", "$stateParams", function(appService, urlHelper, $stateParams) {
|
|
this.getTreatmentActionLink = function() {
|
|
return appService.getAppDescriptor().getExtensions("org.bahmni.clinical.treatment.links", "link") || []
|
|
}, this.getAllConceptsConfig = function() {
|
|
return appService.getAppDescriptor().getConfigValue("conceptSetUI") || {}
|
|
}, this.getConceptConfig = function(name) {
|
|
var config = appService.getAppDescriptor().getConfigValue("conceptSetUI") || {};
|
|
return config[name]
|
|
}, this.getObsIgnoreList = function() {
|
|
var baseObsIgnoreList = [Bahmni.Common.Constants.impressionConcept],
|
|
configuredObsIgnoreList = appService.getAppDescriptor().getConfigValue("obsIgnoreList") || [];
|
|
return baseObsIgnoreList.concat(configuredObsIgnoreList)
|
|
}, this.getAllConsultationBoards = function() {
|
|
return appService.getAppDescriptor().getExtensions("org.bahmni.clinical.consultation.board", "link")
|
|
}, this.getAllConceptSetExtensions = function(conceptSetGroupName) {
|
|
return appService.getAppDescriptor().getExtensions("org.bahmni.clinical.conceptSetGroup." + conceptSetGroupName, "config")
|
|
}, this.getOtherInvestigationsMap = function() {
|
|
return appService.getAppDescriptor().getConfig("otherInvestigationsMap")
|
|
}, this.getVisitPageConfig = function(configSection) {
|
|
var visitSection = appService.getAppDescriptor().getConfigValue("visitPage") || {};
|
|
return configSection ? visitSection[configSection] : visitSection
|
|
}, this.getVisitConfig = function() {
|
|
return appService.getAppDescriptor().getConfigForPage("visit")
|
|
}, this.getMedicationConfig = function() {
|
|
return appService.getAppDescriptor().getConfigForPage("medication") || {}
|
|
}, this.getPrintConfig = function() {
|
|
return appService.getAppDescriptor().getConfigValue("printConfig") || {}
|
|
}, this.getConsultationBoardLink = function() {
|
|
var allBoards = this.getAllConsultationBoards(),
|
|
defaultBoard = _.find(allBoards, "default");
|
|
if ($stateParams.programUuid) {
|
|
var programParams = "?programUuid=" + $stateParams.programUuid + "&enrollment=" + $stateParams.enrollment + "&dateEnrolled=" + $stateParams.dateEnrolled + "&dateCompleted=" + $stateParams.dateCompleted;
|
|
return "/" + $stateParams.configName + urlHelper.getPatientUrl() + "/" + defaultBoard.url + programParams
|
|
}
|
|
return defaultBoard ? "/" + $stateParams.configName + urlHelper.getPatientUrl() + "/" + defaultBoard.url + "?encounterUuid=active" : urlHelper.getConsultationUrl()
|
|
}, this.getDefaultVisitType = function() {
|
|
return appService.getAppDescriptor().getConfigValue("defaultVisitType")
|
|
}, this.getVisitTypeForRetrospectiveEntries = function() {
|
|
return appService.getAppDescriptor().getConfigValue("visitTypeForRetrospectiveEntries")
|
|
}
|
|
}]), angular.module("bahmni.clinical").directive("visitPaginator", ["$state", function($state) {
|
|
var link = function($scope) {
|
|
var visits = _.clone($scope.visits).reverse(),
|
|
visitIndex = _.findIndex(visits, function(visitHistoryEntry) {
|
|
return null !== $scope.currentVisitUuid && visitHistoryEntry.uuid === $scope.currentVisitUuid
|
|
});
|
|
$scope.visitHistoryEntry = visits[visitIndex], $scope.shouldBeShown = function() {
|
|
return $state.is("patient.dashboard.visit")
|
|
}, $scope.hasNext = function() {
|
|
return visitIndex !== -1 && visitIndex < visits.length - 1
|
|
}, $scope.hasPrevious = function() {
|
|
return visitIndex > 0
|
|
}, $scope.next = function() {
|
|
$scope.hasNext() && $scope.nextFn && $scope.nextFn()(visits[visitIndex + 1].uuid)
|
|
}, $scope.previous = function() {
|
|
$scope.hasPrevious() && $scope.previousFn && $scope.previousFn()(visits[visitIndex - 1].uuid)
|
|
}
|
|
};
|
|
return {
|
|
restrict: "EA",
|
|
scope: {
|
|
currentVisitUuid: "=",
|
|
visits: "=",
|
|
nextFn: "&",
|
|
previousFn: "&",
|
|
visitSummary: "="
|
|
},
|
|
link: link,
|
|
templateUrl: "common/views/visitPagination.html"
|
|
}
|
|
}]), angular.module("bahmni.common.services", []), angular.module("bahmni.common.services").factory("drugService", ["$http", function($http) {
|
|
var v = "custom:(uuid,strength,name,dosageForm,concept:(uuid,name,names:(name)))",
|
|
search = function(drugName, conceptUuid) {
|
|
var params = {
|
|
v: v,
|
|
q: drugName,
|
|
conceptUuid: conceptUuid,
|
|
s: "ordered"
|
|
};
|
|
return $http.get(Bahmni.Common.Constants.drugUrl, {
|
|
method: "GET",
|
|
params: params,
|
|
withCredentials: !0
|
|
}).then(function(response) {
|
|
return response.data.results
|
|
})
|
|
},
|
|
getSetMembersOfConcept = function(conceptSetFullySpecifiedName, searchTerm) {
|
|
return $http.get(Bahmni.Common.Constants.drugUrl, {
|
|
method: "GET",
|
|
params: {
|
|
v: v,
|
|
q: conceptSetFullySpecifiedName,
|
|
s: "byConceptSet",
|
|
searchTerm: searchTerm
|
|
},
|
|
withCredentials: !0
|
|
}).then(function(response) {
|
|
return response.data.results
|
|
})
|
|
},
|
|
getRegimen = function(patientUuid, patientProgramUuid, drugs) {
|
|
var params = {
|
|
patientUuid: patientUuid,
|
|
patientProgramUuid: patientProgramUuid,
|
|
drugs: drugs
|
|
};
|
|
return $http.get(Bahmni.Common.Constants.bahmniRESTBaseURL + "/drugOGram/regimen", {
|
|
params: params,
|
|
withCredentials: !0
|
|
})
|
|
};
|
|
return {
|
|
search: search,
|
|
getRegimen: getRegimen,
|
|
getSetMembersOfConcept: getSetMembersOfConcept
|
|
}
|
|
}]), angular.module("bahmni.clinical").controller("VisitHeaderController", ["$rootScope", "$scope", "$state", "clinicalAppConfigService", "patientContext", "visitHistory", "visitConfig", "contextChangeHandler", "$location", "$stateParams", "urlHelper", function($rootScope, $scope, $state, clinicalAppConfigService, patientContext, visitHistory, visitConfig, contextChangeHandler, $location, $stateParams, urlHelper) {
|
|
$scope.patient = patientContext.patient, $scope.visitHistory = visitHistory, $scope.consultationBoardLink = clinicalAppConfigService.getConsultationBoardLink(), $scope.showControlPanel = !1, $scope.visitTabConfig = visitConfig, $scope.switchTab = function(tab) {
|
|
$scope.visitTabConfig.switchTab(tab), $rootScope.$broadcast("event:clearVisitBoard", tab)
|
|
}, $scope.gotoPatientDashboard = function() {
|
|
contextChangeHandler.execute().allow && $location.path($stateParams.configName + "/patient/" + patientContext.patient.uuid + "/dashboard")
|
|
}, $scope.openConsultation = function() {
|
|
var board = clinicalAppConfigService.getAllConsultationBoards()[0],
|
|
urlPrefix = urlHelper.getPatientUrl();
|
|
$scope.collapseControlPanel(), $rootScope.hasVisitedConsultation = !0;
|
|
var url = "/" + $stateParams.configName + (board.url ? urlPrefix + "/" + board.url : urlPrefix),
|
|
extensionParams = board.extensionParams,
|
|
queryParams = [];
|
|
if ($stateParams.programUuid) {
|
|
var programParams = {
|
|
programUuid: $stateParams.programUuid,
|
|
enrollment: $stateParams.enrollment
|
|
};
|
|
extensionParams = _.merge(programParams, extensionParams)
|
|
}
|
|
angular.forEach(extensionParams, function(extensionParamValue, extensionParamKey) {
|
|
queryParams.push(extensionParamKey + "=" + extensionParamValue)
|
|
}), _.isEmpty(queryParams) || (url = url + "?" + queryParams.join("&")), $location.url(url)
|
|
}, $scope.closeTab = function(tab) {
|
|
$scope.visitTabConfig.closeTab(tab), $rootScope.$broadcast("event:clearVisitBoard", tab)
|
|
}, $scope.print = function() {
|
|
$rootScope.$broadcast("event:printVisitTab", $scope.visitTabConfig.currentTab)
|
|
}, $scope.showPrint = function() {
|
|
return $scope.visitTabConfig.showPrint()
|
|
}
|
|
}]), angular.module("bahmni.clinical").controller("VisitController", ["$scope", "$state", "encounterService", "clinicalAppConfigService", "configurations", "visitSummary", "$timeout", "printer", "visitConfig", "visitHistory", "$stateParams", function($scope, $state, encounterService, clinicalAppConfigService, configurations, visitSummary, $timeout, printer, visitConfig, visitHistory, $stateParams) {
|
|
var encounterTypeUuid = configurations.encounterConfig().getPatientDocumentEncounterTypeUuid();
|
|
$scope.documentsPromise = encounterService.getEncountersForEncounterType($scope.patient.uuid, encounterTypeUuid).then(function(response) {
|
|
return (new Bahmni.Clinical.PatientFileObservationsMapper).map(response.data.results)
|
|
}), $scope.currentVisitUrl = $state.current.views["dashboard-content"].templateUrl || $state.current.views["print-content"].templateUrl, $scope.visitHistory = visitHistory, $scope.visitSummary = visitSummary, $scope.visitTabConfig = visitConfig, $scope.showTrends = !0, $scope.patientUuid = $stateParams.patientUuid, $scope.visitUuid = $stateParams.visitUuid;
|
|
var tab = $stateParams.tab;
|
|
$scope.isNumeric = function(value) {
|
|
return $.isNumeric(value)
|
|
}, $scope.toggle = function(item) {
|
|
item.show = !item.show
|
|
}, $scope.isEmpty = function(notes) {
|
|
return !notes || notes.trim().length < 2
|
|
}, $scope.testResultClass = function(line) {
|
|
var style = {};
|
|
return $scope.pendingResults(line) && (style["pending-result"] = !0), line.isSummary && (style.header = !0), style
|
|
}, $scope.pendingResults = function(line) {
|
|
return line.isSummary && !line.hasResults && "" !== line.name
|
|
}, $scope.displayDate = function(date) {
|
|
return moment(date).format("DD-MMM-YY")
|
|
}, $scope.$on("event:printVisitTab", function() {
|
|
printer.printFromScope("common/views/visitTabPrint.html", $scope)
|
|
}), $scope.$on("event:clearVisitBoard", function() {
|
|
$scope.clearBoard = !0, $timeout(function() {
|
|
$scope.clearBoard = !1
|
|
})
|
|
}), $scope.loadVisit = function(visitUuid) {
|
|
$state.go("patient.dashboard.visit", {
|
|
visitUuid: visitUuid
|
|
})
|
|
};
|
|
var printOnPrint = function() {
|
|
$stateParams.print && printer.printFromScope("common/views/visitTabPrint.html", $scope, function() {
|
|
window.close()
|
|
})
|
|
},
|
|
getTab = function() {
|
|
if (tab)
|
|
for (var tabIndex in $scope.visitTabConfig.tabs)
|
|
if ($scope.visitTabConfig.tabs[tabIndex].title === tab) return $scope.visitTabConfig.tabs[tabIndex];
|
|
return $scope.visitTabConfig.getFirstTab()
|
|
},
|
|
init = function() {
|
|
$scope.visitTabConfig.setVisitUuidsAndPatientUuidToTheSections([$scope.visitUuid], $scope.patientUuid);
|
|
var tabToOpen = getTab();
|
|
$scope.visitTabConfig.switchTab(tabToOpen), printOnPrint()
|
|
};
|
|
init()
|
|
}]), angular.module("bahmni.clinical").controller("PatientListHeaderController", ["$scope", "$rootScope", "$bahmniCookieStore", "providerService", "spinner", "locationService", "$window", "ngDialog", "retrospectiveEntryService", "$translate", function($scope, $rootScope, $bahmniCookieStore, providerService, spinner, locationService, $window, ngDialog, retrospectiveEntryService, $translate) {
|
|
var DateUtil = Bahmni.Common.Util.DateUtil;
|
|
$scope.maxStartDate = DateUtil.getDateWithoutTime(DateUtil.today());
|
|
var selectedProvider = {};
|
|
$scope.retrospectivePrivilege = Bahmni.Common.Constants.retrospectivePrivilege, $scope.locationPickerPrivilege = Bahmni.Common.Constants.locationPickerPrivilege, $scope.onBehalfOfPrivilege = Bahmni.Common.Constants.onBehalfOfPrivilege, $scope.selectedLocationUuid = {}, $scope.getProviderList = function() {
|
|
return function(searchAttrs) {
|
|
return providerService.search(searchAttrs.term)
|
|
}
|
|
}, $scope.getProviderDataResults = function(data) {
|
|
return data.data.results.map(function(providerDetails) {
|
|
return {
|
|
value: providerDetails.person ? providerDetails.person.display : providerDetails.display,
|
|
uuid: providerDetails.uuid
|
|
}
|
|
})
|
|
}, $scope.providerSelected = function() {
|
|
return function(providerData) {
|
|
selectedProvider = providerData
|
|
}
|
|
}, $scope.clearProvider = function(data) {
|
|
_.isEmpty(selectedProvider) || data === selectedProvider.value || ($scope.encounterProvider = "", selectedProvider = {})
|
|
}, $scope.windowReload = function() {
|
|
changeCookieData(), $window.location.reload(!1)
|
|
}, $scope.isCurrentLocation = function(location) {
|
|
return getCurrentCookieLocation().uuid === location.uuid
|
|
}, $scope.popUpHandler = function() {
|
|
$scope.dialog = ngDialog.open({
|
|
template: "consultation/views/defaultDataPopUp.html",
|
|
className: "test ngdialog-theme-default",
|
|
controller: "PatientListHeaderController"
|
|
}), $("body").addClass("show-controller-back")
|
|
}, $scope.$on("ngDialog.closed", function() {
|
|
$("body").removeClass("show-controller-back")
|
|
}), $scope.closePopUp = function() {
|
|
ngDialog.close()
|
|
}, $scope.getTitle = function() {
|
|
var title = [];
|
|
return getCurrentCookieLocation() && title.push($translate.instant(getCurrentCookieLocation().name)), getCurrentProvider() && getCurrentProvider().value && title.push(getCurrentProvider().value), retrospectiveEntryService.getRetrospectiveDate() && title.push(DateUtil.formatDateWithoutTime(retrospectiveEntryService.getRetrospectiveDate())), title.join(",")
|
|
}, $scope.sync = function() {};
|
|
var getCurrentCookieLocation = function() {
|
|
return $bahmniCookieStore.get(Bahmni.Common.Constants.locationCookieName) ? $bahmniCookieStore.get(Bahmni.Common.Constants.locationCookieName) : null
|
|
},
|
|
getCurrentProvider = function() {
|
|
return $bahmniCookieStore.get(Bahmni.Common.Constants.grantProviderAccessDataCookieName)
|
|
},
|
|
getLocationFor = function(uuid) {
|
|
return _.find($scope.locations, function(location) {
|
|
return location.uuid === uuid
|
|
})
|
|
},
|
|
changeCookieData = function() {
|
|
retrospectiveEntryService.resetRetrospectiveEntry($scope.date), $bahmniCookieStore.remove(Bahmni.Common.Constants.grantProviderAccessDataCookieName), $bahmniCookieStore.put(Bahmni.Common.Constants.grantProviderAccessDataCookieName, selectedProvider, {
|
|
path: "/",
|
|
expires: 1
|
|
});
|
|
var selectedLocation = getLocationFor($scope.selectedLocationUuid);
|
|
$bahmniCookieStore.remove(Bahmni.Common.Constants.locationCookieName), $bahmniCookieStore.put(Bahmni.Common.Constants.locationCookieName, {
|
|
name: selectedLocation.display,
|
|
uuid: selectedLocation.uuid
|
|
}, {
|
|
path: "/",
|
|
expires: 7
|
|
})
|
|
},
|
|
init = function() {
|
|
var retrospectiveDate = retrospectiveEntryService.getRetrospectiveDate();
|
|
return $scope.date = retrospectiveDate ? new Date(retrospectiveDate) : new Date($scope.maxStartDate), $scope.encounterProvider = getCurrentProvider(), selectedProvider = getCurrentProvider(), locationService.getAllByTag("Login Location").then(function(response) {
|
|
$scope.locations = response.data.results, $scope.selectedLocationUuid = getCurrentCookieLocation().uuid
|
|
})
|
|
};
|
|
return init()
|
|
}]), angular.module("bahmni.clinical").controller("consultationContextController", ["$scope", "appService", "$stateParams", "visitHistory", function($scope, appService, $stateParams, visitHistory) {
|
|
var init = function() {
|
|
$scope.configName = $stateParams.configName;
|
|
var programConfig = appService.getAppDescriptor().getConfigValue("program");
|
|
$scope.visitUuid = _.get(visitHistory, "activeVisit.uuid"), $scope.patientInfoSection = {
|
|
patientInformation: {
|
|
title: "Patient Information",
|
|
name: "patientInformation",
|
|
patientAttributes: [],
|
|
ageLimit: programConfig && programConfig.patientInformation ? programConfig.patientInformation.ageLimit : void 0,
|
|
addressFields: ["address1", "address2", "cityVillage", "countyDistrict"]
|
|
}
|
|
}
|
|
};
|
|
init()
|
|
}]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Graph = Bahmni.Graph || {}, Bahmni.Graph.c3Chart = function() {
|
|
var dateUtil = Bahmni.Common.Util.DateUtil,
|
|
createReferenceClasses = function(data) {
|
|
var classes = {};
|
|
return _.each(data, function(datum) {
|
|
datum.reference && (classes[datum.name] = "reference-line")
|
|
}), classes
|
|
},
|
|
formatValueForDisplay = function(value, config) {
|
|
return config.displayForAge() ? Bahmni.Common.Util.AgeUtil.monthsToAgeString(value) : config.displayForObservationDateTime() ? dateUtil.formatDateWithoutTime(value) : d3.round(value, 2)
|
|
},
|
|
createXAxisConfig = function(config) {
|
|
return {
|
|
label: {
|
|
text: config.xAxisConcept + (config.unit || ""),
|
|
position: "outer-right"
|
|
},
|
|
type: config.type,
|
|
tick: {
|
|
culling: {
|
|
max: 3
|
|
},
|
|
count: 10,
|
|
format: function(xAxisValue) {
|
|
return formatValueForDisplay(xAxisValue, config)
|
|
}
|
|
}
|
|
}
|
|
},
|
|
createYAxisConfig = function(unit) {
|
|
return {
|
|
label: {
|
|
text: unit,
|
|
position: "outer-top"
|
|
},
|
|
tick: {
|
|
culling: {
|
|
max: 3
|
|
},
|
|
format: function(y) {
|
|
return d3.round(y, 2)
|
|
}
|
|
},
|
|
show: !0
|
|
}
|
|
},
|
|
createAxisConfig = function(config, units) {
|
|
var axis = {
|
|
x: createXAxisConfig(config),
|
|
y: createYAxisConfig(units[0])
|
|
};
|
|
return void 0 !== units[1] && (axis.y2 = createYAxisConfig(units[1])), axis
|
|
},
|
|
createGridConfig = function(config) {
|
|
var grid = {
|
|
y: {
|
|
lines: []
|
|
}
|
|
};
|
|
return 1 === config.yAxisConcepts.length && (void 0 !== config.lowNormal && grid.y.lines.push({
|
|
value: config.lowNormal,
|
|
text: "low",
|
|
"class": "lowNormal"
|
|
}), void 0 !== config.hiNormal && grid.y.lines.push({
|
|
value: config.hiNormal,
|
|
text: "high",
|
|
"class": "hiNormal"
|
|
})), grid
|
|
},
|
|
createConfigForToolTipGroupingFix = function(config) {
|
|
var xs = {};
|
|
return config.yAxisConcepts.forEach(function(yAxisConcept) {
|
|
xs[yAxisConcept] = config.xAxisConcept
|
|
}), xs
|
|
},
|
|
createAxisAndPopulateAxes = function(axes, data, axisY, unit) {
|
|
unit && _.each(data, function(item) {
|
|
item.units === unit && (axes[item.name] = axisY)
|
|
})
|
|
},
|
|
createConfigForAxes = function(data, units) {
|
|
var axes = {};
|
|
return createAxisAndPopulateAxes(axes, data, "y", units[0]), createAxisAndPopulateAxes(axes, data, "y2", units[1]), axes
|
|
};
|
|
this.render = function(bindTo, graphWidth, config, data) {
|
|
var distinctUnits = _.uniq(_.map(data, "units"));
|
|
if (distinctUnits.length > 2) throw new Error("Cannot display line graphs with concepts that have more than 2 units");
|
|
var c3Chart, allPoints = _(data).reduce(function(accumulator, item) {
|
|
return accumulator.concat(item.values)
|
|
}, []),
|
|
c3Config = {
|
|
bindto: bindTo,
|
|
size: {
|
|
width: graphWidth
|
|
},
|
|
padding: {
|
|
top: 20,
|
|
right: 50
|
|
},
|
|
data: {
|
|
json: allPoints,
|
|
keys: {
|
|
x: config.xAxisConcept,
|
|
value: config.yAxisConcepts
|
|
},
|
|
axes: createConfigForAxes(data, distinctUnits),
|
|
xs: createConfigForToolTipGroupingFix(config),
|
|
onclick: function(d) {
|
|
c3Chart.tooltip.show({
|
|
data: d
|
|
})
|
|
},
|
|
classes: createReferenceClasses(data)
|
|
},
|
|
point: {
|
|
show: !0,
|
|
r: 5,
|
|
sensitivity: 20
|
|
},
|
|
line: {
|
|
connectNull: !0
|
|
},
|
|
axis: createAxisConfig(config, distinctUnits),
|
|
tooltip: {
|
|
grouped: !0,
|
|
format: {
|
|
title: function(xAxisValue) {
|
|
return formatValueForDisplay(xAxisValue, config)
|
|
}
|
|
}
|
|
},
|
|
zoom: {
|
|
enabled: !0
|
|
},
|
|
transition_duration: 0,
|
|
grid: createGridConfig(config)
|
|
};
|
|
return c3Chart = c3.generate(c3Config)
|
|
}
|
|
}, Bahmni.Graph.c3Chart.create = function() {
|
|
return new Bahmni.Graph.c3Chart
|
|
}, Bahmni.Clinical.ObservationTemplate = function(concept, visitStartDate, observations) {
|
|
var obsTemplate = {
|
|
name: concept.name,
|
|
conceptClass: concept.conceptClass,
|
|
label: concept.shortName || concept.name,
|
|
visitStartDate: visitStartDate,
|
|
encounters: []
|
|
},
|
|
groupedObservations = _.groupBy(observations, function(observation) {
|
|
return observation.encounterDateTime
|
|
}),
|
|
encounterDates = _.sortBy(Object.keys(groupedObservations), function(a) {
|
|
return -a
|
|
});
|
|
return angular.forEach(encounterDates, function(encounterDate) {
|
|
var newEncounter = {
|
|
encounterDateTime: encounterDate,
|
|
observations: groupedObservations[encounterDate]
|
|
};
|
|
obsTemplate.encounters.push(newEncounter)
|
|
}), obsTemplate
|
|
}, Bahmni.Clinical.DiseaseTemplate = function(concept, obsTemplates) {
|
|
var diseaseTemplate = {
|
|
name: concept.name,
|
|
label: concept.shortName || concept.name,
|
|
obsTemplates: obsTemplates || []
|
|
};
|
|
return diseaseTemplate.notEmpty = function() {
|
|
return diseaseTemplate.obsTemplates && diseaseTemplate.obsTemplates.length > 0
|
|
}, diseaseTemplate
|
|
}, Bahmni.Clinical.ClinicalDashboardConfig = function(config) {
|
|
var self = this,
|
|
tabConfig = new Bahmni.Clinical.TabConfig(config);
|
|
tabConfig.identifierKey || (tabConfig.identifierKey = "dashboardName"), angular.extend(self, tabConfig), this.getDiseaseTemplateSections = function(tab) {
|
|
return tab = tab || this.currentTab, _.filter(_.values(tab.sections), function(section) {
|
|
return "diseaseTemplate" === section.type
|
|
})
|
|
}, this.getMaxRecentlyViewedPatients = function() {
|
|
return self.currentTab.maxRecentlyViewedPatients || 10
|
|
}
|
|
}, Bahmni.Clinical.RecordsMapper = function() {
|
|
var DateUtil = Bahmni.Common.Util.DateUtil,
|
|
sortByDateTimeOrId = function(record1, record2) {
|
|
return record2.imageObservation.observationDateTime !== record1.imageObservation.observationDateTime ? DateUtil.parse(record2.imageObservation.observationDateTime) - DateUtil.parse(record1.imageObservation.observationDateTime) : record2.id - record1.id
|
|
};
|
|
this.map = function(records) {
|
|
return records = records.sort(sortByDateTimeOrId), Bahmni.Common.Util.ArrayUtil.groupByPreservingOrder(records, function(record) {
|
|
return record.concept.name
|
|
}, "conceptName", "records")
|
|
}
|
|
}, Bahmni.Clinical.DiseaseTemplateMapper = function(diseaseTemplateResponse, allConceptsConfig) {
|
|
var allObsTemplates = [],
|
|
isGrid = function(obsTemplate) {
|
|
return allConceptsConfig[obsTemplate.concept.name] && allConceptsConfig[obsTemplate.concept.name].grid
|
|
};
|
|
return diseaseTemplateResponse.observationTemplates && diseaseTemplateResponse.observationTemplates.length > 0 && diseaseTemplateResponse.observationTemplates.forEach(function(obsTemplate) {
|
|
var observationTemplate, observations = [];
|
|
isGrid(obsTemplate) ? (obsTemplate.value = (new Bahmni.Common.Obs.ObservationMapper).getGridObservationDisplayValue(obsTemplate), observationTemplate = new Bahmni.Clinical.ObservationTemplate(obsTemplate.concept, obsTemplate.visitStartDate, observations), observationTemplate.value = obsTemplate.value) : (obsTemplate.bahmniObservations.length > 0 && (observations = (new Bahmni.Common.Obs.ObservationMapper).map(obsTemplate.bahmniObservations, allConceptsConfig)), observationTemplate = new Bahmni.Clinical.ObservationTemplate(obsTemplate.concept, obsTemplate.visitStartDate, observations)), allObsTemplates.push(observationTemplate)
|
|
}), Bahmni.Clinical.DiseaseTemplate(diseaseTemplateResponse.concept, allObsTemplates)
|
|
}, angular.module("bahmni.clinical").service("clinicalDashboardConfig", ["appService", function(appService) {
|
|
var self = this;
|
|
this.load = function() {
|
|
return appService.loadConfig("dashboard.json").then(function(response) {
|
|
angular.extend(self, new Bahmni.Clinical.ClinicalDashboardConfig(_.values(response)))
|
|
})
|
|
}
|
|
}]), angular.module("bahmni.clinical").directive("diseaseTemplate", function() {
|
|
var controller = function($scope) {
|
|
$scope.dateTimeDisplayConfig = function(obsTemplate) {
|
|
var showDate = !1,
|
|
showTime = !1;
|
|
return obsTemplate.conceptClass === Bahmni.Clinical.Constants.caseIntakeConceptClass ? $scope.showDateTimeForIntake && (showDate = !0, showTime = !0) : $scope.showTimeForProgress && (showTime = !0), {
|
|
showDate: showDate,
|
|
showTime: showTime
|
|
}
|
|
}, $scope.isIntakeTemplate = function(obsTemplate) {
|
|
return obsTemplate.conceptClass === Bahmni.Clinical.Constants.caseIntakeConceptClass
|
|
}, $scope.showGroupDateTime = $scope.config.showGroupDateTime !== !1
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
controller: controller,
|
|
scope: {
|
|
diseaseTemplate: "=template",
|
|
config: "=",
|
|
patient: "=",
|
|
showDateTimeForIntake: "=",
|
|
showTimeForProgress: "=",
|
|
sectionId: "="
|
|
},
|
|
templateUrl: "dashboard/views/diseaseTemplate.html"
|
|
}
|
|
}), angular.module("bahmni.clinical").directive("recentPatients", function() {
|
|
var controller = function($rootScope, $scope, $state, clinicalDashboardConfig, $stateParams, patientService, sessionService) {
|
|
var initialize = function() {
|
|
$scope.search = new Bahmni.Common.PatientSearch.Search((void 0)), $scope.showPatientsList = !1
|
|
};
|
|
$scope.recentlyViewedPatients = _.take($rootScope.currentUser.recentlyViewedPatients, clinicalDashboardConfig.getMaxRecentlyViewedPatients()), $scope.configName = $stateParams.configName;
|
|
var patientIndex = _.findIndex($scope.recentlyViewedPatients, function(patientHistoryEntry) {
|
|
return patientHistoryEntry.uuid === $scope.patient.uuid
|
|
});
|
|
$scope.hasNext = function() {
|
|
return 0 !== patientIndex
|
|
}, $scope.togglePatientsList = function() {
|
|
$scope.showPatientsList = !$scope.showPatientsList
|
|
}, $scope.hasPrevious = function() {
|
|
return patientIndex >= 0 && $scope.recentlyViewedPatients.length - 1 !== patientIndex
|
|
}, $scope.next = function() {
|
|
$scope.hasNext() && $scope.goToDashboard($scope.recentlyViewedPatients[patientIndex - 1].uuid)
|
|
}, $scope.previous = function() {
|
|
$scope.hasPrevious() && $scope.goToDashboard($scope.recentlyViewedPatients[patientIndex + 1].uuid)
|
|
}, $scope.goToDashboard = function(patientUuid) {
|
|
$state.go("patient.dashboard", {
|
|
configName: $scope.configName,
|
|
patientUuid: patientUuid
|
|
})
|
|
}, $scope.getActivePatients = function() {
|
|
if (!($scope.search.patientsCount() > 0)) {
|
|
var params = {
|
|
q: Bahmni.Clinical.Constants.globalPropertyToFetchActivePatients,
|
|
location_uuid: sessionService.getLoginLocationUuid()
|
|
};
|
|
patientService.findPatients(params).then(function(response) {
|
|
$scope.search.updatePatientList(response.data)
|
|
})
|
|
}
|
|
}, initialize()
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
controller: controller,
|
|
templateUrl: "dashboard/views/recentPatients.html"
|
|
}
|
|
}), angular.module("bahmni.clinical").controller("DiseaseTemplateController", ["$scope", function($scope) {
|
|
var patient = $scope.patient;
|
|
$scope.showDateTimeForIntake = !1, $scope.showTimeForProgress = !0, $scope.dialogData = {
|
|
diseaseTemplateName: $scope.section.templateName,
|
|
patient: patient,
|
|
section: $scope.section
|
|
}, $scope.getDiseaseTemplateSection = function(diseaseName) {
|
|
return _.find($scope.diseaseTemplates, function(diseaseTemplate) {
|
|
return diseaseTemplate.name === diseaseName
|
|
})
|
|
}
|
|
}]), angular.module("bahmni.clinical").controller("EditObservationFormController", ["$scope", "appService", "$window", "$rootScope", "$translate", function($scope, appService, $window, $rootScope, $translate) {
|
|
var configForPrompting = appService.getAppDescriptor().getConfigValue("showSaveConfirmDialog");
|
|
$scope.directivePreCloseCallback = function() {
|
|
if ($scope.resetContextChangeHandler(), configForPrompting && $scope.shouldPromptBeforeClose) return !!$window.confirm($translate.instant("POP_UP_CLOSE_DIALOG_MESSAGE_KEY")) && ($rootScope.hasVisitedConsultation || ($scope.shouldPromptBrowserReload = !1), !0)
|
|
}, window.onbeforeunload = function() {
|
|
if (configForPrompting && $scope.shouldPromptBrowserReload) return $translate.instant("BROWSER_CLOSE_DIALOG_MESSAGE_KEY")
|
|
}
|
|
}]), angular.module("bahmni.clinical").controller("PatientDashboardTreatmentController", ["$scope", "ngDialog", function($scope, ngDialog) {
|
|
var treatmentConfigParams = $scope.dashboard.getSectionByType("treatment") || {},
|
|
patientUuidparams = {
|
|
patientUuid: $scope.patient.uuid
|
|
};
|
|
$scope.dashboardConfig = {}, $scope.expandedViewConfig = {}, _.extend($scope.dashboardConfig, treatmentConfigParams.dashboardConfig || {}, patientUuidparams), _.extend($scope.expandedViewConfig, treatmentConfigParams.expandedViewConfig || {}, patientUuidparams), $scope.openSummaryDialog = function() {
|
|
ngDialog.open({
|
|
template: "dashboard/views/dashboardSections/treatmentSummary.html",
|
|
params: $scope.expandedViewConfig,
|
|
className: "ngdialog-theme-default ng-dialog-all-details-page",
|
|
scope: $scope
|
|
})
|
|
};
|
|
var cleanUpListener = $scope.$on("ngDialog.closing", function() {
|
|
$("body").removeClass("ngdialog-open")
|
|
});
|
|
$scope.$on("$destroy", cleanUpListener)
|
|
}]), angular.module("bahmni.clinical").controller("PatientDashboardLabOrdersController", ["$scope", "$stateParams", function($scope, $stateParams) {
|
|
$scope.dashboardConfig = $scope.dashboard.getSectionByType("labOrders").dashboardConfig || {}, $scope.dashboardConfig.patientUuid = $stateParams.patientUuid, $scope.dialogData = {
|
|
patient: $scope.patient,
|
|
expandedViewConfig: $scope.dashboard.getSectionByType("labOrders").expandedViewConfig || {}
|
|
}
|
|
}]), angular.module("bahmni.clinical").controller("PatientDashboardLabSummaryController", ["$scope", "$stateParams", function($scope, $stateParams) {
|
|
$scope.expandedViewConfig = $scope.ngDialogData.expandedViewConfig, $scope.expandedViewConfig.patientUuid = $stateParams.patientUuid, $scope.patient = $scope.ngDialogData.patient
|
|
}]), angular.module("bahmni.clinical").controller("PatientDashboardRadiologyController", ["$scope", function($scope) {
|
|
$scope.config = $scope.dashboard.getSectionByType("radiology") || {}
|
|
}]), angular.module("bahmni.clinical").controller("PatientDashboardAllDiseaseTemplateController", ["$scope", "diseaseTemplateService", "spinner", "appService", "$stateParams", function($scope, diseaseTemplateService, spinner, appService, $stateParams) {
|
|
var init = function() {
|
|
$scope.diseaseName = $scope.ngDialogData.diseaseTemplateName, $scope.patient = $scope.ngDialogData.patient, $scope.section = $scope.ngDialogData.section, $scope.showDateTimeForIntake = !0, $scope.showTimeForProgress = !0;
|
|
var programConfig = appService.getAppDescriptor().getConfigValue("program"),
|
|
startDate = null,
|
|
endDate = null;
|
|
return programConfig && programConfig.showDetailsWithinDateRange && (startDate = $stateParams.dateEnrolled, endDate = $stateParams.dateCompleted), diseaseTemplateService.getAllDiseaseTemplateObs($scope.patient.uuid, $scope.diseaseName, startDate, endDate).then(function(diseaseTemplate) {
|
|
$scope.diseaseTemplate = diseaseTemplate
|
|
})
|
|
};
|
|
spinner.forPromise(init())
|
|
}]), angular.module("bahmni.clinical").controller("PatientDashboardController", ["$scope", "clinicalAppConfigService", "clinicalDashboardConfig", "printer", "$state", "spinner", "visitSummary", "appService", "$stateParams", "diseaseTemplateService", "patientContext", "$location", "$filter", function($scope, clinicalAppConfigService, clinicalDashboardConfig, printer, $state, spinner, visitSummary, appService, $stateParams, diseaseTemplateService, patientContext, $location, $filter) {
|
|
$scope.patient = patientContext.patient, $scope.activeVisit = $scope.visitHistory.activeVisit, $scope.activeVisitData = {}, $scope.obsIgnoreList = clinicalAppConfigService.getObsIgnoreList(), $scope.clinicalDashboardConfig = clinicalDashboardConfig, $scope.visitSummary = visitSummary, $scope.enrollment = $stateParams.enrollment, $scope.isDashboardPrinting = !1;
|
|
var programConfig = appService.getAppDescriptor().getConfigValue("program") || {};
|
|
$scope.stateChange = function() {
|
|
return "patient.dashboard.show" === $state.current.name
|
|
};
|
|
var cleanUpListenerSwitchDashboard = $scope.$on("event:switchDashboard", function(event, dashboard) {
|
|
$scope.init(dashboard)
|
|
}),
|
|
cleanUpListenerPrintDashboard = $scope.$on("event:printDashboard", function(event, tab) {
|
|
var printScope = $scope.$new();
|
|
printScope.isDashboardPrinting = !0, printScope.tabBeingPrinted = tab || clinicalDashboardConfig.currentTab;
|
|
var dashboardModel = Bahmni.Common.DisplayControl.Dashboard.create(printScope.tabBeingPrinted, $filter);
|
|
spinner.forPromise(diseaseTemplateService.getLatestDiseaseTemplates($stateParams.patientUuid, clinicalDashboardConfig.getDiseaseTemplateSections(printScope.tabBeingPrinted), null, null).then(function(diseaseTemplate) {
|
|
printScope.diseaseTemplates = diseaseTemplate, printScope.sectionGroups = dashboardModel.getSections(printScope.diseaseTemplates), printer.printFromScope("dashboard/views/dashboardPrint.html", printScope)
|
|
}))
|
|
});
|
|
$scope.$on("$destroy", function() {
|
|
cleanUpListenerSwitchDashboard(), cleanUpListenerPrintDashboard()
|
|
});
|
|
var addTabNameToParams = function(board) {
|
|
$location.search("currentTab", board.translationKey)
|
|
},
|
|
getCurrentTab = function() {
|
|
var currentTabKey = $location.search().currentTab,
|
|
currentTab = $state.current.dashboard;
|
|
return currentTabKey && (currentTab = _.find(clinicalDashboardConfig.visibleTabs, function(tab) {
|
|
return tab.translationKey === currentTabKey
|
|
})), void 0 != currentTab ? currentTab : clinicalDashboardConfig.currentTab
|
|
};
|
|
$scope.init = function(dashboard) {
|
|
dashboard.startDate = null, dashboard.endDate = null, programConfig.showDetailsWithinDateRange && (dashboard.startDate = $stateParams.dateEnrolled, dashboard.endDate = $stateParams.dateCompleted), $state.current.dashboard = dashboard, clinicalDashboardConfig.switchTab(dashboard), addTabNameToParams(dashboard);
|
|
var dashboardModel = Bahmni.Common.DisplayControl.Dashboard.create(dashboard, $filter);
|
|
diseaseTemplateService.getLatestDiseaseTemplates($stateParams.patientUuid, clinicalDashboardConfig.getDiseaseTemplateSections(), dashboard.startDate, dashboard.endDate).then(function(diseaseTemplate) {
|
|
$scope.diseaseTemplates = diseaseTemplate, $scope.sectionGroups = dashboardModel.getSections($scope.diseaseTemplates)
|
|
}), $scope.currentDashboardTemplateUrl = $state.current.views["dashboard-content"] ? $state.current.views["dashboard-content"].templateUrl : $state.current.views["dashboard-content"]
|
|
}, $scope.init(getCurrentTab())
|
|
}]), angular.module("bahmni.clinical").controller("PatientDashboardVisitsController", ["$scope", "$stateParams", function($scope, $stateParams) {
|
|
$scope.noOfVisits = $scope.visitHistory.visits.length, $scope.dialogData = {
|
|
noOfVisits: $scope.noOfVisits,
|
|
patient: $scope.patient,
|
|
sectionConfig: $scope.dashboard.getSectionByType("visits")
|
|
}, $scope.dashboardConfig = $scope.dashboard.getSectionByType("visits").dashboardConfig || {}, $scope.patientUuid = $stateParams.patientUuid
|
|
}]), angular.module("bahmni.clinical").controller("PatientDashboardAllVisitsController", ["$scope", "$state", "$stateParams", function($scope, $state, $stateParams) {
|
|
$scope.patient = $scope.ngDialogData.patient, $scope.noOfVisits = $scope.ngDialogData.noOfVisits;
|
|
var sectionConfig = $scope.ngDialogData.sectionConfig,
|
|
defaultParams = {
|
|
maximumNoOfVisits: $scope.noOfVisits ? $scope.noOfVisits : 0
|
|
};
|
|
$scope.params = angular.extend(defaultParams, $scope.params), $scope.params = angular.extend(sectionConfig, $scope.params), $scope.patientUuid = $stateParams.patientUuid, $scope.showAllObservationsData = !0
|
|
}]), angular.module("bahmni.clinical").controller("PatientDashboardProgramsController", ["$scope", "$state", function($scope, $state) {
|
|
$scope.gotoDetailsPage = function() {
|
|
$state.go("patient.patientProgram.show")
|
|
}
|
|
}]), Bahmni.Clinical.Error = function() {
|
|
var messages = Bahmni.Common.Constants.serverErrorMessages,
|
|
findClientMessage = function(message) {
|
|
var result = _.find(messages, function(listItem) {
|
|
return listItem.serverMessage === message
|
|
});
|
|
return result && result.clientMessage || message
|
|
},
|
|
translate = function(error) {
|
|
return error && error.data && error.data.error && error.data.error.message ? findClientMessage(error.data.error.message) : null
|
|
};
|
|
return {
|
|
translate: translate
|
|
}
|
|
}(), Bahmni.Clinical.LabResult = function(name, value, alert, lowNormal, highNormal, unit, notes, members) {
|
|
this.name = name, this.value = value, this.alert = alert, this.unit = unit, this.highNormal = highNormal, this.lowNormal = lowNormal, this.notes = notes || [], this.members = members
|
|
}, Bahmni.Clinical.LabResult.prototype = {
|
|
isPanel: function() {
|
|
return this.members.length > 0
|
|
},
|
|
hasNotes: function() {
|
|
return this.notes.length > 0
|
|
},
|
|
isAbnormal: function() {
|
|
return "A" === this.alert || "B" === this.alert
|
|
},
|
|
range: function() {
|
|
return this.lowNormal && this.highNormal ? "" + this.lowNormal + " - " + this.highNormal : null
|
|
}
|
|
}, Bahmni.Clinical.DrugSearchResult = function() {
|
|
var createSynonym = function(drug, synonymName) {
|
|
var value = drug.dosageForm ? drug.name + " (" + drug.dosageForm.display + ")" : drug.name,
|
|
label = synonymName ? synonymName + " => " + value : value;
|
|
return {
|
|
label: label,
|
|
value: value,
|
|
drug: drug
|
|
}
|
|
},
|
|
create = function(drug) {
|
|
return createSynonym(drug)
|
|
},
|
|
getMatcher = function(searchString) {
|
|
return function(value) {
|
|
return _.includes(value.toLowerCase(), searchString.toLowerCase())
|
|
}
|
|
},
|
|
getSynonymCreator = function(drug) {
|
|
return function(name) {
|
|
return createSynonym(drug, name)
|
|
}
|
|
},
|
|
getAllMatchingSynonyms = function(drug, searchString) {
|
|
var doesMatchSearchString = getMatcher(searchString),
|
|
createSynonym = getSynonymCreator(drug);
|
|
if (doesMatchSearchString(drug.name)) return [createSynonym()];
|
|
var conceptNames = drug && drug.concept && drug.concept.names,
|
|
uniqConceptNames = _.uniq(_.map(conceptNames, "name")),
|
|
namesThatMatches = _.filter(uniqConceptNames, doesMatchSearchString);
|
|
return namesThatMatches = _.sortBy(namesThatMatches), _.map(namesThatMatches, createSynonym)
|
|
};
|
|
return {
|
|
create: create,
|
|
createSynonym: createSynonym,
|
|
getAllMatchingSynonyms: getAllMatchingSynonyms
|
|
}
|
|
}(), Bahmni.Clinical.VisitHistoryEntry = function() {
|
|
var VisitHistoryEntry = function(visitData) {
|
|
angular.extend(this, visitData)
|
|
};
|
|
return VisitHistoryEntry.prototype = {
|
|
isActive: function() {
|
|
return null === this.stopDatetime
|
|
},
|
|
isFromCurrentLocation: function(currentVisitLocation) {
|
|
var visitLocation = _.get(this.location, "uuid");
|
|
return visitLocation === currentVisitLocation
|
|
},
|
|
isOneDayVisit: function() {
|
|
if (this.isActive()) return !0;
|
|
var startDateString = moment(this.startDatetime).format("YYYYMMDD"),
|
|
stopDateString = moment(this.stopDatetime).format("YYYYMMDD");
|
|
return startDateString === stopDateString
|
|
},
|
|
getVisitType: function() {
|
|
if (this.visitType) return this.visitType.name || this.visitType.display
|
|
}
|
|
}, VisitHistoryEntry
|
|
}(), Bahmni.Clinical.Category = function(name, tests) {
|
|
this.name = name, this.tests = tests, this.filteredTests = tests, this.filter = function(filterFunction) {
|
|
this.filteredTests = tests.filter(filterFunction)
|
|
}, this.hasTests = function() {
|
|
return this.filteredTests.length > 0
|
|
}
|
|
}, Bahmni.Clinical.Selectable = function(data, selectableChildren, onSelectionChange) {
|
|
angular.extend(this, data);
|
|
var selectionSources = [],
|
|
children = selectableChildren || [];
|
|
onSelectionChange = onSelectionChange || angular.noop, this.isSelected = function() {
|
|
return selectionSources.length > 0
|
|
}, this.isSelectedFromSelf = function() {
|
|
return selectionSources.indexOf(this) !== -1
|
|
}, this.isSelectedFromOtherSource = function() {
|
|
return this.isSelected() && !this.isSelectedFromSelf()
|
|
}, this.addChild = function(selectable) {
|
|
children.push(selectable)
|
|
}, this.getChildrenCount = function() {
|
|
return children.length
|
|
}, this.toggle = function(selectionSource) {
|
|
this.isSelected() ? this.unselect(selectionSource) : this.select(selectionSource)
|
|
}, this.select = function(selectionSource) {
|
|
selectionSource = selectionSource || this, selectionSources.indexOf(selectionSource) === -1 && (selectionSources.push(selectionSource), angular.forEach(children, function(child) {
|
|
child.unselect(child), child.select(selectionSource)
|
|
}), onSelectionChange(this))
|
|
}, this.unselect = function(selectionSource) {
|
|
selectionSource = selectionSource || this;
|
|
var index = selectionSources.indexOf(selectionSource);
|
|
index !== -1 && (selectionSources.splice(index, 1), angular.forEach(children, function(child) {
|
|
child.unselect(selectionSource)
|
|
}), onSelectionChange(this))
|
|
}
|
|
}, Bahmni.Clinical.Specimen = function(specimen, allSamples) {
|
|
function hasResults() {
|
|
return self && self.report && self.report.results && self.report.results.length > 0
|
|
}
|
|
var self = this;
|
|
self.uuid = specimen && specimen.uuid, self.dateCollected = specimen && Bahmni.Common.Util.DateUtil.getDateWithoutTime(specimen.dateCollected), self.type = specimen && specimen.type, self.typeFreeText = specimen && specimen.typeFreeText, self.identifier = specimen && specimen.identifier, self.sample = specimen && specimen.sample && specimen.sample.additionalAttributes ? specimen.sample : {
|
|
additionalAttributes: []
|
|
}, self.report = specimen && specimen.report && specimen.report.results ? specimen.report : {
|
|
results: []
|
|
}, self.existingObs = specimen && specimen.existingObs, self.typeObservation = new Bahmni.ConceptSet.SpecimenTypeObservation(self, allSamples);
|
|
var isDirtyRuleForFreeText = function() {
|
|
return self.type && "Other" === self.type.name && !self.typeFreeText
|
|
},
|
|
clearObservations = function(obs) {
|
|
angular.forEach(obs, function(ob) {
|
|
ob.value = void 0, clearObservations(ob.groupMembers)
|
|
})
|
|
};
|
|
self.isDirty = function() {
|
|
return !!(self.dateCollected && !self.type || !self.dateCollected && !self.type && self.isAdditionalAttriburtesFilled() || !self.dateCollected && self.type || !self.dateCollected && !self.type && self.identifier || isDirtyRuleForFreeText())
|
|
}, self.isEmpty = function() {
|
|
return !(self.dateCollected || self.identifier || self.type || self.typeFreeText)
|
|
}, self.atLeastOneResult = function() {
|
|
return hasResults() && !!self.report.results[0].value
|
|
}, self.isDateCollectedDirty = function() {
|
|
return !self.dateCollected && self.hasIllegalDateCollected
|
|
}, self.isTypeDirty = function() {
|
|
return !self.type && self.hasIllegalType
|
|
}, self.isTypeFreeTextDirty = function() {
|
|
return !self.typeFreeText && self.hasIllegalTypeFreeText
|
|
}, self.isAdditionalAttriburtesFilled = function() {
|
|
var additionalAttributes = self.sample && self.sample.additionalAttributes[0] && self.sample.additionalAttributes[0].groupMembers;
|
|
for (var i in additionalAttributes)
|
|
if (additionalAttributes[i].value) return !0;
|
|
return !1
|
|
}, self.isExistingSpecimen = function() {
|
|
return self.uuid
|
|
}, self.voidIfEmpty = function() {
|
|
return !(!self.isEmpty() || !self.isExistingSpecimen()) && (self.setMandatoryFieldsBeforeSavingVoidedSpecimen(), !0)
|
|
}, self.setMandatoryFieldsBeforeSavingVoidedSpecimen = function() {
|
|
self.voided = !0, self.dateCollected = self.typeObservation.dateCollected, self.type = self.typeObservation.type, clearObservations(self.sample.additionalAttributes), clearObservations(self.report.results)
|
|
}
|
|
}, Bahmni.Clinical.DrugOrderOptions = function() {
|
|
var itemsForInputConfig = function(listOfObjects, filterStrings, filterKey) {
|
|
return filterKey = filterKey || "name", filterStrings ? _.filter(listOfObjects, function(object) {
|
|
return _.includes(filterStrings, object[filterKey])
|
|
}) : listOfObjects
|
|
};
|
|
return function(_inputConfig, masterConfig) {
|
|
var inputConfig = _inputConfig || {};
|
|
this.doseUnits = itemsForInputConfig(masterConfig.doseUnits, inputConfig.doseUnits), this.routes = itemsForInputConfig(masterConfig.routes, inputConfig.routes), this.frequencies = itemsForInputConfig(masterConfig.frequencies, inputConfig.frequencies), this.durationUnits = itemsForInputConfig(masterConfig.durationUnits, inputConfig.durationUnits), this.dosingInstructions = itemsForInputConfig(masterConfig.dosingInstructions, inputConfig.dosingInstructions), this.dispensingUnits = itemsForInputConfig(masterConfig.dispensingUnits, inputConfig.dispensingUnits), this.dosePlaceHolder = inputConfig.dosePlaceHolder, this.hiddenFields = inputConfig.hiddenFields || [], this.isDropDown = inputConfig.isDropDown, this.drugConceptSet = inputConfig.drugConceptSet, this.labels = inputConfig.labels || {}, this.doseFractions = itemsForInputConfig(masterConfig.doseFractions, inputConfig.doseFractions, "label"), this.allowNonCodedDrugs = !inputConfig.allowOnlyCodedDrugs
|
|
}
|
|
}(), angular.module("bahmni.clinical").service("urlHelper", ["$stateParams", function($stateParams) {
|
|
this.getPatientUrl = function() {
|
|
return "/patient/" + $stateParams.patientUuid + "/dashboard"
|
|
}, this.getConsultationUrl = function() {
|
|
return this.getPatientUrl() + "/consultation"
|
|
}, this.getVisitUrl = function(visitUuid) {
|
|
return this.getPatientUrl() + "/visit/" + visitUuid
|
|
}
|
|
}]), angular.module("bahmni.clinical").service("drugOrderHistoryHelper", [function() {
|
|
this.getInactiveDrugsFromPastVisit = function(activeAndScheduledDrugs, previousVisitDrugs) {
|
|
var inactivePreviousVisitDrugs = [];
|
|
return _.each(previousVisitDrugs, function(previousVisitDrug) {
|
|
var presentInActiveAndScheduledDrugs = _.find(activeAndScheduledDrugs, function(activeAndScheduledDrug) {
|
|
return activeAndScheduledDrug.drug && previousVisitDrug.drug ? activeAndScheduledDrug.drug.uuid === previousVisitDrug.drug.uuid : !(!activeAndScheduledDrug.drugNonCoded || !previousVisitDrug.drugNonCoded) && activeAndScheduledDrug.drugNonCoded === previousVisitDrug.drugNonCoded
|
|
});
|
|
presentInActiveAndScheduledDrugs || inactivePreviousVisitDrugs.push(previousVisitDrug)
|
|
}), inactivePreviousVisitDrugs
|
|
}, this.getRefillableDrugOrders = function(activeAndScheduledDrugOrders, previousVisitDrugOrders, showOnlyActive) {
|
|
var drugOrderUtil = Bahmni.Clinical.DrugOrder.Util,
|
|
now = new Date,
|
|
partitionedDrugOrders = _.groupBy(activeAndScheduledDrugOrders, function(drugOrder) {
|
|
return drugOrder.effectiveStartDate > now ? "scheduled" : "active"
|
|
}),
|
|
sortedDrugOrders = [];
|
|
return sortedDrugOrders.push(drugOrderUtil.sortDrugOrders(partitionedDrugOrders.scheduled)), sortedDrugOrders.push(drugOrderUtil.sortDrugOrders(partitionedDrugOrders.active)), showOnlyActive || sortedDrugOrders.push(drugOrderUtil.sortDrugOrders(this.getInactiveDrugsFromPastVisit(activeAndScheduledDrugOrders, previousVisitDrugOrders))), _.flatten(sortedDrugOrders)
|
|
}
|
|
}]);
|
|
var ReactHelper = {
|
|
createReactComponent: function(component, props) {
|
|
return React.createElement(component, props)
|
|
},
|
|
renderReactComponent: function(component, rootId) {
|
|
return ReactDOM.render(component, document.getElementById(rootId))
|
|
}
|
|
};
|
|
Bahmni.Clinical.DispostionActionMapper = function() {
|
|
var getMappingCode = function(concept) {
|
|
var mappingCode = "";
|
|
return concept.mappings && concept.mappings.forEach(function(mapping) {
|
|
var mappingSource = mapping.display.split(":")[0];
|
|
mappingSource === Bahmni.Common.Constants.emrapiConceptMappingSource && (mappingCode = $.trim(mapping.display.split(":")[1]))
|
|
}), mappingCode
|
|
};
|
|
this.map = function(dispositionActions) {
|
|
return dispositionActions.map(function(dispositionAction) {
|
|
return {
|
|
name: dispositionAction.name.name,
|
|
code: getMappingCode(dispositionAction)
|
|
}
|
|
})
|
|
}
|
|
}, Bahmni.LabResultsMapper = function() {
|
|
this.map = function(encounterTransaction) {
|
|
return getLabResults(getLabResultObs(encounterTransaction))
|
|
};
|
|
var getLabResults = function(observations) {
|
|
return observations.map(function(obs) {
|
|
var notes = getNotes(obs),
|
|
resultValue = obs.value,
|
|
members = isLeaf(obs) ? [] : getLabResults(obs.groupMembers);
|
|
return new Bahmni.Clinical.LabResult(obs.concept.name, resultValue, obs.comments, null, null, null, notes, members)
|
|
})
|
|
},
|
|
isLeaf = function(obs) {
|
|
return 0 === obs.groupMembers.length || "COMMENTS" === obs.groupMembers[0].concept.name
|
|
},
|
|
getNotes = function(obs) {
|
|
var notes = [];
|
|
return obs.groupMembers = obs.groupMembers || [], obs.groupMembers.forEach(function(member) {
|
|
"COMMENTS" === member.concept.name && notes.push(member.value)
|
|
}), notes
|
|
},
|
|
getLabResultObs = function(encounterTransaction) {
|
|
var labResultObs;
|
|
return encounterTransaction.observations.forEach(function(observation) {
|
|
observation.concept.name === Bahmni.Clinical.Constants.labConceptSetName && (labResultObs = observation.groupMembers)
|
|
}), labResultObs || []
|
|
}
|
|
}, Bahmni.ConsultationMapper = function(dosageFrequencies, dosageInstructions, consultationNoteConcept, labOrderNoteConcept, followUpConditionConcept) {
|
|
var filterPreviousOrderOfRevisedOrders = function(orders) {
|
|
return _.filter(orders, function(drugOrder) {
|
|
return !_.some(orders, function(otherDrugOrder) {
|
|
return otherDrugOrder.action === Bahmni.Clinical.Constants.orderActions.revise && otherDrugOrder.encounterUuid === drugOrder.encounterUuid && otherDrugOrder.previousOrderUuid === drugOrder.uuid
|
|
})
|
|
})
|
|
};
|
|
this.map = function(encounterTransaction) {
|
|
var encounterUuid = encounterTransaction.encounterUuid,
|
|
specialObservationConceptUuids = [consultationNoteConcept.uuid, labOrderNoteConcept.uuid],
|
|
investigations = encounterTransaction.orders.filter(function(order) {
|
|
return !order.voided
|
|
}),
|
|
labResults = (new Bahmni.LabResultsMapper).map(encounterTransaction),
|
|
nonVoidedDrugOrders = encounterTransaction.drugOrders.filter(function(order) {
|
|
return !order.voided && order.action !== Bahmni.Clinical.Constants.orderActions.discontinue
|
|
});
|
|
nonVoidedDrugOrders = filterPreviousOrderOfRevisedOrders(nonVoidedDrugOrders);
|
|
var treatmentDrugs = nonVoidedDrugOrders.map(function(drugOrder) {
|
|
return Bahmni.Clinical.DrugOrderViewModel.createFromContract(drugOrder)
|
|
}),
|
|
consultationNote = mapSpecialObservation(encounterTransaction.observations, consultationNoteConcept),
|
|
labOrderNote = mapSpecialObservation(encounterTransaction.observations, labOrderNoteConcept),
|
|
observations = encounterTransaction.observations.filter(function(observation) {
|
|
return !observation.voided && specialObservationConceptUuids.indexOf(observation.concept.uuid) === -1
|
|
}),
|
|
orders = encounterTransaction.orders.filter(function(order) {
|
|
return order.action !== Bahmni.Clinical.Constants.orderActions.discontinue && !order.dateStopped
|
|
}),
|
|
mdrtbSpecimen = encounterTransaction.extensions.mdrtbSpecimen && encounterTransaction.extensions.mdrtbSpecimen.map(function(specimen) {
|
|
return specimen.sample && (specimen.sample.additionalAttributes = specimen.sample.additionalAttributes ? (new Bahmni.Common.Obs.ObservationMapper).map([specimen.sample.additionalAttributes], {}) : []), specimen.report && (specimen.report.results = specimen.report.results ? (new Bahmni.Common.Obs.ObservationMapper).map([specimen.report.results], {}) : []), new Bahmni.Clinical.Specimen(specimen)
|
|
}),
|
|
followUpConditions = _.filter(encounterTransaction.observations, function(observation) {
|
|
return _.get(followUpConditionConcept, "uuid") == _.get(observation, "concept.uuid")
|
|
});
|
|
return {
|
|
visitUuid: encounterTransaction.visitUuid,
|
|
visitTypeUuid: encounterTransaction.visitTypeUuid,
|
|
encounterUuid: encounterUuid,
|
|
investigations: investigations,
|
|
treatmentDrugs: treatmentDrugs,
|
|
newlyAddedDiagnoses: [],
|
|
newlyAddedSpecimens: [],
|
|
labResults: labResults,
|
|
consultationNote: consultationNote || emptyObservation(consultationNoteConcept),
|
|
labOrderNote: labOrderNote || emptyObservation(labOrderNoteConcept),
|
|
observations: observations,
|
|
disposition: encounterTransaction.disposition,
|
|
encounterDateTime: encounterTransaction.encounterDateTime,
|
|
orders: orders,
|
|
patientUuid: encounterTransaction.patientUuid,
|
|
visitType: encounterTransaction.visitType,
|
|
providers: encounterTransaction.providers,
|
|
locationUuid: encounterTransaction.locationUuid,
|
|
extensions: {
|
|
mdrtbSpecimen: mdrtbSpecimen
|
|
},
|
|
followUpConditions: followUpConditions
|
|
}
|
|
};
|
|
var emptyObservation = function(concept) {
|
|
return {
|
|
concept: {
|
|
uuid: concept.uuid
|
|
}
|
|
}
|
|
},
|
|
mapSpecialObservation = function(encounterObservations, specialConcept) {
|
|
var observation = emptyObservation(specialConcept),
|
|
obsFromEncounter = encounterObservations.filter(function(obs) {
|
|
return obs.concept && obs.concept.uuid === specialConcept.uuid && !obs.voided
|
|
})[0];
|
|
return obsFromEncounter && (observation.value = obsFromEncounter.value, observation.uuid = obsFromEncounter.uuid, observation.observationDateTime = obsFromEncounter.observationDateTime), observation
|
|
}
|
|
}, Bahmni.LabConceptsMapper = function() {
|
|
var LabConceptsMapper = function() {},
|
|
forConcptClass = function(conceptClassName) {
|
|
return function(concept) {
|
|
return concept.conceptClass.name === conceptClassName
|
|
}
|
|
},
|
|
assignDepartmentToTests = function(tests, departmentConceptSet) {
|
|
var departmentConcepts = departmentConceptSet ? departmentConceptSet.setMembers : [];
|
|
angular.forEach(departmentConcepts, function(departmentConcept) {
|
|
var department = {
|
|
name: departmentConcept.name.name
|
|
};
|
|
angular.forEach(departmentConcept.setMembers, function(testConcept) {
|
|
var test = tests.filter(function(test) {
|
|
return test.uuid === testConcept.uuid
|
|
})[0];
|
|
test && (test.department = department)
|
|
})
|
|
})
|
|
},
|
|
createTest = function(concept, sample, panels) {
|
|
return {
|
|
uuid: concept.uuid,
|
|
name: concept.name.name,
|
|
sample: sample,
|
|
panels: panels,
|
|
set: !1,
|
|
orderTypeName: Bahmni.Clinical.Constants.labOrderType
|
|
}
|
|
},
|
|
createPanel = function(concept, sample) {
|
|
return {
|
|
uuid: concept.uuid,
|
|
name: concept.name.name,
|
|
sample: sample,
|
|
set: !0,
|
|
orderTypeName: Bahmni.Clinical.Constants.labOrderType
|
|
}
|
|
},
|
|
mapPanelTests = function(sample, tests, panelConcept) {
|
|
var panel = createPanel(panelConcept, sample),
|
|
testConcepts = panelConcept.setMembers.filter(forConcptClass(Bahmni.Clinical.Constants.testConceptName));
|
|
angular.forEach(testConcepts, function(testConcept) {
|
|
var test = tests.filter(function(test) {
|
|
return test.uuid === testConcept.uuid
|
|
})[0];
|
|
test ? test.panels.push(panel) : tests.push(createTest(testConcept, sample, [panel]))
|
|
})
|
|
};
|
|
return LabConceptsMapper.prototype = {
|
|
map: function(labConceptSet, departmentConceptSet) {
|
|
if (!labConceptSet) return [];
|
|
var tests = [],
|
|
sampleConcepts = labConceptSet.setMembers;
|
|
return angular.forEach(sampleConcepts, function(sampleConcept) {
|
|
var sample = {
|
|
uuid: sampleConcept.uuid,
|
|
name: sampleConcept.name.name
|
|
},
|
|
panelConcepts = sampleConcept.setMembers.filter(forConcptClass(Bahmni.Clinical.Constants.labSetConceptName)),
|
|
testConcepts = sampleConcept.setMembers.filter(forConcptClass(Bahmni.Clinical.Constants.testConceptName));
|
|
angular.forEach(panelConcepts, function(panelConcept) {
|
|
mapPanelTests(sample, tests, panelConcept)
|
|
}), angular.forEach(testConcepts, function(testConcept) {
|
|
var test = tests.filter(function(test) {
|
|
return test.uuid === testConcept.uuid
|
|
})[0];
|
|
test || tests.push(createTest(testConcept, sample, []))
|
|
})
|
|
}), assignDepartmentToTests(tests, departmentConceptSet), tests
|
|
}
|
|
}, LabConceptsMapper
|
|
}(), Bahmni.Clinical.EncounterTransactionMapper = function() {
|
|
var addEditedDiagnoses = function(consultation, diagnosisList) {
|
|
consultation.pastDiagnoses && consultation.pastDiagnoses.forEach(function(diagnosis) {
|
|
diagnosis.isDirty && (diagnosis.diagnosisDateTime = null, diagnosisList.push(diagnosis))
|
|
}), consultation.savedDiagnosesFromCurrentEncounter && consultation.savedDiagnosesFromCurrentEncounter.forEach(function(diagnosis) {
|
|
diagnosis.isDirty && (diagnosis.diagnosisDateTime = null, diagnosisList.push(diagnosis))
|
|
})
|
|
};
|
|
this.map = function(consultation, patient, locationUuid, retrospectiveEntry, defaultRetrospectiveVisitType, defaultVisitType, isInEditEncounterMode, patientProgramUuid) {
|
|
var encounterData = {};
|
|
encounterData.locationUuid = isInEditEncounterMode ? consultation.locationUuid : locationUuid, encounterData.patientUuid = patient.uuid, encounterData.encounterUuid = consultation.encounterUuid, encounterData.visitUuid = consultation.visitUuid, encounterData.providers = consultation.providers, encounterData.encounterDateTime = consultation.encounterDateTime, encounterData.extensions = {
|
|
mdrtbSpecimen: consultation.newlyAddedSpecimens
|
|
}, encounterData.context = {
|
|
patientProgramUuid: patientProgramUuid
|
|
}, _.isEmpty(retrospectiveEntry) ? encounterData.visitUuid ? encounterData.visitType || (encounterData.visitType = defaultVisitType) : encounterData.visitType = defaultVisitType : encounterData.visitType = defaultRetrospectiveVisitType || "OPD", consultation.newlyAddedDiagnoses && consultation.newlyAddedDiagnoses.length > 0 ? encounterData.bahmniDiagnoses = consultation.newlyAddedDiagnoses.map(function(diagnosis) {
|
|
return {
|
|
codedAnswer: {
|
|
uuid: diagnosis.isNonCodedAnswer ? void 0 : diagnosis.codedAnswer.uuid
|
|
},
|
|
freeTextAnswer: diagnosis.isNonCodedAnswer ? diagnosis.codedAnswer.name : void 0,
|
|
order: diagnosis.order,
|
|
certainty: diagnosis.certainty,
|
|
existingObs: null,
|
|
diagnosisDateTime: null,
|
|
diagnosisStatusConcept: diagnosis.diagnosisStatusConcept,
|
|
voided: diagnosis.voided,
|
|
comments: diagnosis.comments
|
|
}
|
|
}) : encounterData.bahmniDiagnoses = [], addEditedDiagnoses(consultation, encounterData.bahmniDiagnoses), encounterData.orders = [];
|
|
var addOrdersToEncounter = function() {
|
|
var modifiedOrders = _.filter(consultation.orders, function(order) {
|
|
return order.hasBeenModified || order.isDiscontinued || !order.uuid
|
|
}),
|
|
tempOrders = modifiedOrders.map(function(order) {
|
|
return order.urgency = order.isUrgent ? "STAT" : void 0, order.hasBeenModified && !order.isDiscontinued ? Bahmni.Clinical.Order.revise(order) : order.isDiscontinued ? Bahmni.Clinical.Order.discontinue(order) : {
|
|
uuid: order.uuid,
|
|
concept: {
|
|
name: order.concept.name,
|
|
uuid: order.concept.uuid
|
|
},
|
|
commentToFulfiller: order.commentToFulfiller,
|
|
urgency: order.urgency
|
|
}
|
|
});
|
|
encounterData.orders = encounterData.orders.concat(tempOrders)
|
|
};
|
|
addOrdersToEncounter(), consultation.drugOrders = [];
|
|
var newlyAddedTreatments = consultation.newlyAddedTreatments;
|
|
newlyAddedTreatments && newlyAddedTreatments.forEach(function(treatment) {
|
|
consultation.drugOrders.push(Bahmni.Clinical.DrugOrder.createFromUIObject(treatment))
|
|
}), consultation.removableDrugs && (consultation.drugOrders = consultation.drugOrders.concat(consultation.removableDrugs)), encounterData.drugOrders = consultation.drugOrders, encounterData.disposition = consultation.disposition;
|
|
var addObservationsToEncounter = function() {
|
|
if (encounterData.observations = consultation.observations || [], consultation.consultationNote && encounterData.observations.push(consultation.consultationNote), consultation.labOrderNote && encounterData.observations.push(consultation.labOrderNote), !_.isEmpty(consultation.drugOrdersWithUpdatedOrderAttributes)) {
|
|
var orderAttributes = _.values(consultation.drugOrdersWithUpdatedOrderAttributes).map(function(drugOrder) {
|
|
return drugOrder.getOrderAttributesAsObs()
|
|
});
|
|
encounterData.observations = encounterData.observations.concat(_.flatten(orderAttributes))
|
|
}
|
|
};
|
|
return addObservationsToEncounter(), consultation.followUpConditions && [].push.apply(consultation.observations, consultation.followUpConditions), encounterData
|
|
}
|
|
}, Bahmni.Clinical.SpecimenMapper = function() {
|
|
this.mapObservationToSpecimen = function(observation, allSamples, conceptsConfig, dontSortByObsDateTime) {
|
|
var specimen = new Bahmni.Clinical.Specimen(observation, allSamples);
|
|
if (specimen.specimenId = specimen.identifier, specimen.specimenSource = specimen.type.shortName ? specimen.type.shortName : specimen.type.name, specimen.specimenCollectionDate = specimen.dateCollected, specimen.report && specimen.report.results) {
|
|
specimen.report.results = specimen.report.results instanceof Array ? specimen.report.results : [specimen.report.results];
|
|
var obs = (new Bahmni.Common.Obs.ObservationMapper).map(specimen.report.results, conceptsConfig, dontSortByObsDateTime);
|
|
specimen.sampleResult = obs && obs.length > 0 ? obs[0] : obs
|
|
}
|
|
return specimen.sample && specimen.sample.additionalAttributes && (specimen.sample.additionalAttributes = specimen.sample.additionalAttributes instanceof Array ? specimen.sample.additionalAttributes : [specimen.sample.additionalAttributes]), specimen
|
|
}, this.mapSpecimenToObservation = function(specimen) {
|
|
var observation = {};
|
|
observation.dateCollected = moment(specimen.dateCollected).format("YYYY-MM-DDTHH:mm:ss.SSSZ"), observation.existingObs = specimen.existingObs, observation.identifier = specimen.identifier, observation.sample = {}, observation.report = {}, observation.type = specimen.type, observation.voided = specimen.voided, observation.typeFreeText = specimen.typeFreeText, observation.uuid = specimen.uuid;
|
|
var observationFilter = new Bahmni.Common.Domain.ObservationFilter;
|
|
return observation.sample.additionalAttributes = Array.isArray(specimen.sample.additionalAttributes) ? specimen.sample.additionalAttributes : [specimen.sample.additionalAttributes], observation.sample.additionalAttributes = observationFilter.filter(specimen.sample.additionalAttributes)[0], observation.report.results = Array.isArray(specimen.report.results) ? specimen.report.results : [specimen.report.results], observation.report.results = observationFilter.filter(specimen.report.results)[0], observation
|
|
}
|
|
}, Bahmni.OtherInvestigationsConceptsMapper = function() {
|
|
var OtherInvestigationsConceptsMapper = function(orderTypesMap) {
|
|
this.orderTypesMap = orderTypesMap
|
|
},
|
|
assignCategoriesToTests = function(tests, categoryConceptSet) {
|
|
var categoryConcepts = categoryConceptSet ? categoryConceptSet.setMembers : [];
|
|
angular.forEach(categoryConcepts, function(categoryConcept) {
|
|
var category = {
|
|
name: categoryConcept.name.name
|
|
};
|
|
angular.forEach(categoryConcept.setMembers, function(testConcept) {
|
|
var test = tests.filter(function(test) {
|
|
return test.uuid === testConcept.uuid
|
|
})[0];
|
|
test && (test.category = category)
|
|
})
|
|
})
|
|
},
|
|
createTest = function(concept, investigationType, orderTypesMap) {
|
|
var orderTypeName = orderTypesMap[investigationType.name] || investigationType.name;
|
|
return {
|
|
uuid: concept.uuid,
|
|
name: concept.name.name,
|
|
type: investigationType,
|
|
orderTypeName: orderTypeName
|
|
}
|
|
};
|
|
return OtherInvestigationsConceptsMapper.prototype = {
|
|
map: function(otherInvestigationsConcept, categoryConceptSet) {
|
|
var self = this;
|
|
if (!otherInvestigationsConcept) return [];
|
|
var tests = [],
|
|
testTypeSets = otherInvestigationsConcept.setMembers.filter(function(concept) {
|
|
return concept.set
|
|
});
|
|
return angular.forEach(testTypeSets, function(concept) {
|
|
var type = {
|
|
uuid: concept.uuid,
|
|
name: concept.name.name
|
|
},
|
|
testConcepts = concept.setMembers.filter(function(concept) {
|
|
return concept.conceptClass.name === Bahmni.Clinical.Constants.testConceptName
|
|
});
|
|
angular.forEach(testConcepts, function(testConcept) {
|
|
tests.push(createTest(testConcept, type, self.orderTypesMap))
|
|
})
|
|
}), assignCategoriesToTests(tests, categoryConceptSet), tests
|
|
}
|
|
}, OtherInvestigationsConceptsMapper
|
|
}(), angular.module("bahmni.clinical").service("patientVisitHistoryService", ["visitService", function(visitService) {
|
|
this.getVisitHistory = function(patientUuid, currentVisitLocation) {
|
|
return visitService.search({
|
|
patient: patientUuid,
|
|
v: "custom:(uuid,visitType,startDatetime,stopDatetime,location,encounters:(uuid))",
|
|
includeInactive: !0
|
|
}).then(function(data) {
|
|
var visits = _.map(data.data.results, function(visitData) {
|
|
return new Bahmni.Clinical.VisitHistoryEntry(visitData)
|
|
}),
|
|
activeVisit = visits.filter(function(visit) {
|
|
return visit.isActive() && visit.isFromCurrentLocation(currentVisitLocation)
|
|
})[0];
|
|
return {
|
|
visits: visits,
|
|
activeVisit: activeVisit
|
|
}
|
|
})
|
|
}
|
|
}]), angular.module("bahmni.clinical").service("labTestsProvider", ["$q", "conceptSetService", function($q, conceptSetService) {
|
|
this.getTests = function() {
|
|
var deferer = $q.defer(),
|
|
labConceptsPromise = conceptSetService.getConcept({
|
|
name: Bahmni.Clinical.Constants.labConceptSetName,
|
|
v: "custom:(uuid,setMembers:(uuid,name,conceptClass,setMembers:(uuid,name,conceptClass,setMembers:(uuid,name,conceptClass))))"
|
|
}, !0),
|
|
departmentConceptsPromise = conceptSetService.getConcept({
|
|
name: Bahmni.Clinical.Constants.labDepartmentsConceptSetName,
|
|
v: "custom:(uuid,setMembers:(uuid,name,setMembers:(uuid,name)))"
|
|
}, !0);
|
|
return $q.all([labConceptsPromise, departmentConceptsPromise]).then(function(results) {
|
|
var labConceptsSet = results[0].data.results[0],
|
|
labDepartmentsSet = results[1].data.results[0],
|
|
tests = (new Bahmni.LabConceptsMapper).map(labConceptsSet, labDepartmentsSet);
|
|
deferer.resolve(tests)
|
|
}, deferer.reject), deferer.promise
|
|
}
|
|
}]), angular.module("bahmni.clinical").service("otherTestsProvider", ["$q", "conceptSetService", "clinicalAppConfigService", function($q, conceptSetService, clinicalAppConfigService) {
|
|
var orderTypesMapConfig = clinicalAppConfigService.getOtherInvestigationsMap(),
|
|
orderTypesMap = orderTypesMapConfig ? orderTypesMapConfig.value : {},
|
|
mapper = new Bahmni.OtherInvestigationsConceptsMapper(orderTypesMap);
|
|
this.getTests = function() {
|
|
var deferer = $q.defer(),
|
|
otherInvestigationsConceptPromise = conceptSetService.getConcept({
|
|
name: Bahmni.Clinical.Constants.otherInvestigationsConceptSetName,
|
|
v: "fullchildren"
|
|
}, !0),
|
|
categoriesConceptPromise = conceptSetService.getConcept({
|
|
name: Bahmni.Clinical.Constants.otherInvestigationCategoriesConceptSetName,
|
|
v: "custom:(uuid,setMembers:(uuid,name,setMembers:(uuid,name)))"
|
|
}, !0);
|
|
return $q.all([otherInvestigationsConceptPromise, categoriesConceptPromise]).then(function(results) {
|
|
var otherInvestigationConcept = results[0].data.results[0],
|
|
labDepartmentsSet = results[1].data.results[0],
|
|
tests = mapper.map(otherInvestigationConcept, labDepartmentsSet);
|
|
deferer.resolve(tests)
|
|
}, deferer.reject), deferer.promise
|
|
}
|
|
}]), Bahmni.Clinical.Notifier = function() {
|
|
var callBacks = {};
|
|
this.register = function(key, callback) {
|
|
callBacks[key] = callback
|
|
}, this.fire = function() {
|
|
_.each(callBacks, function(callback) {
|
|
callback()
|
|
})
|
|
}
|
|
}, angular.module("bahmni.clinical").factory("treatmentConfig", ["treatmentService", "spinner", "configurationService", "appService", "$q", "$translate", function(treatmentService, spinner, configurationService, appService, $q, $translate) {
|
|
var getConfigFromServer = function(baseTreatmentConfig) {
|
|
return treatmentService.getConfig().then(function(result) {
|
|
var config = angular.extend(baseTreatmentConfig, result.data);
|
|
return config.durationUnits = [{
|
|
name: "Day(s)",
|
|
factor: 1
|
|
}, {
|
|
name: "Week(s)",
|
|
factor: 7
|
|
}, {
|
|
name: "Month(s)",
|
|
factor: 30
|
|
}], config.frequencies = _(config.frequencies).reverse().sortBy({
|
|
name: "Immediately"
|
|
}).sortBy({
|
|
name: "SOS"
|
|
}).reverse().value(), config
|
|
})
|
|
},
|
|
setNonCodedDrugConcept = function(config) {
|
|
return treatmentService.getNonCodedDrugConcept().then(function(data) {
|
|
return config.nonCodedDrugconcept = {
|
|
uuid: data
|
|
}, config
|
|
})
|
|
},
|
|
setStoppedOrderReasonConcepts = function(config) {
|
|
return configurationService.getConfigurations(["stoppedOrderReasonConfig"]).then(function(response) {
|
|
var stoppedOrderReasonConfig = response.stoppedOrderReasonConfig.results[0] || {};
|
|
return config.stoppedOrderReasonConcepts = stoppedOrderReasonConfig.answers, config
|
|
})
|
|
};
|
|
return function(tabConfigName) {
|
|
var drugOrderOptions, baseTreatmentConfig = {
|
|
allowNonCodedDrugs: function() {
|
|
return drugOrderOptions.allowNonCodedDrugs
|
|
},
|
|
getDoseUnits: function() {
|
|
return drugOrderOptions.doseUnits
|
|
},
|
|
getRoutes: function() {
|
|
return drugOrderOptions.routes
|
|
},
|
|
getDurationUnits: function() {
|
|
return drugOrderOptions.durationUnits
|
|
},
|
|
getDosingInstructions: function() {
|
|
return drugOrderOptions.dosingInstructions
|
|
},
|
|
getDispensingUnits: function() {
|
|
return drugOrderOptions.dispensingUnits
|
|
},
|
|
getFrequencies: function() {
|
|
return drugOrderOptions.frequencies
|
|
},
|
|
getDosePlaceHolder: function() {
|
|
return drugOrderOptions.dosePlaceHolder
|
|
},
|
|
getDoseFractions: function() {
|
|
return drugOrderOptions.doseFractions
|
|
},
|
|
isHiddenField: function(fieldName) {
|
|
return _.includes(drugOrderOptions.hiddenFields, fieldName)
|
|
},
|
|
isDropDown: function() {
|
|
return drugOrderOptions.isDropDown && drugOrderOptions.drugConceptSet
|
|
},
|
|
isAutoComplete: function() {
|
|
return !this.isDropDown()
|
|
},
|
|
getDrugConceptSet: function() {
|
|
return drugOrderOptions.drugConceptSet
|
|
},
|
|
isDropDownForGivenConceptSet: function() {
|
|
return this.isDropDown() && this.getDrugConceptSet()
|
|
},
|
|
isAutoCompleteForGivenConceptSet: function() {
|
|
return this.isAutoComplete() && this.getDrugConceptSet()
|
|
},
|
|
isAutoCompleteForAllConcepts: function() {
|
|
return !this.getDrugConceptSet()
|
|
},
|
|
showAdditionalInformation: function() {
|
|
var additionalInformationFields = ["sos", "additionalInstructions", "dosingInstructions"],
|
|
hiddenAdditionalInformationFields = _.intersection(additionalInformationFields, drugOrderOptions.hiddenFields);
|
|
return hiddenAdditionalInformationFields.length < additionalInformationFields.length
|
|
},
|
|
translate: function(field, defaultKey) {
|
|
var labelKey = drugOrderOptions.labels[field],
|
|
labelValue = $translate.instant(labelKey);
|
|
return labelValue === labelKey && (labelValue = $translate.instant(defaultKey)), labelValue
|
|
},
|
|
showBulkChangeDuration: function() {
|
|
return !this.hideBulkChangeDurationButton
|
|
}
|
|
},
|
|
setDrugOrderOptions = function(medicationTabConfig, tabConfigName) {
|
|
var medicationJson = appService.getAppDescriptor().getConfigForPage("medication") || {},
|
|
commonConfig = medicationJson.commonConfig || {},
|
|
allTabConfigs = medicationJson.tabConfig || {},
|
|
tabConfig = allTabConfigs[tabConfigName] || {};
|
|
tabConfig.inputOptionsConfig = tabConfig.inputOptionsConfig || {}, tabConfig.orderSet = tabConfig.orderSet || {};
|
|
var showDoseFractions = tabConfig.inputOptionsConfig.showDoseFractions;
|
|
return tabConfig.inputOptionsConfig.showDoseFractions = !!showDoseFractions && showDoseFractions, tabConfig.drugOrderHistoryConfig = tabConfig.drugOrderHistoryConfig || {}, angular.extend(medicationTabConfig, commonConfig, tabConfig), drugOrderOptions = new Bahmni.Clinical.DrugOrderOptions(medicationTabConfig.inputOptionsConfig, medicationTabConfig), medicationTabConfig
|
|
};
|
|
return getConfigFromServer(baseTreatmentConfig).then(function(config) {
|
|
return setDrugOrderOptions(config, tabConfigName)
|
|
}).then(setStoppedOrderReasonConcepts).then(setNonCodedDrugConcept)
|
|
}
|
|
}]), angular.module("bahmni.clinical").filter("observationValue", function() {
|
|
return function(obs) {
|
|
return Bahmni.Common.Domain.ObservationValueMapper.map(obs)
|
|
}
|
|
}), angular.module("bahmni.clinical").directive("buttonsRadio", function() {
|
|
return {
|
|
restrict: "E",
|
|
scope: {
|
|
model: "=",
|
|
options: "=",
|
|
dirtyCheckFlag: "="
|
|
},
|
|
link: function(scope, element, attrs) {
|
|
attrs.dirtyCheckFlag && (scope.hasDirtyFlag = !0)
|
|
},
|
|
controller: function($scope) {
|
|
angular.isString($scope.options) && ($scope.options = $scope.options.split(",").reduce(function(options, item) {
|
|
return options[item] = item, options
|
|
}, {})), $scope.activate = function(option) {
|
|
$scope.model === option ? $scope.model = void 0 : $scope.model = option, $scope.hasDirtyFlag && ($scope.dirtyCheckFlag = !0)
|
|
}
|
|
},
|
|
template: "<button type='button' class='btn' ng-class='{active: value === model}'ng-repeat='(displayOption,value) in options' ng-click='activate(value)'><span></span>{{displayOption | translate}} </button>"
|
|
}
|
|
}), angular.module("bahmni.clinical").directive("orderSelector", [function() {
|
|
var link = function($scope) {
|
|
$scope.hasTests = function() {
|
|
var rootConcept = $scope.tab.leftCategory;
|
|
return rootConcept && !_.isEmpty(rootConcept.setMembers)
|
|
}, $scope.filterByConceptClass = function(test) {
|
|
return test.conceptClass.name === $scope.group.name
|
|
};
|
|
var filterBySearchString = function(testName) {
|
|
return _.includes(_.toLower(testName.name), _.toLower($scope.search.string))
|
|
};
|
|
$scope.filterBySearchString = function(test) {
|
|
return _.some(test.names, filterBySearchString)
|
|
}
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
link: link,
|
|
templateUrl: "./consultation/views/orderSelector.html",
|
|
scope: !1
|
|
}
|
|
}]), angular.module("bahmni.clinical").directive("diagnosisAutoComplete", ["$parse", function($parse) {
|
|
var link = function(scope, element, attrs) {
|
|
var ngModel = $parse(attrs.ngModel),
|
|
source = scope.source(),
|
|
responseMap = scope.responseMap(),
|
|
onSelect = scope.onSelect();
|
|
element.autocomplete({
|
|
autofocus: !0,
|
|
minLength: 2,
|
|
source: function(request, response) {
|
|
source(request.term).success(function(data) {
|
|
var results = responseMap ? responseMap(data) : data;
|
|
response(results)
|
|
})
|
|
},
|
|
select: function(event, ui) {
|
|
return scope.$apply(function() {
|
|
ngModel.assign(scope, ui.item.value), onSelect && onSelect(scope.index, ui.item.lookup), scope.$eval(attrs.ngChange)
|
|
}), !0
|
|
},
|
|
search: function(event) {
|
|
var searchTerm = $.trim(element.val());
|
|
searchTerm.length < 2 && event.preventDefault()
|
|
}
|
|
})
|
|
};
|
|
return {
|
|
link: link,
|
|
require: "ngModel",
|
|
scope: {
|
|
source: "&",
|
|
responseMap: "&",
|
|
onSelect: "&",
|
|
index: "="
|
|
}
|
|
}
|
|
}]), angular.module("bahmni.clinical").directive("newDrugOrders", ["messagingService", function(messagingService) {
|
|
var controller = function($scope, $rootScope) {
|
|
$scope.edit = function(drugOrder, index) {
|
|
$rootScope.$broadcast("event:editDrugOrder", drugOrder, index)
|
|
}, $scope.remove = function(index) {
|
|
$rootScope.$broadcast("event:removeDrugOrder", index)
|
|
};
|
|
var defaultBulkDuration = function() {
|
|
return {
|
|
bulkDurationUnit: $scope.treatmentConfig.durationUnits ? $scope.treatmentConfig.durationUnits[0].name : ""
|
|
}
|
|
};
|
|
$scope.bulkDurationData = defaultBulkDuration();
|
|
var clearBulkDurationChange = function() {
|
|
$scope.bulkDurationData = defaultBulkDuration(), $scope.bulkSelectCheckbox = !1
|
|
};
|
|
$scope.bulkDurationChangeDone = function() {
|
|
$scope.bulkDurationData.bulkDuration && $scope.bulkDurationData.bulkDurationUnit && $scope.treatments.forEach(function(treatment) {
|
|
treatment.durationUpdateFlag && (treatment.duration || (treatment.quantityEnteredManually = !1), treatment.duration = $scope.bulkDurationData.bulkDuration, treatment.durationUnit = $scope.bulkDurationData.bulkDurationUnit, treatment.calculateDurationInDays(), treatment.calculateQuantityAndUnit())
|
|
}), clearBulkDurationChange(), $scope.bulkChangeDuration()
|
|
};
|
|
var isDurationNullForAnyTreatment = function(treatments) {
|
|
var isDurationNull = !1;
|
|
return treatments.forEach(function(treatment) {
|
|
treatment.duration || (isDurationNull = !0)
|
|
}), isDurationNull
|
|
},
|
|
setNonCodedDrugConcept = function(treatment) {
|
|
treatment.drugNonCoded && (treatment.concept = $scope.treatmentConfig.nonCodedDrugconcept)
|
|
};
|
|
$scope.selectAllCheckbox = function() {
|
|
$scope.bulkSelectCheckbox = !$scope.bulkSelectCheckbox, $scope.treatments.forEach(function(treatment) {
|
|
setNonCodedDrugConcept(treatment), treatment.durationUpdateFlag = $scope.bulkSelectCheckbox
|
|
})
|
|
}, $scope.bulkChangeDuration = function() {
|
|
$scope.showBulkChangeToggle = !$scope.showBulkChangeToggle, clearBulkDurationChange(), $scope.selectAllCheckbox(), $scope.showBulkChangeToggle && isDurationNullForAnyTreatment($scope.treatments) && messagingService.showMessage("info", "There are drugs that do no have a duration specified.Updating duration will update for those drugs as well")
|
|
}, $scope.showBulkChangeDuration = $scope.treatmentConfig.showBulkChangeDuration(), $scope.updateDuration = function(stepperValue) {
|
|
!$scope.bulkDurationData.bulkDuration && isNaN($scope.bulkDurationData.bulkDuration) && ($scope.bulkDurationData.bulkDuration = 0), $scope.bulkDurationData.bulkDuration += stepperValue
|
|
}
|
|
};
|
|
return {
|
|
templateUrl: "consultation/views/newDrugOrders.html",
|
|
scope: {
|
|
treatments: "=",
|
|
treatmentConfig: "="
|
|
},
|
|
controller: controller
|
|
}
|
|
}]), angular.module("bahmni.clinical").directive("newOrderGroup", [function() {
|
|
var controller = function($scope) {
|
|
$scope.config = {
|
|
columns: ["drugName", "dosage", "frequency", "route", "duration", "startDate", "instructions"],
|
|
actions: ["edit"],
|
|
columnHeaders: {
|
|
frequency: "MEDICATION_LABEL_FREQUENCY",
|
|
drugName: "MEDICATION_DRUG_NAME_TITLE"
|
|
}
|
|
};
|
|
var setOrderSetName = function(orderSetNewName) {
|
|
_.isUndefined(orderSetNewName) || ($scope.config.title = orderSetNewName)
|
|
};
|
|
$scope.$watch("orderSetName", setOrderSetName)
|
|
};
|
|
return {
|
|
templateUrl: "consultation/views/newOrderGroup.html",
|
|
scope: {
|
|
treatments: "=",
|
|
orderSetName: "="
|
|
},
|
|
controller: controller
|
|
}
|
|
}]), angular.module("bahmni.clinical").controller("InvestigationsSelectorController", ["$scope", "spinner", "configurations", function($scope, spinner, configurations) {
|
|
var Selectable = Bahmni.Clinical.Selectable,
|
|
Category = Bahmni.Clinical.Category;
|
|
$scope.selectablePanels = [], $scope.selectableTests = [], spinner.forPromise($scope.testsProvider.getTests()).then(function(tests) {
|
|
initializeTests(tests), selectSelectablesBasedOnInvestigations(), $scope.showAll()
|
|
});
|
|
var onSelectionChange = function(selectable) {
|
|
selectable.isSelected() ? selectable.isSelectedFromSelf() && addInvestigationForSelectable(selectable) : removeInvestigationForSelectable(selectable)
|
|
},
|
|
initializeTests = function(tests) {
|
|
var categories = $scope.categories = [],
|
|
selectablePanels = $scope.selectablePanels = [],
|
|
selectableTests = $scope.selectableTests = [],
|
|
filters = $scope.filters = [];
|
|
angular.forEach(tests, function(test) {
|
|
var selectableTest = new Selectable(test, [], onSelectionChange);
|
|
selectableTests.push(selectableTest);
|
|
var categoryData = test[$scope.categoryColumn] || {
|
|
name: "Other"
|
|
},
|
|
category = categories.filter(function(category) {
|
|
return category.name === categoryData.name
|
|
})[0];
|
|
category ? category.tests.push(selectableTest) : categories.push(new Category(categoryData.name, [selectableTest])), angular.forEach(test.panels, function(testPanel) {
|
|
var selectablePanel = selectablePanels.filter(function(panel) {
|
|
return panel.name === testPanel.name
|
|
})[0];
|
|
selectablePanel ? selectablePanel.addChild(selectableTest) : (selectablePanel = new Selectable(testPanel, [selectableTest], onSelectionChange), selectablePanels.push(selectablePanel))
|
|
});
|
|
var filter = test[$scope.filterColumn];
|
|
filters.indexOf(filter) === -1 && filters.push(filter)
|
|
})
|
|
},
|
|
selectSelectablesBasedOnInvestigations = function() {
|
|
var selectables = $scope.allSelectables(),
|
|
currentInvestigations = $scope.investigations.filter(function(investigation) {
|
|
return !investigation.voided
|
|
});
|
|
angular.forEach(currentInvestigations, function(investigation) {
|
|
var selectable = findSelectableForInvestigation(selectables, investigation);
|
|
selectable && selectable.select()
|
|
})
|
|
},
|
|
findSelectableForInvestigation = function(selectables, investigation) {
|
|
return selectables.filter(function(selectableConcept) {
|
|
return selectableConcept.uuid === investigation.concept.uuid
|
|
})[0]
|
|
},
|
|
createInvestigationFromSelectable = function(selectable) {
|
|
return {
|
|
concept: {
|
|
uuid: selectable.uuid,
|
|
name: selectable.name,
|
|
set: selectable.set
|
|
},
|
|
orderTypeUuid: configurations.encounterConfig().orderTypes[selectable.orderTypeName],
|
|
voided: !1
|
|
}
|
|
},
|
|
addInvestigationForSelectable = function(selectable) {
|
|
var investigation = findInvestigationForSelectable(selectable);
|
|
investigation ? investigation.voided = !1 : $scope.investigations.push(createInvestigationFromSelectable(selectable))
|
|
},
|
|
removeInvestigationForSelectable = function(selectable) {
|
|
var investigation = findInvestigationForSelectable(selectable);
|
|
investigation && removeInvestigation(investigation)
|
|
},
|
|
removeInvestigation = function(investigation) {
|
|
if (investigation.uuid) investigation.voided = !0;
|
|
else {
|
|
var index = $scope.investigations.indexOf(investigation);
|
|
$scope.investigations.splice(index, 1)
|
|
}
|
|
},
|
|
findInvestigationForSelectable = function(selectable) {
|
|
return $scope.investigations.filter(function(investigation) {
|
|
return investigation.concept.uuid === selectable.uuid
|
|
})[0]
|
|
};
|
|
$scope.showAll = function() {
|
|
$scope.filterBy(null)
|
|
};
|
|
var applyCurrentFilterByFilterCoulmn = function(selectable) {
|
|
return !$scope.currentFilter || selectable[$scope.filterColumn] === $scope.currentFilter
|
|
};
|
|
$scope.filterBy = function(filter) {
|
|
$scope.currentFilter = filter,
|
|
$scope.filteredPanels = $scope.selectablePanels.filter(applyCurrentFilterByFilterCoulmn), angular.forEach($scope.categories, function(category) {
|
|
category.filter(applyCurrentFilterByFilterCoulmn)
|
|
})
|
|
}, $scope.hasFilter = function() {
|
|
return !!$scope.currentFilter
|
|
}, $scope.hasTests = function() {
|
|
return $scope.selectableTests && $scope.selectableTests.length > 0
|
|
}, $scope.isFilteredBy = function(filter) {
|
|
return $scope.currentFilter === filter
|
|
}, $scope.allSelectables = function() {
|
|
return $scope.selectablePanels.concat($scope.selectableTests)
|
|
}, $scope.selctedSelectables = function() {
|
|
return $scope.allSelectables().filter(function(selectable) {
|
|
return selectable.isSelectedFromSelf()
|
|
})
|
|
}
|
|
}]).directive("investigationsSelector", function() {
|
|
return {
|
|
restrict: "EA",
|
|
templateUrl: "consultation/views/investigationsSelector.html",
|
|
controller: "InvestigationsSelectorController",
|
|
require: "ngModel",
|
|
scope: {
|
|
investigations: "=ngModel",
|
|
testsProvider: "=",
|
|
filterColumn: "@",
|
|
filterHeader: "@",
|
|
categoryColumn: "@"
|
|
}
|
|
}
|
|
}), angular.module("bahmni.clinical").controller("ClinicalController", ["$scope", "retrospectiveEntryService", "$rootScope", "appService", function($scope, retrospectiveEntryService, $rootScope, appService) {
|
|
$scope.retrospectiveClass = function() {
|
|
return !_.isEmpty(retrospectiveEntryService.getRetrospectiveEntry())
|
|
}, $rootScope.toggleControlPanel = function() {
|
|
$rootScope.showControlPanel = !$rootScope.showControlPanel
|
|
}, $rootScope.collapseControlPanel = function() {
|
|
$rootScope.showControlPanel = !1
|
|
}, $rootScope.getLocaleCSS = function() {
|
|
var networkConnectivity, localeCSS = "offline-language-english";
|
|
appService.getAppDescriptor() && (networkConnectivity = appService.getAppDescriptor().getConfigValue("networkConnectivity"));
|
|
var locales = void 0 != networkConnectivity ? networkConnectivity.locales : null,
|
|
currentUser = $rootScope.currentUser;
|
|
return currentUser && currentUser.userProperties && locales && _.each(locales, function(localeObj) {
|
|
localeObj.locale == currentUser.userProperties.defaultLocale && (localeCSS = localeObj.css)
|
|
}), localeCSS
|
|
}
|
|
}]), angular.module("bahmni.clinical").controller("ConsultationSummaryController", ["$scope", "conceptSetUiConfigService", function($scope, conceptSetUiConfigService) {
|
|
var geEditedDiagnosesFromPastEncounters = function() {
|
|
var editedDiagnosesFromPastEncounters = [];
|
|
return $scope.consultation.pastDiagnoses.forEach(function(pastDiagnosis) {
|
|
pastDiagnosis.isDirty && pastDiagnosis.encounterUuid !== $scope.consultation.encounterUuid && editedDiagnosesFromPastEncounters.push(pastDiagnosis)
|
|
}), editedDiagnosesFromPastEncounters
|
|
};
|
|
$scope.editedDiagnosesFromPastEncounters = geEditedDiagnosesFromPastEncounters(), $scope.onNoteChanged = function() {
|
|
$scope.consultation.consultationNote.observationDateTime = null
|
|
};
|
|
var groupObservations = function() {
|
|
var allObservations = $scope.consultation.observations;
|
|
return allObservations = _.filter(allObservations, function(obs) {
|
|
return "Dispensed" !== obs.concept.name && (!$scope.followUpConditionConcept || obs.concept.uuid !== $scope.followUpConditionConcept.uuid)
|
|
}), new Bahmni.Clinical.ObsGroupingHelper(conceptSetUiConfigService).groupObservations(allObservations)
|
|
};
|
|
$scope.groupedObservations = groupObservations(), $scope.disposition = $scope.consultation.disposition, $scope.toggle = function(item) {
|
|
item.show = !item.show
|
|
}, $scope.isConsultationTabEmpty = function() {
|
|
return !!(_.isEmpty($scope.consultation.newlyAddedDiagnoses) && _.isEmpty($scope.groupedObservations) && _.isEmpty($scope.consultation.newlyAddedSpecimens) && _.isEmpty($scope.consultation.consultationNote.value) && _.isEmpty($scope.consultation.investigations) && _.isEmpty($scope.consultation.disposition) && _.isEmpty($scope.consultation.treatmentDrugs) && _.isEmpty($scope.consultation.newlyAddedTreatments) && _.isEmpty($scope.consultation.discontinuedDrugs) && _.isEmpty($scope.consultation.savedDiagnosesFromCurrentEncounter))
|
|
}
|
|
}]), angular.module("bahmni.clinical").controller("DiagnosisController", ["$scope", "$rootScope", "diagnosisService", "messagingService", "contextChangeHandler", "spinner", "appService", "$translate", "retrospectiveEntryService", function($scope, $rootScope, diagnosisService, messagingService, contextChangeHandler, spinner, appService, $translate, retrospectiveEntryService) {
|
|
var DateUtil = Bahmni.Common.Util.DateUtil;
|
|
$scope.todayWithoutTime = DateUtil.getDateWithoutTime(DateUtil.today()), $scope.toggles = {
|
|
expandInactive: !1
|
|
}, $scope.consultation.condition = $scope.consultation.condition || new Bahmni.Common.Domain.Condition({}), $scope.conditionsStatuses = {
|
|
CONDITION_LIST_ACTIVE: "ACTIVE",
|
|
CONDITION_LIST_INACTIVE: "INACTIVE",
|
|
CONDITION_LIST_HISTORY_OF: "HISTORY_OF"
|
|
}, $scope.consultation.followUpConditions = $scope.consultation.followUpConditions || [], _.forEach($scope.consultation.conditions, function(condition) {
|
|
condition.isFollowUp = _.some($scope.consultation.followUpConditions, {
|
|
value: condition.uuid
|
|
})
|
|
}), $scope.placeholder = "Add Diagnosis", $scope.hasAnswers = !1, $scope.orderOptions = {
|
|
CLINICAL_DIAGNOSIS_ORDER_PRIMARY: "PRIMARY",
|
|
CLINICAL_DIAGNOSIS_ORDER_SECONDARY: "SECONDARY"
|
|
}, $scope.certaintyOptions = {
|
|
CLINICAL_DIAGNOSIS_CERTAINTY_CONFIRMED: "CONFIRMED",
|
|
CLINICAL_DIAGNOSIS_CERTAINTY_PRESUMED: "PRESUMED"
|
|
}, $scope.getDiagnosis = function(params) {
|
|
return diagnosisService.getAllFor(params.term).then(mapConcept)
|
|
};
|
|
var _canAdd = function(diagnosis) {
|
|
var canAdd = !0;
|
|
return $scope.consultation.newlyAddedDiagnoses.forEach(function(observation) {
|
|
observation.codedAnswer.uuid === diagnosis.codedAnswer.uuid && (canAdd = !1)
|
|
}), diagnosis.codedAnswer.uuid && (diagnosis.order = "PRIMARY", diagnosis.certainty = "PRESUMED"), canAdd
|
|
};
|
|
$scope.getAddNewDiagnosisMethod = function(diagnosisAtIndex) {
|
|
return function(item) {
|
|
var concept = item.lookup,
|
|
index = $scope.consultation.newlyAddedDiagnoses.indexOf(diagnosisAtIndex),
|
|
diagnosisBeingEdited = $scope.consultation.newlyAddedDiagnoses[index],
|
|
diagnosis = new Bahmni.Common.Domain.Diagnosis(concept, diagnosisBeingEdited.order, diagnosisBeingEdited.certainty, diagnosisBeingEdited.existingObs);
|
|
_canAdd(diagnosis) && $scope.consultation.newlyAddedDiagnoses.splice(index, 1, diagnosis)
|
|
}
|
|
};
|
|
var addPlaceHolderDiagnosis = function() {
|
|
var diagnosis = new Bahmni.Common.Domain.Diagnosis("");
|
|
$scope.consultation.newlyAddedDiagnoses.push(diagnosis)
|
|
},
|
|
findPrivilege = function(privilegeName) {
|
|
return _.find($rootScope.currentUser.privileges, function(privilege) {
|
|
return privilegeName === privilege.name
|
|
})
|
|
},
|
|
init = function() {
|
|
$scope.canDeleteDiagnosis = findPrivilege(Bahmni.Common.Constants.deleteDiagnosisPrivilege), $scope.allowOnlyCodedDiagnosis = appService.getAppDescriptor().getConfig("allowOnlyCodedDiagnosis") && appService.getAppDescriptor().getConfig("allowOnlyCodedDiagnosis").value, $scope.hideConditions = appService.getAppDescriptor().getConfigValue("hideConditions"), addPlaceHolderDiagnosis(), diagnosisService.getDiagnosisConceptSet().then(function(result) {
|
|
$scope.diagnosisMetaData = result.data.results[0], $scope.isStatusConfigured = function() {
|
|
var memberFound = _.find($scope.diagnosisMetaData.setMembers, function(member) {
|
|
return "Bahmni Diagnosis Status" === member.name.name
|
|
});
|
|
return void 0 !== memberFound
|
|
}
|
|
})
|
|
};
|
|
$scope.checkInvalidDiagnoses = function() {
|
|
$scope.errorMessage = "", $scope.consultation.newlyAddedDiagnoses.forEach(function(diagnosis) {
|
|
isInvalidDiagnosis(diagnosis) && ($scope.errorMessage = "{{'CLINICAL_DUPLICATE_DIAGNOSIS_ERROR_MESSAGE' | translate }}")
|
|
})
|
|
};
|
|
var isInvalidDiagnosis = function(diagnosis) {
|
|
var codedAnswers = _.map(_.remove(_.map($scope.consultation.newlyAddedDiagnoses, "codedAnswer"), void 0), function(answer) {
|
|
return answer.name.toLowerCase()
|
|
}),
|
|
codedAnswersCount = _.countBy(codedAnswers);
|
|
return diagnosis.invalid = !!(diagnosis.codedAnswer.name && codedAnswersCount[diagnosis.codedAnswer.name.toLowerCase()] > 1), diagnosis.invalid
|
|
},
|
|
contextChange = function() {
|
|
var invalidnewlyAddedDiagnoses = $scope.consultation.newlyAddedDiagnoses.filter(function(diagnosis) {
|
|
return isInvalidDiagnosis(diagnosis) || !$scope.isValid(diagnosis)
|
|
}),
|
|
invalidSavedDiagnosesFromCurrentEncounter = $scope.consultation.savedDiagnosesFromCurrentEncounter.filter(function(diagnosis) {
|
|
return !$scope.isValid(diagnosis)
|
|
}),
|
|
invalidPastDiagnoses = $scope.consultation.pastDiagnoses.filter(function(diagnosis) {
|
|
return !$scope.isValid(diagnosis)
|
|
}),
|
|
isValidConditionForm = $scope.consultation.condition.isEmpty() || $scope.consultation.condition.isValid();
|
|
return {
|
|
allow: 0 === invalidnewlyAddedDiagnoses.length && 0 === invalidPastDiagnoses.length && 0 === invalidSavedDiagnosesFromCurrentEncounter.length && isValidConditionForm,
|
|
errorMessage: $scope.errorMessage
|
|
}
|
|
};
|
|
contextChangeHandler.add(contextChange);
|
|
var mapConcept = function(result) {
|
|
return _.map(result.data, function(concept) {
|
|
var response = {
|
|
value: concept.matchedName || concept.conceptName,
|
|
concept: {
|
|
name: concept.conceptName,
|
|
uuid: concept.conceptUuid
|
|
},
|
|
lookup: {
|
|
name: concept.matchedName || concept.conceptName,
|
|
uuid: concept.conceptUuid
|
|
}
|
|
};
|
|
return concept.matchedName && concept.matchedName !== concept.conceptName && (response.value = response.value + " => " + concept.conceptName), concept.code && (response.value = response.value + " (" + concept.code + ")"), response
|
|
})
|
|
};
|
|
$scope.getAddConditionMethod = function() {
|
|
return function(item) {
|
|
$scope.consultation.condition.concept.uuid = item.lookup.uuid, item.value = $scope.consultation.condition.concept.name = item.lookup.name
|
|
}
|
|
};
|
|
var findExistingCondition = function(newCondition) {
|
|
return _.find($scope.consultation.conditions, function(condition) {
|
|
return newCondition.conditionNonCoded ? condition.conditionNonCoded == newCondition.conditionNonCoded : condition.concept.uuid == newCondition.concept.uuid
|
|
})
|
|
};
|
|
$scope.filterConditions = function(status) {
|
|
return _.filter($scope.consultation.conditions, {
|
|
status: status
|
|
})
|
|
};
|
|
var expandInactiveOnNewInactive = function(condition) {
|
|
"INACTIVE" == condition.status && ($scope.toggles.expandInactive = !0)
|
|
},
|
|
updateOrAddCondition = function(condition) {
|
|
var existingCondition = findExistingCondition(condition);
|
|
return existingCondition ? existingCondition.uuid ? existingCondition.isActive() ? void messagingService.showMessage("error", "CONDITION_LIST_ALREADY_EXISTS_AS_ACTIVE") : existingCondition.activeSince && condition.onSetDate && !DateUtil.isBeforeDate(existingCondition.activeSince - 1, condition.onSetDate) ? void messagingService.showMessage("error", $translate.instant("CONDITION_LIST_ALREADY_EXISTS", {
|
|
lastActive: DateUtil.formatDateWithoutTime(existingCondition.activeSince),
|
|
status: existingCondition.status
|
|
})) : (existingCondition.status != condition.status && (existingCondition.onSetDate = condition.onSetDate || DateUtil.today(), existingCondition.status = condition.status), existingCondition.additionalDetail = condition.additionalDetail, existingCondition.isActive() && (existingCondition.activeSince = existingCondition.endDate), expandInactiveOnNewInactive(condition), void clearCondition()) : (_.pull($scope.consultation.conditions, existingCondition), $scope.consultation.conditions.push(condition), expandInactiveOnNewInactive(condition), void clearCondition()) : ($scope.consultation.conditions.push(condition), expandInactiveOnNewInactive(condition), void clearCondition())
|
|
};
|
|
$scope.addCondition = function(condition_) {
|
|
var condition = _.cloneDeep(condition_);
|
|
condition_.isNonCoded && (condition.conditionNonCoded = condition.concept.name, condition.concept = {}), condition.voided = !1, updateOrAddCondition(new Bahmni.Common.Domain.Condition(condition))
|
|
}, $scope.markAs = function(condition, status) {
|
|
condition.status = status, condition.onSetDate = DateUtil.today(), expandInactiveOnNewInactive(condition)
|
|
};
|
|
var clearCondition = function() {
|
|
$scope.consultation.condition = new Bahmni.Common.Domain.Condition, $scope.consultation.condition.showNotes = !1
|
|
};
|
|
$scope.addDiagnosisToConditions = function(diagnosis) {
|
|
updateOrAddCondition(Bahmni.Common.Domain.Condition.createFromDiagnosis(diagnosis))
|
|
}, $scope.cannotBeACondition = function(diagnosis) {
|
|
return "CONFIRMED" != diagnosis.certainty || alreadyHasActiveCondition(diagnosis)
|
|
}, $scope.addConditionAsFollowUp = function(condition) {
|
|
condition.isFollowUp = !0;
|
|
var followUpCondition = {
|
|
concept: {
|
|
uuid: $scope.followUpConditionConcept.uuid
|
|
},
|
|
value: condition.uuid,
|
|
voided: !1
|
|
};
|
|
$scope.consultation.followUpConditions.push(followUpCondition)
|
|
};
|
|
var alreadyHasActiveCondition = function(diagnosis) {
|
|
var existingCondition = findExistingCondition(Bahmni.Common.Domain.Condition.createFromDiagnosis(diagnosis));
|
|
return existingCondition && existingCondition.isActive()
|
|
};
|
|
$scope.cleanOutDiagnosisList = function(allDiagnoses) {
|
|
return allDiagnoses.filter(function(diagnosis) {
|
|
return !alreadyAddedToDiagnosis(diagnosis)
|
|
})
|
|
};
|
|
var alreadyAddedToDiagnosis = function(diagnosis) {
|
|
var isPresent = !1;
|
|
return $scope.consultation.newlyAddedDiagnoses.forEach(function(d) {
|
|
d.codedAnswer.uuid === diagnosis.concept.uuid && (isPresent = !0)
|
|
}), isPresent
|
|
};
|
|
$scope.removeObservation = function(index) {
|
|
index >= 0 && $scope.consultation.newlyAddedDiagnoses.splice(index, 1)
|
|
}, $scope.clearDiagnosis = function(index) {
|
|
var diagnosisBeingEdited = $scope.consultation.newlyAddedDiagnoses[index];
|
|
diagnosisBeingEdited.clearCodedAnswerUuid()
|
|
};
|
|
var reloadDiagnosesSection = function(encounterUuid) {
|
|
return diagnosisService.getPastAndCurrentDiagnoses($scope.patient.uuid, encounterUuid).then(function(response) {
|
|
$scope.consultation.pastDiagnoses = response.pastDiagnoses, $scope.consultation.savedDiagnosesFromCurrentEncounter = response.savedDiagnosesFromCurrentEncounter
|
|
})
|
|
};
|
|
$scope.deleteDiagnosis = function(diagnosis) {
|
|
var obsUUid = null !== diagnosis.existingObs ? diagnosis.existingObs : diagnosis.previousObs;
|
|
spinner.forPromise(diagnosisService.deleteDiagnosis(obsUUid).then(function() {
|
|
messagingService.showMessage("info", "Deleted");
|
|
var currentUuid = $scope.consultation.savedDiagnosesFromCurrentEncounter.length > 0 ? $scope.consultation.savedDiagnosesFromCurrentEncounter[0].encounterUuid : "";
|
|
return reloadDiagnosesSection(currentUuid)
|
|
})).then(function() {})
|
|
};
|
|
var clearBlankDiagnosis = !0,
|
|
removeBlankDiagnosis = function() {
|
|
clearBlankDiagnosis && ($scope.consultation.newlyAddedDiagnoses = $scope.consultation.newlyAddedDiagnoses.filter(function(diagnosis) {
|
|
return !diagnosis.isEmpty()
|
|
}), clearBlankDiagnosis = !1)
|
|
};
|
|
$scope.consultation.preSaveHandler.register("diagnosisSaveHandlerKey", removeBlankDiagnosis), $scope.$on("$destroy", removeBlankDiagnosis), $scope.processDiagnoses = function(data) {
|
|
data.map(function(concept) {
|
|
return concept.conceptName === concept.matchedName ? {
|
|
value: concept.matchedName,
|
|
concept: concept
|
|
} : {
|
|
value: concept.matchedName + "=>" + concept.conceptName,
|
|
concept: concept
|
|
}
|
|
})
|
|
}, $scope.restEmptyRowsToOne = function(index) {
|
|
var iter;
|
|
for (iter = 0; iter < $scope.consultation.newlyAddedDiagnoses.length; iter++) $scope.consultation.newlyAddedDiagnoses[iter].isEmpty() && iter !== index && $scope.consultation.newlyAddedDiagnoses.splice(iter, 1);
|
|
var emptyRows = $scope.consultation.newlyAddedDiagnoses.filter(function(diagnosis) {
|
|
return diagnosis.isEmpty()
|
|
});
|
|
0 === emptyRows.length && addPlaceHolderDiagnosis(), clearBlankDiagnosis = !0
|
|
}, $scope.toggle = function(item) {
|
|
item.show = !item.show
|
|
}, $scope.isValid = function(diagnosis) {
|
|
return diagnosis.isValidAnswer() && diagnosis.isValidOrder() && diagnosis.isValidCertainty()
|
|
}, $scope.isRetrospectiveMode = retrospectiveEntryService.isRetrospectiveMode, init()
|
|
}]), angular.module("bahmni.clinical").controller("InvestigationController", ["$scope", "labTestsProvider", "otherTestsProvider", function($scope, labTestsProvider, otherTestsProvider) {
|
|
$scope.tabs = [{
|
|
name: "Laboratory",
|
|
testsProvider: labTestsProvider,
|
|
filterColumn: "sample",
|
|
filterHeader: "Sample",
|
|
categoryColumn: "department"
|
|
}, {
|
|
name: "Other",
|
|
testsProvider: otherTestsProvider,
|
|
filterColumn: "type",
|
|
filterHeader: "Investigation",
|
|
categoryColumn: "category"
|
|
}], $scope.activateTab = function(tab) {
|
|
$scope.activeTab && ($scope.activeTab.klass = ""), $scope.activeTab = tab, $scope.activeTab.klass = "active"
|
|
};
|
|
var findVoidedInvestigations = function() {
|
|
var filteredInvestigation = $scope.consultation.investigations.filter(function(investigation) {
|
|
return investigation.voided
|
|
});
|
|
return filteredInvestigation.length === $scope.consultation.investigations.length
|
|
};
|
|
$scope.isValidInvestigation = function() {
|
|
return !$scope.consultation.investigations.length > 0 || findVoidedInvestigations() ? ($scope.noteState = !1, $scope.consultation.labOrderNote.uuid ? $scope.consultation.labOrderNote.voided = !0 : $scope.consultation.labOrderNote.value && ($scope.consultation.labOrderNote.value = null), !1) : ($scope.consultation.labOrderNote.uuid && ($scope.noteState = !0, $scope.consultation.labOrderNote.voided = !1), !0)
|
|
}, $scope.activateTab($scope.tabs[0]), $scope.toggleNote = function() {
|
|
$scope.noteState = !$scope.noteState
|
|
};
|
|
var init = function() {
|
|
$scope.noteState = !(!$scope.consultation.labOrderNote || !$scope.consultation.labOrderNote.value)
|
|
};
|
|
$scope.onNoteChanged = function() {
|
|
$scope.consultation.labOrderNote && ($scope.consultation.labOrderNote.observationDateTime = null)
|
|
}, init()
|
|
}]), angular.module("bahmni.clinical").controller("OrderController", ["$scope", "allOrderables", "ngDialog", "retrospectiveEntryService", "appService", "$translate", function($scope, allOrderables, ngDialog, retrospectiveEntryService, appService, $translate) {
|
|
$scope.consultation.orders = $scope.consultation.orders || [], $scope.consultation.childOrders = $scope.consultation.childOrders || [], $scope.allOrdersTemplates = allOrderables;
|
|
var RadiologyOrderOptionsConfig = appService.getAppDescriptor().getConfig("enableRadiologyOrderOptions"),
|
|
LabOrderOptionsConfig = appService.getAppDescriptor().getConfig("enableLabOrderOptions");
|
|
$scope.enableRadiologyOrderOptions = RadiologyOrderOptionsConfig ? RadiologyOrderOptionsConfig.value : null, $scope.enableLabOrderOptions = LabOrderOptionsConfig ? LabOrderOptionsConfig.value : null;
|
|
var testConceptToParentsMapping = {},
|
|
collapseExistingActiveSection = function(section) {
|
|
section && (section.klass = "")
|
|
},
|
|
showFirstLeftCategoryByDefault = function() {
|
|
if (!$scope.activeTab.leftCategory) {
|
|
var allLeftCategories = $scope.getOrderTemplate($scope.activeTab.name).setMembers;
|
|
allLeftCategories.length > 0 && $scope.showLeftCategoryTests(allLeftCategories[0])
|
|
}
|
|
},
|
|
findTest = function(testUuid) {
|
|
var test, allLeftCategories = $scope.getOrderTemplate($scope.activeTab.name).setMembers;
|
|
return _.each(allLeftCategories, function(leftCategory) {
|
|
var foundTest = _.find(leftCategory.setMembers, function(test) {
|
|
return test.uuid === testUuid
|
|
});
|
|
if (foundTest) return void(test = foundTest)
|
|
}), test
|
|
},
|
|
removeOrder = function(testUuid) {
|
|
var order = _.find($scope.consultation.orders, function(order) {
|
|
return order.concept.uuid === testUuid
|
|
});
|
|
order && (order.uuid ? order.isDiscontinued = !0 : _.remove($scope.consultation.orders, order))
|
|
},
|
|
createOrder = function(test) {
|
|
var discontinuedOrder = _.find($scope.consultation.orders, function(order) {
|
|
return test.uuid === order.concept.uuid && order.isDiscontinued
|
|
});
|
|
if (discontinuedOrder) discontinuedOrder.isDiscontinued = !1;
|
|
else {
|
|
var createdOrder = Bahmni.Clinical.Order.create(test);
|
|
$scope.consultation.orders.push(createdOrder)
|
|
}
|
|
},
|
|
initTestConceptToParentsMapping = function() {
|
|
var allLeftCategories = $scope.getOrderTemplate($scope.activeTab.name).setMembers;
|
|
_.each(allLeftCategories, function(leftCategory) {
|
|
_.each(leftCategory.setMembers, function(member) {
|
|
0 !== member.setMembers.length && _.each(member.setMembers, function(child) {
|
|
void 0 === testConceptToParentsMapping[child.uuid] && (testConceptToParentsMapping[child.uuid] = []), testConceptToParentsMapping[child.uuid].push(member.uuid)
|
|
})
|
|
})
|
|
})
|
|
},
|
|
init = function() {
|
|
$scope.tabs = [], _.forEach($scope.allOrdersTemplates, function(item) {
|
|
var conceptName = $scope.getName(item);
|
|
$scope.tabs.push({
|
|
name: conceptName ? conceptName : item.name.name,
|
|
topLevelConcept: item.name.name
|
|
})
|
|
})
|
|
};
|
|
$scope.isRetrospectiveMode = function() {
|
|
return !_.isEmpty(retrospectiveEntryService.getRetrospectiveEntry())
|
|
}, $scope.activateTab = function(tab) {
|
|
"active" === tab.klass ? (tab.klass = "", $scope.activeTab = void 0) : (collapseExistingActiveSection($scope.activeTab), $scope.activeTab = tab, $scope.activeTab.klass = "active", $scope.updateSelectedOrdersForActiveTab(), initTestConceptToParentsMapping(), showFirstLeftCategoryByDefault())
|
|
}, $scope.updateSelectedOrdersForActiveTab = function() {
|
|
if ($scope.activeTab) {
|
|
var activeTabTestConcepts = _.map(_.flatten(_.map($scope.getOrderTemplate($scope.activeTab.name).setMembers, "setMembers")), "uuid");
|
|
$scope.selectedOrders = _.filter($scope.consultation.orders, function(testOrder) {
|
|
return _.indexOf(activeTabTestConcepts, testOrder.concept.uuid) !== -1
|
|
}), _.each($scope.selectedOrders, function(order) {
|
|
order.isUrgent = "STAT" == order.urgency || order.isUrgent
|
|
})
|
|
}
|
|
}, $scope.getOrderTemplate = function(templateName) {
|
|
var key = "'" + templateName + "'";
|
|
return $scope.allOrdersTemplates[key]
|
|
}, $scope.showLeftCategoryTests = function(leftCategory) {
|
|
collapseExistingActiveSection($scope.activeTab.leftCategory), $scope.activeTab.leftCategory = leftCategory, $scope.activeTab.leftCategory.klass = "active", $scope.activeTab.leftCategory.groups = $scope.getConceptClassesInSet(leftCategory)
|
|
}, $scope.getConceptClassesInSet = function(conceptSet) {
|
|
var conceptsWithUniqueClass = _.uniqBy(conceptSet ? conceptSet.setMembers : [], function(concept) {
|
|
return concept.conceptClass.uuid
|
|
}),
|
|
conceptClasses = [];
|
|
return _.forEach(conceptsWithUniqueClass, function(concept) {
|
|
conceptClasses.push({
|
|
name: concept.conceptClass.name,
|
|
description: concept.conceptClass.description
|
|
})
|
|
}), conceptClasses = _.sortBy(conceptClasses, "name")
|
|
}, $scope.$watchCollection("consultation.orders", $scope.updateSelectedOrdersForActiveTab), $scope.handleOrderClick = function(order) {
|
|
var test = findTest(order.concept.uuid);
|
|
$scope.toggleOrderSelection(test)
|
|
}, $scope.search = {}, $scope.search.string = "", $scope.resetSearchString = function() {
|
|
$scope.search.string = ""
|
|
}, $scope.toggleOrderSelection = function(test) {
|
|
$scope.resetSearchString();
|
|
var orderPresent = $scope.isActiveOrderPresent(test);
|
|
orderPresent ? removeOrder(test.uuid) : (createOrder(test), _.each(test.setMembers, function(child) {
|
|
removeOrder(child.uuid)
|
|
}))
|
|
}, $scope.isActiveOrderPresent = function(test) {
|
|
var validOrders = _.filter($scope.consultation.orders, function(testOrder) {
|
|
return !testOrder.isDiscontinued
|
|
});
|
|
return _.find(validOrders, function(order) {
|
|
return order.concept.uuid === test.uuid || _.includes(testConceptToParentsMapping[test.uuid], order.concept.uuid)
|
|
})
|
|
}, $scope.isOrderNotEditable = function(order) {
|
|
var test = findTest(order.concept.uuid);
|
|
return $scope.isTestIndirectlyPresent(test)
|
|
}, $scope.isTestIndirectlyPresent = function(test) {
|
|
var validOrders = _.filter($scope.consultation.orders, function(testOrder) {
|
|
return !testOrder.isDiscontinued
|
|
});
|
|
return _.find(validOrders, function(order) {
|
|
return _.includes(testConceptToParentsMapping[test.uuid], order.concept.uuid)
|
|
})
|
|
}, $scope.openNotesPopup = function(order) {
|
|
order.previousNote = order.commentToFulfiller, $scope.orderNoteText = order.previousNote, $scope.dialog = ngDialog.open({
|
|
template: "consultation/views/orderNotes.html",
|
|
className: "selectedOrderNoteContainer-dialog ngdialog-theme-default",
|
|
data: order,
|
|
scope: $scope
|
|
})
|
|
}, $scope.$on("ngDialog.opened", function() {
|
|
$("body").addClass("show-controller-back")
|
|
}), $scope.$on("ngDialog.closed", function() {
|
|
$("body").removeClass("show-controller-back")
|
|
}), $scope.appendPrintNotes = function(order) {
|
|
var printNotes = $translate.instant("CLINICAL_ORDER_RADIOLOGY_NEED_PRINT");
|
|
order.previousNote && order.previousNote.indexOf(printNotes) == -1 ? $scope.orderNoteText = printNotes + (order.previousNote || "") : ($scope.orderNoteText || "").indexOf(printNotes) == -1 && ($scope.orderNoteText = $translate.instant(printNotes) + ($scope.orderNoteText || ""))
|
|
}, $scope.isPrintShown = function(isOrderSaved) {
|
|
var configuredOptions = getConfiguredOptions();
|
|
return _.some(configuredOptions, function(option) {
|
|
return "needsprint" === option.toLowerCase()
|
|
}) && !isOrderSaved
|
|
}, $scope.isUrgent = function() {
|
|
var configuredOptions = getConfiguredOptions();
|
|
return _.some(configuredOptions, function(option) {
|
|
return "urgent" === option.toLowerCase()
|
|
})
|
|
};
|
|
var getConfiguredOptions = function() {
|
|
var configuredOptions = null;
|
|
return configuredOptions = "Radiology" == $scope.activeTab.name ? $scope.enableRadiologyOrderOptions : $scope.enableLabOrderOptions
|
|
};
|
|
$scope.setEditedFlag = function(order, orderNoteText) {
|
|
order.previousNote !== orderNoteText && (order.commentToFulfiller = orderNoteText, order.hasBeenModified = !0), $scope.closePopup()
|
|
}, $scope.closePopup = function() {
|
|
ngDialog.close()
|
|
}, $scope.getName = function(sample) {
|
|
var name = _.find(sample.names, {
|
|
conceptNameType: "SHORT"
|
|
}) || _.find(sample.names, {
|
|
conceptNameType: "FULLY_SPECIFIED"
|
|
});
|
|
return name && name.name
|
|
}, init()
|
|
}]), angular.module("bahmni.clinical").controller("TreatmentController", ["$scope", "clinicalAppConfigService", "treatmentConfig", "$stateParams", function($scope, clinicalAppConfigService, treatmentConfig, $stateParams) {
|
|
var init = function() {
|
|
var drugOrderHistoryConfig = treatmentConfig.drugOrderHistoryConfig || {};
|
|
$scope.drugOrderHistoryView = drugOrderHistoryConfig.view || "default", $scope.tabConfigName = $stateParams.tabConfigName || "default";
|
|
var initializeTreatments = function() {
|
|
$scope.consultation.newlyAddedTabTreatments = $scope.consultation.newlyAddedTabTreatments || {}, $scope.consultation.newlyAddedTabTreatments[$scope.tabConfigName] = $scope.consultation.newlyAddedTabTreatments[$scope.tabConfigName] || {
|
|
treatments: [],
|
|
orderSetTreatments: [],
|
|
newOrderSet: {}
|
|
}, $scope.treatments = $scope.consultation.newlyAddedTabTreatments[$scope.tabConfigName].treatments, $scope.orderSetTreatments = $scope.consultation.newlyAddedTabTreatments[$scope.tabConfigName].orderSetTreatments, $scope.newOrderSet = $scope.consultation.newlyAddedTabTreatments[$scope.tabConfigName].newOrderSet
|
|
};
|
|
$scope.$watch("consultation.newlyAddedTabTreatments", initializeTreatments), $scope.enrollment = $stateParams.enrollment, $scope.treatmentConfig = treatmentConfig
|
|
};
|
|
init()
|
|
}]), angular.module("bahmni.clinical").controller("AddTreatmentController", ["$scope", "$rootScope", "contextChangeHandler", "treatmentConfig", "drugService", "$timeout", "clinicalAppConfigService", "ngDialog", "$window", "messagingService", "appService", "activeDrugOrders", "orderSetService", "$q", "locationService", "spinner", "$translate", "$http", "$location", function($scope, $rootScope, contextChangeHandler, treatmentConfig, drugService, $timeout, clinicalAppConfigService, ngDialog, $window, messagingService, appService, activeDrugOrders, orderSetService, $q, locationService, spinner, $translate, $http, $location) {
|
|
var DateUtil = Bahmni.Common.Util.DateUtil,
|
|
DrugOrderViewModel = Bahmni.Clinical.DrugOrderViewModel,
|
|
scrollTop = _.partial($window.scrollTo, 0, 0);
|
|
$scope.showOrderSetDetails = !0, $scope.addTreatment = !0, $scope.canOrderSetBeAdded = !0, $scope.isSearchDisabled = !1, $scope.getFilteredOrderSets = function(searchTerm) {
|
|
searchTerm && searchTerm.length >= 3 ? orderSetService.getOrderSetsByQuery(searchTerm).then(function(response) {
|
|
$scope.orderSets = response.data.results, _.each($scope.orderSets, function(orderSet) {
|
|
_.each(orderSet.orderSetMembers, setUpOrderSetTransactionalData)
|
|
})
|
|
}) : $scope.orderSets = {}
|
|
}, $scope.treatmentActionLinks = clinicalAppConfigService.getTreatmentActionLink();
|
|
var preFetchDrugsForGivenConceptSet = function() {
|
|
drugService.getSetMembersOfConcept(treatmentConfig.getDrugConceptSet()).then(function(result) {
|
|
$scope.drugs = result.map(Bahmni.Clinical.DrugSearchResult.create)
|
|
})
|
|
};
|
|
treatmentConfig.isDropDownForGivenConceptSet() && preFetchDrugsForGivenConceptSet(), treatmentConfig.isAutoCompleteForAllConcepts() && ($scope.getDrugs = function(request) {
|
|
return drugService.search(request.term)
|
|
}), treatmentConfig.isAutoCompleteForGivenConceptSet() && ($scope.getDrugs = function(request) {
|
|
return drugService.getSetMembersOfConcept(treatmentConfig.getDrugConceptSet(), request.term)
|
|
}), $scope.doseFractions = treatmentConfig.getDoseFractions(), $scope.hideOrderSet = treatmentConfig.inputOptionsConfig.hideOrderSet, $scope.showDoseFractions = treatmentConfig.inputOptionsConfig.showDoseFractions, $scope.isDoseFractionsAvailable = function() {
|
|
return $scope.doseFractions && !_.isEmpty($scope.doseFractions)
|
|
}, $scope.isSelected = function(drug) {
|
|
var selectedDrug = $scope.treatment.drug;
|
|
return selectedDrug && drug.drug.name === selectedDrug.name
|
|
}, $scope.selectFromDefaultDrugList = function() {
|
|
$scope.onSelect($scope.treatment.selectedItem)
|
|
};
|
|
var markVariable = function(variable) {
|
|
$scope[variable] = !0, $timeout(function() {
|
|
$scope[variable] = !1
|
|
})
|
|
},
|
|
markEitherVariableDrugOrUniformDrug = function(drug) {
|
|
markVariable(drug.isVariableDosingType() ? "editDrugEntryVariableFrequency" : "editDrugEntryUniformFrequency")
|
|
};
|
|
markVariable("startNewDrugEntry");
|
|
var setDrugOrderBeingEdited, clearHighlights;
|
|
! function() {
|
|
var drugOrderBeingEdited = null;
|
|
setDrugOrderBeingEdited = function(drugOder) {
|
|
drugOrderBeingEdited = drugOder
|
|
}, clearHighlights = function() {
|
|
$scope.treatments.forEach(setIsNotBeingEdited), $scope.orderSetTreatments.forEach(setIsNotBeingEdited), drugOrderBeingEdited && (drugOrderBeingEdited.isBeingEdited = !1, drugOrderBeingEdited.isDiscontinuedAllowed = !0)
|
|
}
|
|
}();
|
|
var encounterDate = DateUtil.parse($scope.consultation.encounterDateTime),
|
|
newTreatment = function() {
|
|
var newTreatment = new Bahmni.Clinical.DrugOrderViewModel(treatmentConfig, null, encounterDate);
|
|
return newTreatment.isEditAllowed = !1, newTreatment
|
|
};
|
|
$scope.treatment = newTreatment(), treatmentConfig.durationUnits.forEach(function(durationUnit) {
|
|
_.isEqual(durationUnit, $scope.treatment.durationUnit) && ($scope.treatment.durationUnit = durationUnit)
|
|
});
|
|
var watchFunctionForQuantity = function() {
|
|
var treatment = $scope.treatment;
|
|
return {
|
|
uniformDosingType: treatment.uniformDosingType,
|
|
variableDosingType: treatment.variableDosingType,
|
|
"continue": treatment["continue"],
|
|
doseUnits: treatment.doseUnits,
|
|
duration: treatment.duration,
|
|
durationUnit: treatment.durationUnit
|
|
}
|
|
},
|
|
isSameDrugBeingDiscontinuedAndOrdered = function() {
|
|
var existingTreatment = !1;
|
|
return angular.forEach($scope.consultation.discontinuedDrugs, function(drugOrder) {
|
|
existingTreatment = _.some($scope.treatments, function(treatment) {
|
|
return treatment.getDisplayName() === drugOrder.getDisplayName()
|
|
}) && drugOrder.isMarkedForDiscontinue
|
|
}), existingTreatment
|
|
},
|
|
clearOtherDrugOrderActions = function(drugOrders) {
|
|
drugOrders.forEach(function(drugOrder) {
|
|
drugOrder.isDiscontinuedAllowed = !0, drugOrder.isBeingEdited = !1
|
|
})
|
|
},
|
|
setNonCodedDrugConcept = function(treatment) {
|
|
treatment.drugNonCoded && (treatment.concept = treatmentConfig.nonCodedDrugconcept)
|
|
};
|
|
$scope.refillDrug = function(drugOrder, alreadyActiveSimilarOrder) {
|
|
$scope.bulkSelectCheckbox = !1;
|
|
var existingOrderStopDate = alreadyActiveSimilarOrder ? alreadyActiveSimilarOrder.effectiveStopDate : null,
|
|
refillDrugOrder = drugOrder.refill(existingOrderStopDate);
|
|
setNonCodedDrugConcept(refillDrugOrder), setDrugOrderBeingEdited(drugOrder), $scope.treatments.push(refillDrugOrder), markVariable("startNewDrugEntry"), ngDialog.close()
|
|
}, $scope.refillOrderSet = function(drugOrder) {
|
|
ngDialog.close();
|
|
var drugOrdersOfOrderGroup = _.filter($scope.consultation.activeAndScheduledDrugOrders, function(treatment) {
|
|
return treatment.orderGroupUuid === drugOrder.orderGroupUuid
|
|
}),
|
|
refilledOrderGroupOrders = [];
|
|
drugOrdersOfOrderGroup.forEach(function(drugOrder) {
|
|
setNonCodedDrugConcept(drugOrder), drugOrder.effectiveStopDate && refilledOrderGroupOrders.push(drugOrder.refill())
|
|
}), setSortWeightForOrderSetDrugs(refilledOrderGroupOrders);
|
|
var matchedOrderSet = _.find(orderSets, {
|
|
uuid: drugOrder.orderSetUuid
|
|
}),
|
|
orderSetMembersOfMatchedOrderSet = matchedOrderSet.orderSetMembers,
|
|
matchedMembers = [];
|
|
_.each(refilledOrderGroupOrders, function(drugOrder) {
|
|
_.each(orderSetMembersOfMatchedOrderSet, function(orderSetMember) {
|
|
orderSetMember.orderTemplate.drug ? orderSetMember.orderTemplate.drug.uuid === _.get(drugOrder, "drug.uuid") && matchedMembers.push(orderSetMember) : orderSetMember.concept.uuid === drugOrder.concept.uuid && matchedMembers.push(orderSetMember)
|
|
})
|
|
});
|
|
var listOfPromises = _.map(matchedMembers, function(eachMember, index) {
|
|
if (eachMember.orderTemplate) {
|
|
var doseUnits = eachMember.orderTemplate.dosingInstructions.doseUnits,
|
|
baseDose = eachMember.orderTemplate.dosingInstructions.dose,
|
|
drugName = eachMember.orderTemplate.concept.name;
|
|
return orderSetService.getCalculatedDose($scope.patient.uuid, drugName, baseDose, doseUnits, $scope.newOrderSet.name).then(function(calculatedDosage) {
|
|
refilledOrderGroupOrders[index].uniformDosingType.dose = calculatedDosage.dose, refilledOrderGroupOrders[index].uniformDosingType.doseUnits = calculatedDosage.doseUnit, refilledOrderGroupOrders[index].calculateQuantityAndUnit()
|
|
})
|
|
}
|
|
});
|
|
spinner.forPromise($q.all(listOfPromises).then(function() {
|
|
Array.prototype.push.apply($scope.treatments, refilledOrderGroupOrders)
|
|
}))
|
|
}, $scope.$on("event:refillDrugOrder", function(event, drugOrder, alreadyActiveSimilarOrder) {
|
|
$scope.refillDrug(drugOrder, alreadyActiveSimilarOrder)
|
|
});
|
|
var refillDrugOrders = function(drugOrders) {
|
|
drugOrders.forEach(function(drugOrder) {
|
|
if (setNonCodedDrugConcept(drugOrder), drugOrder.effectiveStopDate) {
|
|
var refill = drugOrder.refill();
|
|
$scope.treatments.push(refill)
|
|
}
|
|
})
|
|
};
|
|
$scope.$on("event:sectionUpdated", function(event, drugOrder) {
|
|
_.remove($scope.consultation.activeAndScheduledDrugOrders, function(activeOrder) {
|
|
return activeOrder.uuid === drugOrder.uuid
|
|
})
|
|
}), $scope.$on("event:refillDrugOrders", function(event, drugOrders) {
|
|
$scope.bulkSelectCheckbox = !1, refillDrugOrders(drugOrders);
|
|
}), $scope.$on("event:discontinueDrugOrder", function(event, drugOrder) {
|
|
drugOrder.isMarkedForDiscontinue = !0, drugOrder.isEditAllowed = !1, drugOrder.dateStopped = DateUtil.now(), $scope.consultation.discontinuedDrugs.push(drugOrder), $scope.minDateStopped = DateUtil.getDateWithoutTime(drugOrder.effectiveStartDate < DateUtil.now() ? drugOrder.effectiveStartDate : DateUtil.now())
|
|
}), $scope.$on("event:undoDiscontinueDrugOrder", function(event, drugOrder) {
|
|
$scope.consultation.discontinuedDrugs = _.reject($scope.consultation.discontinuedDrugs, function(removableOrder) {
|
|
return removableOrder.uuid === drugOrder.uuid
|
|
}), $scope.consultation.removableDrugs = _.reject($scope.consultation.removableDrugs, function(removableOrder) {
|
|
return removableOrder.previousOrderUuid === drugOrder.uuid
|
|
}), drugOrder.orderReasonConcept = null, drugOrder.dateStopped = null, drugOrder.orderReasonText = null, drugOrder.isMarkedForDiscontinue = !1, drugOrder.isEditAllowed = !0
|
|
});
|
|
var selectDrugFromDropdown = function(drug_) {
|
|
treatmentConfig.isDropDownForGivenConceptSet() && ($scope.treatment.selectedItem = _.find($scope.drugs, function(drug) {
|
|
return drug.drug.uuid === drug_.uuid
|
|
}))
|
|
};
|
|
$scope.$on("event:reviseDrugOrder", function(event, drugOrder, drugOrders) {
|
|
clearOtherDrugOrderActions(drugOrders), drugOrder.isBeingEdited = !0, drugOrder.isDiscontinuedAllowed = !1, $scope.treatments.forEach(setIsNotBeingEdited), setDrugOrderBeingEdited(drugOrder), $scope.treatment = drugOrder.revise(), selectDrugFromDropdown(drugOrder.drug), markEitherVariableDrugOrUniformDrug($scope.treatment), $scope.treatment.currentIndex = $scope.treatments.length + 1, $scope.treatment.frequencyType === Bahmni.Clinical.Constants.dosingTypes.variable && ($scope.treatment.isUniformFrequency = !1), $scope.treatment.quantity = $scope.treatment.quantity ? $scope.treatment.quantity : null
|
|
}), $scope.$watch(watchFunctionForQuantity, function() {
|
|
$scope.treatment.calculateQuantityAndUnit()
|
|
}, !0), $scope.add = function() {
|
|
var treatments = $scope.treatments;
|
|
$scope.treatment.isNewOrderSet && (treatments = $scope.orderSetTreatments), $scope.treatment.dosingInstructionType = Bahmni.Clinical.Constants.flexibleDosingInstructionsClass, $scope.treatment.isNonCodedDrug && ($scope.treatment.drugNonCoded = $scope.treatment.drugNameDisplay), $scope.treatment.setUniformDoseFraction();
|
|
var newDrugOrder = $scope.treatment;
|
|
return setNonCodedDrugConcept($scope.treatment), newDrugOrder.calculateEffectiveStopDate(), getConflictingDrugOrder(newDrugOrder) ? ($scope.alreadyActiveSimilarOrder.isNewOrderSet ? $scope.conflictingIndex = _.findIndex($scope.orderSetTreatments, $scope.alreadyActiveSimilarOrder) : $scope.conflictingIndex = _.findIndex($scope.treatments, $scope.alreadyActiveSimilarOrder), ngDialog.open({
|
|
template: "consultation/views/treatmentSections/conflictingDrugOrderModal.html",
|
|
scope: $scope
|
|
}), void($scope.popupActive = !0)) : ($scope.treatment.quantity || ($scope.treatment.quantity = 0), $scope.treatment.isBeingEdited ? (treatments.splice($scope.treatment.currentIndex, 1, $scope.treatment), $scope.treatment.isBeingEdited = !1) : treatments.push($scope.treatment), void $scope.clearForm())
|
|
};
|
|
var getConflictingDrugOrder = function(newDrugOrder) {
|
|
var allDrugOrders = $scope.treatments.concat($scope.orderSetTreatments);
|
|
allDrugOrders = _.reject(allDrugOrders, newDrugOrder);
|
|
var existingDrugOrders, unsavedNotBeingEditedOrders = _.filter(allDrugOrders, {
|
|
isBeingEdited: !1
|
|
});
|
|
existingDrugOrders = newDrugOrder.isBeingEdited ? _.reject($scope.consultation.activeAndScheduledDrugOrders, {
|
|
uuid: newDrugOrder.previousOrderUuid
|
|
}) : $scope.consultation.activeAndScheduledDrugOrders, existingDrugOrders = existingDrugOrders.concat(unsavedNotBeingEditedOrders);
|
|
var potentiallyOverlappingOrders = existingDrugOrders.filter(function(drugOrder) {
|
|
return drugOrder.getDisplayName() === newDrugOrder.getDisplayName() && drugOrder.overlappingScheduledWith(newDrugOrder)
|
|
});
|
|
setEffectiveDates(newDrugOrder, potentiallyOverlappingOrders);
|
|
var alreadyActiveSimilarOrders = existingDrugOrders.filter(function(drugOrder) {
|
|
return drugOrder.getDisplayName() === newDrugOrder.getDisplayName() && drugOrder.overlappingScheduledWith(newDrugOrder)
|
|
});
|
|
return alreadyActiveSimilarOrders.length > 0 && ($scope.alreadyActiveSimilarOrder = _.sortBy(potentiallyOverlappingOrders, "effectiveStartDate").reverse()[0], $scope.alreadyActiveSimilarOrder)
|
|
},
|
|
isEffectiveStartDateSameAsToday = function(newDrugOrder) {
|
|
return DateUtil.isSameDate(newDrugOrder.effectiveStartDate, DateUtil.parse(newDrugOrder.encounterDate)) && DateUtil.isSameDate(newDrugOrder.effectiveStartDate, DateUtil.now())
|
|
},
|
|
setEffectiveDates = function(newDrugOrder, existingDrugOrders) {
|
|
newDrugOrder.scheduledDate = newDrugOrder.effectiveStartDate, existingDrugOrders.forEach(function(existingDrugOrder) {
|
|
DateUtil.isSameDate(existingDrugOrder.effectiveStartDate, newDrugOrder.effectiveStopDate) && !DateUtil.isSameDate(existingDrugOrder.effectiveStopDate, newDrugOrder.effectiveStartDate) && (newDrugOrder.previousOrderUuid && newDrugOrder.previousOrderDurationInDays !== newDrugOrder.durationInDays || (newDrugOrder.effectiveStopDate = DateUtil.subtractSeconds(existingDrugOrder.effectiveStartDate, 1)), (newDrugOrder.previousOrderUuid || DateUtil.isSameDate(newDrugOrder.effectiveStartDate, newDrugOrder.encounterDate)) && (newDrugOrder.autoExpireDate = newDrugOrder.effectiveStopDate)), DateUtil.isSameDate(existingDrugOrder.effectiveStopDate, newDrugOrder.effectiveStartDate) && DateUtil.isSameDate(DateUtil.addSeconds(existingDrugOrder.effectiveStopDate, 1), newDrugOrder.effectiveStartDate) && (existingDrugOrder.uuid || (existingDrugOrder.effectiveStopDate = DateUtil.subtractSeconds(existingDrugOrder.effectiveStopDate, 1)), newDrugOrder.effectiveStartDate = DateUtil.addSeconds(existingDrugOrder.effectiveStopDate, 1))
|
|
}), isEffectiveStartDateSameAsToday(newDrugOrder) && (newDrugOrder.scheduledDate = null)
|
|
};
|
|
$scope.closeDialog = function() {
|
|
ngDialog.close()
|
|
}, $scope.refillConflictingDrug = function(drugOrder, alreadyActiveSimilarOrder) {
|
|
$scope.popupActive = !1, ngDialog.close(), $scope.clearForm(), $scope.$broadcast("event:refillDrugOrder", drugOrder, alreadyActiveSimilarOrder)
|
|
}, $scope.revise = function(drugOrder, index) {
|
|
$scope.popupActive = !1, ngDialog.close(), drugOrder.uuid ? $scope.$broadcast("event:reviseDrugOrder", drugOrder, $scope.consultation.activeAndScheduledDrugOrders) : edit(drugOrder, index)
|
|
}, $scope.toggleShowAdditionalInstructions = function(treatment) {
|
|
treatment.showAdditionalInstructions = !treatment.showAdditionalInstructions
|
|
}, $scope.toggleAsNeeded = function(treatment) {
|
|
treatment.asNeeded = !treatment.asNeeded
|
|
};
|
|
var edit = function(drugOrder, index) {
|
|
clearHighlights();
|
|
var treatment = drugOrder;
|
|
markEitherVariableDrugOrUniformDrug(treatment), treatment.isBeingEdited = !0, $scope.treatment = treatment.cloneForEdit(index, treatmentConfig), 0 === $scope.treatment.quantity && ($scope.treatment.quantity = null, $scope.treatment.quantityEnteredManually = !1), selectDrugFromDropdown(treatment.drug)
|
|
};
|
|
$scope.$on("event:editDrugOrder", function(event, drugOrder, index) {
|
|
edit(drugOrder, index)
|
|
}), $scope.$on("event:removeDrugOrder", function(event, index) {
|
|
$scope.treatments.splice(index, 1)
|
|
}), $scope.incompleteDrugOrders = function() {
|
|
var anyValuesFilled = $scope.treatment.drug || $scope.treatment.uniformDosingType.dose || $scope.treatment.uniformDosingType.frequency || $scope.treatment.variableDosingType.morningDose || $scope.treatment.variableDosingType.afternoonDose || $scope.treatment.variableDosingType.eveningDose || $scope.treatment.duration || $scope.treatment.quantity || $scope.treatment.isNonCodedDrug || $scope.treatment.drugNameDisplay;
|
|
return anyValuesFilled && $scope.addForm.$invalid
|
|
}, $scope.unaddedDrugOrders = function() {
|
|
return $scope.addForm.$valid
|
|
};
|
|
var contextChange = function() {
|
|
var errorMessages = Bahmni.Clinical.Constants.errorMessages;
|
|
return isSameDrugBeingDiscontinuedAndOrdered() ? {
|
|
allow: !1,
|
|
errorMessage: $translate.instant(errorMessages.discontinuingAndOrderingSameDrug)
|
|
} : $scope.incompleteDrugOrders() ? ($scope.formInvalid = !0, {
|
|
allow: !1
|
|
}) : $scope.unaddedDrugOrders() ? {
|
|
allow: !1,
|
|
errorMessage: $translate.instant(errorMessages.incompleteForm)
|
|
} : {
|
|
allow: !0
|
|
}
|
|
},
|
|
setIsNotBeingEdited = function(treatment) {
|
|
treatment.isBeingEdited = !1
|
|
};
|
|
$scope.getDataResults = function(drugs) {
|
|
var searchString = $scope.treatment.drugNameDisplay,
|
|
listOfDrugSynonyms = _.map(drugs, function(drug) {
|
|
return Bahmni.Clinical.DrugSearchResult.getAllMatchingSynonyms(drug, searchString)
|
|
});
|
|
return _.flatten(listOfDrugSynonyms)
|
|
},
|
|
function() {
|
|
var selectedItem;
|
|
$scope.onSelect = function(item) {
|
|
selectedItem = item, $scope.onChange()
|
|
}, $scope.onAccept = function() {
|
|
$scope.treatment.acceptedItem = $scope.treatment.drugNameDisplay, $scope.onChange()
|
|
};
|
|
var value = !1;
|
|
$scope["continue"] = function() {
|
|
value = !value, value === !0 ? void 0 === $scope.treatment.duration && ($scope.treatment.duration = parseInt("1")) : $scope.treatment.duration = void 0
|
|
}, $scope.onChange = function() {
|
|
return selectedItem ? ($scope.treatment.isNonCodedDrug = !1, delete $scope.treatment.drugNonCoded, $scope.treatment.changeDrug({
|
|
name: selectedItem.drug.name,
|
|
form: selectedItem.drug.dosageForm && selectedItem.drug.dosageForm.display,
|
|
uuid: selectedItem.drug.uuid
|
|
}), $scope.treatment.variableDosingType.doseUnits = selectedItem.drug.dosageForm.display, $http({
|
|
method: "GET",
|
|
url: "/openmrs/module/bahmnicustomutil/drugs-additional-info.form?uuid=${selectedItem.drug.uuid}"
|
|
}).success(function(response) {
|
|
response ? (response["continue"] === !0 ? ($scope.treatment["continue"] = !0, value = !0) : ($scope.treatment["continue"] = !1, value = !1), null !== response.instruction ? $scope.treatment.instructions = response.instruction : $scope.treatment.instructions = void 0, null !== response.duration ? $scope.treatment.duration = response.duration : response["continue"] === !0 ? $scope.treatment.duration = parseInt(1) : $scope.treatment.duration = void 0, null !== response.durationUnit ? $scope.treatment.durationUnit = response.durationUnit : $scope.treatment.durationUnit = "Day(s)", null !== response.dose ? ($scope.treatment.isUniformFrequency = !0, $scope.treatment.uniformDosingType.dose = parseFloat(response.dose), null !== response.frequency ? $scope.treatment.uniformDosingType.frequency = response.frequency : $scope.treatment.uniformDosingType.frequency = void 0, null !== response.and ? $scope.treatment.uniformDosingType.doseFraction = $scope.doseFractions.filter(function(data) {
|
|
return data.label === response.and
|
|
})[0] : $scope.treatment.uniformDosingType.doseFraction = void 0) : ($scope.treatment.isUniformFrequency = !1, $scope.treatment.uniformDosingType.dose = void 0, null !== response.morningDose ? ($scope.treatment.isUniformFrequency = !1, $scope.treatment.variableDosingType.morningDose = parseFloat(response.morningDose)) : $scope.treatment.variableDosingType.morningDose = 0, null !== response.nightDose ? ($scope.treatment.isUniformFrequency = !1, $scope.treatment.variableDosingType.eveningDose = parseFloat(response.nightDose)) : $scope.treatment.variableDosingType.eveningDose = 0, null !== response.afternoonDose ? ($scope.treatment.isUniformFrequency = !1, $scope.treatment.variableDosingType.afternoonDose = parseFloat(response.afternoonDose)) : $scope.treatment.variableDosingType.afternoonDose = 0)) : ($scope.treatment.isUniformFrequency = !1, $scope.treatment.uniformDosingType.dose = void 0, $scope.treatment.variableDosingType.afternoonDose = 0, $scope.treatment.variableDosingType.morningDose = 0, $scope.treatment.variableDosingType.eveningDose = 0, $scope.treatment.uniformDosingType.frequency = void 0, $scope.treatment.uniformDosingType.doseFraction = void 0, $scope.treatment.duration = void 0, $scope.treatment["continue"] = !1, $scope.treatment.instructions = void 0, $scope.treatment.durationUnit = "Day(s)")
|
|
}), void(selectedItem = null)) : $scope.treatment.acceptedItem ? ($scope.treatment.isNonCodedDrug = !$scope.treatment.isNonCodedDrug, $scope.treatment.drugNonCoded = $scope.treatment.acceptedItem, delete $scope.treatment.drug, void delete $scope.treatment.acceptedItem) : void delete $scope.treatment.drug
|
|
}
|
|
}(), $scope.clearForm = function() {
|
|
$scope.treatment = newTreatment(), $scope.formInvalid = !1, clearHighlights(), markVariable("startNewDrugEntry")
|
|
}, $scope.openActionLink = function(extension) {
|
|
var url, location;
|
|
locationService.getLoggedInLocation().then(function(response) {
|
|
location = response.name, url = extension.url.replace("{{patient_ref}}", $scope.patient.identifier).replace("{{location_ref}}", location), $window.open(url, "_blank")
|
|
})
|
|
}, $scope.toggleTabIndexWithinModal = function(event) {
|
|
var buttonsToFocusOn = ["modal-revise-button", "modal-refill-button"],
|
|
focusedButton = event.target;
|
|
focusedButton.tabIndex = 1, buttonsToFocusOn.splice(buttonsToFocusOn.indexOf(focusedButton.id), 1);
|
|
var otherButton = buttonsToFocusOn[0];
|
|
$("#" + otherButton)[0].tabIndex = 2
|
|
}, $scope.toggleDrugOrderAttribute = function(orderAttribute) {
|
|
orderAttribute.value = !orderAttribute.value
|
|
}, contextChangeHandler.add(contextChange);
|
|
var getActiveDrugOrders = function(activeDrugOrders) {
|
|
var activeDrugOrdersList = activeDrugOrders || [];
|
|
return activeDrugOrdersList.map(function(drugOrder) {
|
|
return DrugOrderViewModel.createFromContract(drugOrder, treatmentConfig)
|
|
})
|
|
},
|
|
removeOrder = function(removableOrder) {
|
|
removableOrder.action = Bahmni.Clinical.Constants.orderActions.discontinue, removableOrder.previousOrderUuid = removableOrder.uuid, removableOrder.uuid = void 0, $scope.consultation.removableDrugs.push(removableOrder)
|
|
},
|
|
saveTreatment = function() {
|
|
var tabNames = Object.keys($scope.consultation.newlyAddedTabTreatments || {}),
|
|
allTreatmentsAcrossTabs = _.flatten(_.map(tabNames, function(tabName) {
|
|
return $scope.consultation.newlyAddedTabTreatments[tabName].treatments
|
|
})),
|
|
orderSetTreatmentsAcrossTabs = _.flatten(_.map(tabNames, function(tabName) {
|
|
return $scope.consultation.newlyAddedTabTreatments[tabName].orderSetTreatments
|
|
})),
|
|
includedOrderSetTreatments = _.filter(orderSetTreatmentsAcrossTabs, function(treatment) {
|
|
return !treatment.orderSetUuid || treatment.include
|
|
});
|
|
$scope.consultation.newlyAddedTreatments = allTreatmentsAcrossTabs.concat(includedOrderSetTreatments), $scope.consultation.discontinuedDrugs && $scope.consultation.discontinuedDrugs.forEach(function(discontinuedDrug) {
|
|
var removableOrder = _.find(activeDrugOrders, {
|
|
uuid: discontinuedDrug.uuid
|
|
});
|
|
discontinuedDrug && (removableOrder.orderReasonText = discontinuedDrug.orderReasonText, removableOrder.dateActivated = null, removableOrder.scheduledDate = discontinuedDrug.dateStopped, removableOrder.dateStopped = discontinuedDrug.dateStopped, discontinuedDrug.orderReasonConcept && discontinuedDrug.orderReasonConcept.name && (removableOrder.orderReasonConcept = {
|
|
name: discontinuedDrug.orderReasonConcept.name.name,
|
|
uuid: discontinuedDrug.orderReasonConcept.uuid
|
|
})), removableOrder && removeOrder(removableOrder)
|
|
})
|
|
},
|
|
putCalculatedDose = function(orderTemplate) {
|
|
var visitUuid = treatmentConfig.orderSet.calculateDoseOnlyOnCurrentVisitValues ? $scope.activeVisit.uuid : void 0,
|
|
calculatedDose = orderSetService.getCalculatedDose($scope.patient.uuid, orderTemplate.concept.name, orderTemplate.dosingInstructions.dose, orderTemplate.dosingInstructions.doseUnits, $scope.newOrderSet.name, orderTemplate.dosingInstructions.dosingRule, visitUuid);
|
|
return 0 === calculatedDose.$$state.status && ($scope.isSearchDisabled = !1), calculatedDose.then(function(calculatedDosage) {
|
|
return orderTemplate.dosingInstructions.dose = calculatedDosage.dose, orderTemplate.dosingInstructions.doseUnits = calculatedDosage.doseUnit, orderTemplate
|
|
})
|
|
},
|
|
deleteDrugIfEmpty = function(template) {
|
|
_.isEmpty(template.drug) && delete template.drug
|
|
},
|
|
setUpOrderSetTransactionalData = function(orderSetMember) {
|
|
orderSetMember.orderTemplateMetaData = orderSetMember.orderTemplate, orderSetMember.orderTemplate = JSON.parse(orderSetMember.orderTemplate), orderSetMember.orderTemplate.concept = {
|
|
name: orderSetMember.concept.display,
|
|
uuid: orderSetMember.concept.uuid
|
|
}, deleteDrugIfEmpty(orderSetMember.orderTemplate)
|
|
},
|
|
calculateDoseForTemplatesIn = function(orderSet) {
|
|
$scope.newOrderSet.name = orderSet.name;
|
|
var orderSetMemberTemplates = _.map(orderSet.orderSetMembers, "orderTemplate"),
|
|
promisesToCalculateDose = _.map(orderSetMemberTemplates, putCalculatedDose),
|
|
returnOrderSet = function() {
|
|
return orderSet
|
|
};
|
|
return $q.all(promisesToCalculateDose).then(returnOrderSet)
|
|
},
|
|
createDrugOrderViewModel = function(orderTemplate) {
|
|
orderTemplate.effectiveStartDate = $scope.newOrderSet.date;
|
|
var drugOrder = Bahmni.Clinical.DrugOrder.create(orderTemplate),
|
|
drugOrderViewModel = Bahmni.Clinical.DrugOrderViewModel.createFromContract(drugOrder, treatmentConfig);
|
|
return drugOrderViewModel.instructions = orderTemplate.administrationInstructions, drugOrderViewModel.additionalInstructions = orderTemplate.additionalInstructions, drugOrderViewModel.isNewOrderSet = !0, drugOrderViewModel.dosingInstructionType = Bahmni.Clinical.Constants.flexibleDosingInstructionsClass, drugOrderViewModel.quantity = drugOrderViewModel.quantity || 0, drugOrderViewModel.calculateDurationUnit(), drugOrderViewModel.calculateQuantityAndUnit(), drugOrderViewModel.calculateEffectiveStopDate(), drugOrderViewModel.setUniformDoseFraction(), drugOrderViewModel
|
|
},
|
|
setSortWeightForOrderSetDrugs = function(orderSetDrugs) {
|
|
_.each(orderSetDrugs, function(drugOrder, index) {
|
|
void 0 !== drugOrder.sortWeight ? drugOrder.sortWeight = drugOrder.sortWeight + orderSetDrugs.length : drugOrder.sortWeight = index + 1
|
|
})
|
|
},
|
|
createDrugOrdersAndGetConflicts = function(orderSet) {
|
|
var conflictingDrugOrders = [],
|
|
orderSetMemberTemplates = _.map(orderSet.orderSetMembers, "orderTemplate");
|
|
return _.each(orderSetMemberTemplates, function(orderTemplate) {
|
|
var drugOrderViewModel = createDrugOrderViewModel(orderTemplate);
|
|
drugOrderViewModel.orderSetUuid = orderSet.uuid;
|
|
var conflictingDrugOrder = getConflictingDrugOrder(drugOrderViewModel);
|
|
conflictingDrugOrder ? conflictingDrugOrders.push(conflictingDrugOrder) : drugOrderViewModel.include = !1, $scope.orderSetTreatments.push(drugOrderViewModel)
|
|
}), setSortWeightForOrderSetDrugs($scope.orderSetTreatments), conflictingDrugOrders
|
|
},
|
|
showConflictMessageIfAny = function(conflictingDrugOrders) {
|
|
_.isEmpty(conflictingDrugOrders) || (_.each($scope.orderSetTreatments, function(orderSetDrugOrder) {
|
|
orderSetDrugOrder.include = !1
|
|
}), ngDialog.open({
|
|
template: "consultation/views/treatmentSections/conflictingOrderSet.html",
|
|
data: {
|
|
conflictingDrugOrders: conflictingDrugOrders
|
|
}
|
|
}), $scope.popupActive = !0)
|
|
};
|
|
$scope.addOrderSet = function(orderSet) {
|
|
$scope.isSearchDisabled = !0, scrollTop();
|
|
var setUpNewOrderSet = function() {
|
|
$scope.newOrderSet.name = orderSet.name, $scope.newOrderSet.uuid = orderSet.uuid, $scope.isSearchDisabled = !0
|
|
};
|
|
calculateDoseForTemplatesIn(orderSet).then(createDrugOrdersAndGetConflicts).then(showConflictMessageIfAny).then(setUpNewOrderSet)
|
|
}, $scope.removeOrderSet = function() {
|
|
$scope.isSearchDisabled = !1, delete $scope.newOrderSet.name, delete $scope.newOrderSet.uuid, $scope.orderSetTreatments.splice(0, $scope.orderSetTreatments.length)
|
|
}, $scope.$on("event:includeOrderSetDrugOrder", function(event, drugOrder) {
|
|
var conflictingDrugOrder = getConflictingDrugOrder(drugOrder);
|
|
conflictingDrugOrder && (drugOrder.include = !1, ngDialog.open({
|
|
template: "consultation/views/treatmentSections/conflictingOrderSet.html",
|
|
data: {
|
|
conflictingDrugOrders: [conflictingDrugOrder]
|
|
}
|
|
}), $scope.popupActive = !0)
|
|
}), $scope.consultation.preSaveHandler.register("drugOrderSaveHandlerKey", saveTreatment);
|
|
var mergeActiveAndScheduledWithDiscontinuedOrders = function() {
|
|
_.each($scope.consultation.discontinuedDrugs, function(discontinuedDrug) {
|
|
_.remove($scope.consultation.activeAndScheduledDrugOrders, {
|
|
uuid: discontinuedDrug.uuid
|
|
}), $scope.consultation.activeAndScheduledDrugOrders.push(discontinuedDrug)
|
|
})
|
|
},
|
|
init = function() {
|
|
$scope.consultation.removableDrugs = $scope.consultation.removableDrugs || [], $scope.consultation.discontinuedDrugs = $scope.consultation.discontinuedDrugs || [], $scope.consultation.drugOrdersWithUpdatedOrderAttributes = $scope.consultation.drugOrdersWithUpdatedOrderAttributes || {}, $scope.consultation.activeAndScheduledDrugOrders = getActiveDrugOrders(activeDrugOrders), mergeActiveAndScheduledWithDiscontinuedOrders(), $scope.treatmentConfig = treatmentConfig
|
|
};
|
|
init()
|
|
}]), angular.module("bahmni.clinical").controller("DispositionController", ["$scope", "$q", "dispositionService", "retrospectiveEntryService", "spinner", function($scope, $q, dispositionService, retrospectiveEntryService, spinner) {
|
|
var consultation = $scope.consultation,
|
|
allDispositions = [],
|
|
getPreviousDispositionNote = function() {
|
|
if (consultation.disposition && !consultation.disposition.voided) return _.find(consultation.disposition.additionalObs, function(obs) {
|
|
return obs.concept.uuid === $scope.dispositionNoteConceptUuid
|
|
})
|
|
},
|
|
getDispositionNotes = function() {
|
|
var previousDispositionNotes = getPreviousDispositionNote();
|
|
return getSelectedConceptName($scope.dispositionCode, $scope.dispositionActions) ? _.cloneDeep(previousDispositionNotes) || {
|
|
concept: {
|
|
uuid: $scope.dispositionNoteConceptUuid
|
|
}
|
|
} : {
|
|
concept: {
|
|
uuid: $scope.dispositionNoteConceptUuid
|
|
}
|
|
}
|
|
},
|
|
getDispositionActionsPromise = function() {
|
|
return dispositionService.getDispositionActions().then(function(response) {
|
|
allDispositions = (new Bahmni.Clinical.DispostionActionMapper).map(response.data.results[0].answers), $scope.dispositionActions = filterDispositionActions(allDispositions, $scope.$parent.visitSummary), $scope.dispositionCode = consultation.disposition && !consultation.disposition.voided ? consultation.disposition.code : null, $scope.dispositionNote = getDispositionNotes()
|
|
})
|
|
},
|
|
getDispositionActions = function(finalDispositionActions, dispositions, action) {
|
|
var copyOfFinalDispositionActions = _.cloneDeep(finalDispositionActions),
|
|
dispositionPresent = _.find(dispositions, action);
|
|
return dispositionPresent && copyOfFinalDispositionActions.push(dispositionPresent), copyOfFinalDispositionActions
|
|
},
|
|
filterDispositionActions = function(dispositions, visitSummary) {
|
|
var defaultDispositions = ["Undo Discharge", "Admit Patient", "Transfer Patient", "Discharge Patient"],
|
|
finalDispositionActions = _.filter(dispositions, function(disposition) {
|
|
return defaultDispositions.indexOf(disposition.name) < 0
|
|
}),
|
|
isVisitOpen = !!visitSummary && _.isEmpty(visitSummary.stopDateTime);
|
|
return visitSummary && visitSummary.isDischarged() && isVisitOpen ? finalDispositionActions = getDispositionActions(finalDispositionActions, dispositions, {
|
|
name: defaultDispositions[0]
|
|
}) : visitSummary && visitSummary.isAdmitted() && isVisitOpen ? (finalDispositionActions = getDispositionActions(finalDispositionActions, dispositions, {
|
|
name: defaultDispositions[2]
|
|
}), finalDispositionActions = getDispositionActions(finalDispositionActions, dispositions, {
|
|
name: defaultDispositions[3]
|
|
})) : finalDispositionActions = getDispositionActions(finalDispositionActions, dispositions, {
|
|
name: defaultDispositions[1]
|
|
}), finalDispositionActions
|
|
};
|
|
$scope.isRetrospectiveMode = function() {
|
|
return !_.isEmpty(retrospectiveEntryService.getRetrospectiveEntry())
|
|
}, $scope.showWarningForEarlierDispositionNote = function() {
|
|
return !$scope.dispositionCode && consultation.disposition
|
|
};
|
|
var getDispositionNotePromise = function() {
|
|
return dispositionService.getDispositionNoteConcept().then(function(response) {
|
|
$scope.dispositionNoteConceptUuid = response.data.results[0].uuid
|
|
})
|
|
},
|
|
loadDispositionActions = function() {
|
|
return getDispositionNotePromise().then(getDispositionActionsPromise)
|
|
};
|
|
$scope.clearDispositionNote = function() {
|
|
$scope.dispositionNote.value = null
|
|
};
|
|
var getSelectedConceptName = function(dispositionCode, dispositions) {
|
|
var selectedDispositionConceptName = _.findLast(dispositions, {
|
|
code: dispositionCode
|
|
}) || {};
|
|
return selectedDispositionConceptName.name
|
|
},
|
|
getSelectedDisposition = function() {
|
|
if ($scope.dispositionCode) {
|
|
$scope.dispositionNote.voided = !$scope.dispositionNote.value;
|
|
var disposition = {
|
|
additionalObs: [],
|
|
dispositionDateTime: consultation.disposition && consultation.disposition.dispositionDateTime,
|
|
code: $scope.dispositionCode,
|
|
conceptName: getSelectedConceptName($scope.dispositionCode, allDispositions)
|
|
};
|
|
return ($scope.dispositionNote.value || $scope.dispositionNote.uuid) && (disposition.additionalObs = [_.clone($scope.dispositionNote)]), disposition
|
|
}
|
|
};
|
|
spinner.forPromise(loadDispositionActions(), "#disposition");
|
|
var saveDispositions = function() {
|
|
var selectedDisposition = getSelectedDisposition();
|
|
selectedDisposition ? consultation.disposition = selectedDisposition : consultation.disposition && (consultation.disposition.voided = !0, consultation.disposition.voidReason = "Cancelled during encounter")
|
|
};
|
|
$scope.consultation.preSaveHandler.register("dispositionSaveHandlerKey", saveDispositions), $scope.$on("$destroy", saveDispositions)
|
|
}]), angular.module("bahmni.clinical").controller("ConsultationController", ["$scope", "$rootScope", "$state", "$http", "$location", "$translate", "clinicalAppConfigService", "diagnosisService", "urlHelper", "contextChangeHandler", "spinner", "encounterService", "messagingService", "sessionService", "retrospectiveEntryService", "patientContext", "$q", "patientVisitHistoryService", "$stateParams", "$window", "visitHistory", "clinicalDashboardConfig", "appService", "ngDialog", "$filter", "configurations", "visitConfig", "conditionsService", "configurationService", "auditLogService", function($scope, $rootScope, $state, $http, $location, $translate, clinicalAppConfigService, diagnosisService, urlHelper, contextChangeHandler, spinner, encounterService, messagingService, sessionService, retrospectiveEntryService, patientContext, $q, patientVisitHistoryService, $stateParams, $window, visitHistory, clinicalDashboardConfig, appService, ngDialog, $filter, configurations, visitConfig, conditionsService, configurationService, auditLogService) {
|
|
var DateUtil = Bahmni.Common.Util.DateUtil;
|
|
Bahmni.Common.Domain.Conditions.getPreviousActiveCondition;
|
|
$scope.togglePrintList = !1, $scope.patient = patientContext.patient, $scope.showDashboardMenu = !1, $scope.stateChange = function() {
|
|
return "patient.dashboard.show" === $state.current.name
|
|
}, $scope.showComment = !0, $scope.showSaveAndContinueButton = !0, $scope.visitHistory = visitHistory, $scope.consultationBoardLink = clinicalAppConfigService.getConsultationBoardLink(), $scope.showControlPanel = !1, $scope.clinicalDashboardConfig = clinicalDashboardConfig, $scope.lastvisited = null, $scope.openConsultationInNewTab = function() {
|
|
$window.open("#" + $scope.consultationBoardLink, "_blank")
|
|
}, $scope.toggleDashboardMenu = function() {
|
|
$scope.showDashboardMenu = !$scope.showDashboardMenu
|
|
}, $scope.showDashboard = function(dashboard) {
|
|
clinicalDashboardConfig.isCurrentTab(dashboard) || $scope.$parent.$broadcast("event:switchDashboard", dashboard), $scope.showDashboardMenu = !1
|
|
};
|
|
var setPrintAction = function(event, tab) {
|
|
tab.print = function() {
|
|
$rootScope.$broadcast(event, tab)
|
|
}
|
|
},
|
|
setDashboardPrintAction = _.partial(setPrintAction, "event:printDashboard", _),
|
|
setVisitTabPrintAction = function(tab) {
|
|
tab.print = function() {
|
|
var url = $state.href("patient.dashboard.visitPrint", {
|
|
visitUuid: visitHistory.activeVisit.uuid,
|
|
tab: tab.title,
|
|
print: "print"
|
|
});
|
|
window.open(url, "_blank")
|
|
}
|
|
};
|
|
_.each(visitConfig.tabs, setVisitTabPrintAction), _.each(clinicalDashboardConfig.tabs, setDashboardPrintAction), $scope.printList = _.concat(clinicalDashboardConfig.tabs, visitConfig.tabs), clinicalDashboardConfig.quickPrints = appService.getAppDescriptor().getConfigValue("quickPrints"), $scope.printDashboard = function(tab) {
|
|
tab ? tab.print() : clinicalDashboardConfig.currentTab.print()
|
|
}, $scope.allowConsultation = function() {
|
|
return appService.getAppDescriptor().getConfigValue("allowConsultationWhenNoOpenVisit")
|
|
}, $scope.closeDashboard = function(dashboard) {
|
|
clinicalDashboardConfig.closeTab(dashboard), $scope.$parent.$parent.$broadcast("event:switchDashboard", clinicalDashboardConfig.currentTab)
|
|
}, $scope.closeAllDialogs = function() {
|
|
ngDialog.closeAll()
|
|
}, $scope.availableBoards = [], $scope.configName = $stateParams.configName, $scope.getTitle = function(board) {
|
|
return $filter("titleTranslate")(board)
|
|
}, $scope.showBoard = function(boardIndex) {
|
|
return $rootScope.collapseControlPanel(), buttonClickAction($scope.availableBoards[boardIndex])
|
|
};
|
|
var updateQueueStatus = function(identifier, roomId) {
|
|
return $http({
|
|
method: "PUT",
|
|
url: "/openmrs/module/queuemanagement/updateQueue.form?identifier=" + identifier + "&roomId=" + roomId,
|
|
headers: {
|
|
"Content-Type": "application/json"
|
|
}
|
|
})
|
|
};
|
|
$scope.completeConsultation = function(visitUuid) {
|
|
const queueMng = appService.getAppDescriptor().getConfigValue("queueManagement"),
|
|
identifier = $scope.patient.identifier,
|
|
date = new Date,
|
|
formatDate = date.toISOString().split("T");
|
|
queueMng.willUse === !0 ? $http({
|
|
method: "GET",
|
|
url: "/openmrs/module/queuemanagement/getToken.form?identifier=" + identifier + "&dateCreated=" + formatDate[0]
|
|
}).then(function(response) {
|
|
const room = response.data.roomId;
|
|
void 0 !== room ? updateQueueStatus(identifier, room) : console.log("Patient Room Id is undefined for the queue")
|
|
}) : console.log("Queue management module is not being used now"), contextChangeHandler.execute().allow && $location.path($stateParams.configName + "/patient/" + patientContext.patient.uuid + "/dashboard/visit/" + visitUuid + "/?encounterUuid=active")
|
|
}, $scope.gotoPatientDashboard = function() {
|
|
if (!isFormValid()) return $scope.$parent.$parent.$broadcast("event:errorsOnForm"), $q.when({});
|
|
if (contextChangeHandler.execute().allow) {
|
|
var params = {
|
|
configName: $scope.configName,
|
|
patientUuid: patientContext.patient.uuid,
|
|
encounterUuid: void 0
|
|
};
|
|
$scope.dashboardDirty && (params.dashboardCachebuster = Math.random()), $state.go("patient.dashboard.show", params)
|
|
}
|
|
};
|
|
var isLongerName = function(value) {
|
|
return !!value && value.length > 18
|
|
};
|
|
$scope.getShorterName = function(value) {
|
|
return isLongerName(value) ? value.substring(0, 15) + "..." : value
|
|
}, $scope.isInEditEncounterMode = function() {
|
|
return void 0 !== $stateParams.encounterUuid && "active" !== $stateParams.encounterUuid
|
|
}, $scope.enablePatientSearch = function() {
|
|
return appService.getAppDescriptor().getConfigValue("allowPatientSwitchOnConsultation") === !0
|
|
};
|
|
var setCurrentBoardBasedOnPath = function() {
|
|
var currentPath = $location.url(),
|
|
board = _.find($scope.availableBoards, function(board) {
|
|
return "treatment" === board.url ? _.includes(currentPath, board.extensionParams ? board.extensionParams.tabConfigName : board.url) : _.includes(currentPath, board.url)
|
|
});
|
|
board && ($scope.currentBoard = board, $scope.currentBoard.isSelectedTab = !0)
|
|
},
|
|
initialize = function() {
|
|
var appExtensions = clinicalAppConfigService.getAllConsultationBoards();
|
|
$scope.adtNavigationConfig = {
|
|
forwardUrl: Bahmni.Clinical.Constants.adtForwardUrl,
|
|
title: $translate.instant("CLINICAL_GO_TO_DASHBOARD_LABEL"),
|
|
privilege: Bahmni.Clinical.Constants.adtPrivilege
|
|
}, $scope.availableBoards = $scope.availableBoards.concat(appExtensions), $scope.showSaveConfirmDialogConfig = appService.getAppDescriptor().getConfigValue("showSaveConfirmDialog");
|
|
var adtNavigationConfig = appService.getAppDescriptor().getConfigValue("adtNavigationConfig");
|
|
Object.assign($scope.adtNavigationConfig, adtNavigationConfig), setCurrentBoardBasedOnPath()
|
|
};
|
|
$scope.shouldDisplaySaveConfirmDialogForStateChange = function(toState, toParams, fromState, fromParams) {
|
|
return !toState.name.match(/patient.dashboard.show.*/) || fromParams.patientUuid != toParams.patientUuid
|
|
};
|
|
var cleanUpListenerStateChangeStart = $scope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams) {
|
|
$scope.showSaveConfirmDialogConfig && $rootScope.hasVisitedConsultation && $scope.shouldDisplaySaveConfirmDialogForStateChange(toState, toParams, fromState, fromParams) && $scope.showConfirmationPopUp && (event.preventDefault(), spinner.hide(toState.spinnerToken), ngDialog.close(), $scope.toStateConfig = {
|
|
toState: toState,
|
|
toParams: toParams
|
|
}, $scope.displayConfirmationDialog()), setCurrentBoardBasedOnPath()
|
|
});
|
|
$scope.adtNavigationURL = function(visitUuid) {
|
|
return appService.getAppDescriptor().formatUrl($scope.adtNavigationConfig.forwardUrl, {
|
|
patientUuid: $scope.patient.uuid,
|
|
visitUuid: visitUuid
|
|
})
|
|
};
|
|
var cleanUpListenerErrorsOnForm = $scope.$on("event:errorsOnForm", function() {
|
|
$scope.showConfirmationPopUp = !0
|
|
});
|
|
$scope.displayConfirmationDialog = function(event) {
|
|
$rootScope.hasVisitedConsultation && $scope.showSaveConfirmDialogConfig && (event && (event.preventDefault(), $scope.targetUrl = event.currentTarget.getAttribute("href")), ngDialog.openConfirm({
|
|
template: "../common/ui-helper/views/saveConfirmation.html",
|
|
scope: $scope
|
|
}))
|
|
};
|
|
var cleanUpListenerStateChangeSuccess = $scope.$on("$stateChangeSuccess", function(event, toState, toParams, fromState) {
|
|
toState.name.match(/patient.dashboard.show.+/) && ($rootScope.hasVisitedConsultation = !0, $scope.showConfirmationPopUp = !0, $scope.showSaveConfirmDialogConfig && $rootScope.$broadcast("event:pageUnload")), toState.name === fromState.name && "patient.dashboard.show" === fromState.name && ($rootScope.hasVisitedConsultation = !1)
|
|
});
|
|
$scope.$on("$destroy", function() {
|
|
cleanUpListenerStateChangeSuccess(), cleanUpListenerErrorsOnForm(), cleanUpListenerStateChangeStart()
|
|
}), $scope.cancelTransition = function() {
|
|
$scope.showConfirmationPopUp = !0, ngDialog.close(), delete $scope.targetUrl
|
|
}, $scope.saveAndContinue = function() {
|
|
$scope.showConfirmationPopUp = !1, $scope.save($scope.toStateConfig), $window.onbeforeunload = null, ngDialog.close()
|
|
}, $scope.continueWithoutSaving = function() {
|
|
$scope.showConfirmationPopUp = !1, $scope.targetUrl && $window.open($scope.targetUrl, "_self"),
|
|
$window.onbeforeunload = null, $state.go($scope.toStateConfig.toState, $scope.toStateConfig.toParams), ngDialog.close()
|
|
};
|
|
var getUrl = function(board) {
|
|
var urlPrefix = urlHelper.getPatientUrl(),
|
|
url = "/" + $stateParams.configName + (board.url ? urlPrefix + "/" + board.url : urlPrefix),
|
|
queryParams = [];
|
|
$state.params.encounterUuid && queryParams.push("encounterUuid=" + $state.params.encounterUuid), $state.params.programUuid && queryParams.push("programUuid=" + $state.params.programUuid), $state.params.enrollment && queryParams.push("enrollment=" + $state.params.enrollment), $state.params.dateEnrolled && queryParams.push("dateEnrolled=" + $state.params.dateEnrolled), $state.params.dateCompleted && queryParams.push("dateCompleted=" + $state.params.dateCompleted);
|
|
var extensionParams = board.extensionParams;
|
|
return angular.forEach(extensionParams, function(extensionParamValue, extensionParamKey) {
|
|
queryParams.push(extensionParamKey + "=" + extensionParamValue)
|
|
}), _.isEmpty(queryParams) || (url = url + "?" + queryParams.join("&")), $scope.lastConsultationTabUrl.url = url, $location.url(url)
|
|
};
|
|
$scope.openConsultation = function() {
|
|
$scope.showSaveConfirmDialogConfig && $rootScope.$broadcast("event:pageUnload"), $scope.closeAllDialogs(), $scope.collapseControlPanel(), $rootScope.hasVisitedConsultation = !0, switchToConsultationTab()
|
|
}, $scope.singlePagePrescription = function() {
|
|
//$window.location.href = "https://${$window.location.hostname}:6061/prescription/${$scope.patient.uuid}"
|
|
$window.location.href = "https://" + $window.location.hostname + ":6060/patientDashboard/" + $scope.patient.uuid;
|
|
};
|
|
var switchToConsultationTab = function() {
|
|
$scope.lastConsultationTabUrl.url ? $location.url($scope.lastConsultationTabUrl.url) : getUrl($scope.availableBoards[0])
|
|
},
|
|
contextChange = function() {
|
|
return contextChangeHandler.execute()
|
|
},
|
|
buttonClickAction = function(board) {
|
|
if ($scope.currentBoard !== board) return isFormValid() ? (contextChangeHandler.reset(), _.map($scope.availableBoards, function(availableBoard) {
|
|
availableBoard.isSelectedTab = !1
|
|
}), $scope.currentBoard = board, $scope.currentBoard.isSelectedTab = !0, getUrl(board)) : void $scope.$parent.$broadcast("event:errorsOnForm")
|
|
},
|
|
preSavePromise = function() {
|
|
var deferred = $q.defer(),
|
|
observationFilter = new Bahmni.Common.Domain.ObservationFilter;
|
|
$scope.consultation.preSaveHandler.fire(), $scope.lastvisited = $scope.consultation.lastvisited;
|
|
var selectedObsTemplate = $scope.consultation.selectedObsTemplate,
|
|
tempConsultation = angular.copy($scope.consultation);
|
|
tempConsultation.observations = observationFilter.filter(tempConsultation.observations), tempConsultation.consultationNote = observationFilter.filter([tempConsultation.consultationNote])[0], tempConsultation.labOrderNote = observationFilter.filter([tempConsultation.labOrderNote])[0], addFormObservations(tempConsultation), storeTemplatePreference(selectedObsTemplate);
|
|
var visitTypeForRetrospectiveEntries = clinicalAppConfigService.getVisitTypeForRetrospectiveEntries(),
|
|
defaultVisitType = clinicalAppConfigService.getDefaultVisitType(),
|
|
encounterData = (new Bahmni.Clinical.EncounterTransactionMapper).map(tempConsultation, $scope.patient, sessionService.getLoginLocationUuid(), retrospectiveEntryService.getRetrospectiveEntry(), visitTypeForRetrospectiveEntries, defaultVisitType, $scope.isInEditEncounterMode(), $state.params.enrollment);
|
|
return deferred.resolve(encounterData), deferred.promise
|
|
},
|
|
saveConditions = function() {
|
|
return conditionsService.save($scope.consultation.conditions, $scope.patient.uuid).then(function() {
|
|
return conditionsService.getConditions($scope.patient.uuid)
|
|
}).then(function(savedConditions) {
|
|
return savedConditions
|
|
})
|
|
},
|
|
storeTemplatePreference = function(selectedObsTemplate) {
|
|
var templates = [];
|
|
_.each(selectedObsTemplate, function(template) {
|
|
var templateName = template.formName || template.conceptName,
|
|
isTemplateAlreadyPresent = _.find(templates, function(template) {
|
|
return template === templateName
|
|
});
|
|
_.isUndefined(isTemplateAlreadyPresent) && templates.push(templateName)
|
|
});
|
|
var data = {
|
|
patientUuid: $scope.patient.uuid,
|
|
providerUuid: $rootScope.currentProvider.uuid,
|
|
templates: templates
|
|
};
|
|
_.isEmpty(templates) || localStorage.setItem("templatePreference", JSON.stringify(data))
|
|
},
|
|
discontinuedDrugOrderValidation = function(removableDrugs) {
|
|
var discontinuedDrugOrderValidationMessage;
|
|
return _.find(removableDrugs, function(drugOrder) {
|
|
if (!drugOrder.dateStopped) return drugOrder._effectiveStartDate < moment() ? (discontinuedDrugOrderValidationMessage = "Please make sure that " + drugOrder.concept.name + " has a stop date between " + DateUtil.getDateWithoutTime(drugOrder._effectiveStartDate) + " and " + DateUtil.getDateWithoutTime(DateUtil.now()), !0) : (discontinuedDrugOrderValidationMessage = drugOrder.concept.name + " should have stop date as today's date since it is a future drug order", !0)
|
|
}), discontinuedDrugOrderValidationMessage
|
|
},
|
|
addFormObservations = function(tempConsultation) {
|
|
tempConsultation.observationForms && (_.remove(tempConsultation.observations, function(observation) {
|
|
return observation.formNamespace
|
|
}), _.each(tempConsultation.observationForms, function(observationForm) {
|
|
if (observationForm.component) {
|
|
var formObservations = observationForm.component.getValue();
|
|
_.each(formObservations.observations, function(obs) {
|
|
tempConsultation.observations.push(obs)
|
|
})
|
|
}
|
|
}))
|
|
},
|
|
isObservationFormValid = function() {
|
|
var valid = !0;
|
|
return _.each($scope.consultation.observationForms, function(observationForm) {
|
|
if (valid && observationForm.component) {
|
|
var value = observationForm.component.getValue();
|
|
value.errors && (messagingService.showMessage("error", "{{'CLINICAL_FORM_ERRORS_MESSAGE_KEY' | translate }}"), valid = !1)
|
|
}
|
|
}), valid
|
|
},
|
|
isFormValid = function() {
|
|
var contxChange = contextChange(),
|
|
shouldAllow = contxChange.allow,
|
|
discontinuedDrugOrderValidationMessage = discontinuedDrugOrderValidation($scope.consultation.discontinuedDrugs);
|
|
if (shouldAllow) discontinuedDrugOrderValidationMessage && messagingService.showMessage("error", discontinuedDrugOrderValidationMessage);
|
|
else {
|
|
var errorMessage = contxChange.errorMessage ? contxChange.errorMessage : "{{'CLINICAL_FORM_ERRORS_MESSAGE_KEY' | translate }}";
|
|
messagingService.showMessage("error", errorMessage)
|
|
}
|
|
return shouldAllow && !discontinuedDrugOrderValidationMessage && isObservationFormValid()
|
|
},
|
|
copyConsultationToScope = function(consultationWithDiagnosis) {
|
|
consultationWithDiagnosis.preSaveHandler = $scope.consultation.preSaveHandler, consultationWithDiagnosis.postSaveHandler = $scope.consultation.postSaveHandler, $scope.$parent.consultation = consultationWithDiagnosis, $scope.$parent.consultation.postSaveHandler.fire(), $scope.dashboardDirty = !0
|
|
};
|
|
$scope.save = function(toStateConfig) {
|
|
return isFormValid() ? spinner.forPromise($q.all([preSavePromise(), encounterService.getEncounterType($state.params.programUuid, sessionService.getLoginLocationUuid())]).then(function(results) {
|
|
var encounterData = results[0];
|
|
encounterData.encounterTypeUuid = results[1].uuid;
|
|
var params = angular.copy($state.params);
|
|
return params.cachebuster = Math.random(), encounterService.create(encounterData).then(function(saveResponse) {
|
|
var messageParams = {
|
|
encounterUuid: saveResponse.data.encounterUuid,
|
|
encounterType: saveResponse.data.encounterType
|
|
};
|
|
auditLogService.log($scope.patient.uuid, "EDIT_ENCOUNTER", messageParams, "MODULE_LABEL_CLINICAL_KEY");
|
|
var consultationMapper = new Bahmni.ConsultationMapper(configurations.dosageFrequencyConfig(), configurations.dosageInstructionConfig(), configurations.consultationNoteConcept(), configurations.labOrderNotesConcept(), $scope.followUpConditionConcept),
|
|
consultation = consultationMapper.map(saveResponse.data);
|
|
return consultation.lastvisited = $scope.lastvisited, consultation
|
|
}).then(function(savedConsultation) {
|
|
return spinner.forPromise(diagnosisService.populateDiagnosisInformation($scope.patient.uuid, savedConsultation).then(function(consultationWithDiagnosis) {
|
|
return saveConditions().then(function(savedConditions) {
|
|
consultationWithDiagnosis.conditions = savedConditions, messagingService.showMessage("info", "{{'CLINICAL_SAVE_SUCCESS_MESSAGE_KEY' | translate}}")
|
|
}, function() {
|
|
consultationWithDiagnosis.conditions = $scope.consultation.conditions
|
|
}).then(function() {
|
|
return copyConsultationToScope(consultationWithDiagnosis), $scope.targetUrl ? $window.open($scope.targetUrl, "_self") : $state.transitionTo(toStateConfig ? toStateConfig.toState : $state.current, toStateConfig ? toStateConfig.toParams : params, {
|
|
inherit: !1,
|
|
notify: !0,
|
|
reload: void 0 !== toStateConfig
|
|
})
|
|
})
|
|
}))
|
|
})["catch"](function(error) {
|
|
var message = Bahmni.Clinical.Error.translate(error) || "{{'CLINICAL_SAVE_FAILURE_MESSAGE_KEY' | translate}}";
|
|
messagingService.showMessage("error", message)
|
|
})
|
|
})) : ($scope.$parent.$parent.$broadcast("event:errorsOnForm"), $q.when({}))
|
|
}, initialize()
|
|
}]), angular.module("bahmni.clinical").controller("ConceptSetPageController", ["$scope", "$rootScope", "$stateParams", "conceptSetService", "clinicalAppConfigService", "messagingService", "configurations", "$state", "spinner", "contextChangeHandler", "$q", "$translate", "formService", function($scope, $rootScope, $stateParams, conceptSetService, clinicalAppConfigService, messagingService, configurations, $state, spinner, contextChangeHandler, $q, $translate, formService) {
|
|
$scope.consultation.selectedObsTemplate = $scope.consultation.selectedObsTemplate || [], $scope.allTemplates = $scope.allTemplates || [], $scope.scrollingEnabled = !1;
|
|
var extensions = clinicalAppConfigService.getAllConceptSetExtensions($stateParams.conceptSetGroupName),
|
|
configs = clinicalAppConfigService.getAllConceptsConfig(),
|
|
visitType = configurations.encounterConfig().getVisitTypeByUuid($scope.consultation.visitTypeUuid);
|
|
$scope.context = {
|
|
visitType: visitType,
|
|
patient: $scope.patient
|
|
};
|
|
var numberOfLevels = 2,
|
|
fields = ["uuid", "name:(name,display)", "names:(uuid,conceptNameType,name)"],
|
|
customRepresentation = Bahmni.ConceptSet.CustomRepresentationBuilder.build(fields, "setMembers", numberOfLevels),
|
|
allConceptSections = [],
|
|
init = function() {
|
|
void 0 !== $scope.allTemplates && $scope.allTemplates.length > 0 || spinner.forPromise(conceptSetService.getConcept({
|
|
name: "All Observation Templates",
|
|
v: "custom:" + customRepresentation
|
|
}).then(function(response) {
|
|
var allTemplates = response.data.results[0].setMembers;
|
|
createConceptSections(allTemplates), $state.params.programUuid && showOnlyTemplatesFilledInProgram(), void 0 !== $scope.consultation.observationForms && $scope.consultation.observationForms.length > 0 ? concatObservationForms() : spinner.forPromise(formService.getFormList($scope.consultation.encounterUuid).then(function(response) {
|
|
$scope.consultation.observationForms = getObservationForms(response.data), concatObservationForms()
|
|
}))
|
|
}))
|
|
},
|
|
concatObservationForms = function() {
|
|
if ($scope.allTemplates = getSelectedObsTemplate(allConceptSections), $scope.uniqueTemplates = _.uniqBy($scope.allTemplates, "label"), $scope.allTemplates = $scope.allTemplates.concat($scope.consultation.observationForms), 0 == $scope.consultation.selectedObsTemplate.length) {
|
|
initializeDefaultTemplates(), $scope.consultation.observations && $scope.consultation.observations.length > 0 && addTemplatesInSavedOrder();
|
|
var templateToBeOpened = getLastVisitedTemplate() || _.first($scope.consultation.selectedObsTemplate);
|
|
templateToBeOpened && openTemplate(templateToBeOpened)
|
|
}
|
|
},
|
|
addTemplatesInSavedOrder = function() {
|
|
var templatePreference = JSON.parse(localStorage.getItem("templatePreference"));
|
|
templatePreference && templatePreference.patientUuid === $scope.patient.uuid && !_.isEmpty(templatePreference.templates) && $rootScope.currentProvider.uuid === templatePreference.providerUuid ? insertInSavedOrder(templatePreference) : insertInDefaultOrder()
|
|
},
|
|
insertInSavedOrder = function(templatePreference) {
|
|
var templateNames = templatePreference.templates;
|
|
_.each(templateNames, function(templateName) {
|
|
var foundTemplates = _.filter($scope.allTemplates, function(allTemplate) {
|
|
return allTemplate.conceptName === templateName
|
|
});
|
|
foundTemplates.length > 0 && _.each(foundTemplates, function(template) {
|
|
_.isEmpty(template.observations) || insertTemplate(template)
|
|
})
|
|
})
|
|
},
|
|
insertInDefaultOrder = function() {
|
|
_.each($scope.allTemplates, function(template) {
|
|
template.observations.length > 0 && insertTemplate(template)
|
|
})
|
|
},
|
|
insertTemplate = function(template) {
|
|
!template || template.isDefault() || template.alwaysShow || $scope.consultation.selectedObsTemplate.push(template)
|
|
},
|
|
getLastVisitedTemplate = function() {
|
|
return _.find($scope.consultation.selectedObsTemplate, function(template) {
|
|
return template.id === $scope.consultation.lastvisited
|
|
})
|
|
},
|
|
openTemplate = function(template) {
|
|
template.isOpen = !0, template.isLoaded = !0, template.klass = "active"
|
|
},
|
|
initializeDefaultTemplates = function() {
|
|
$scope.consultation.selectedObsTemplate = _.filter($scope.allTemplates.reverse(), function(template) {
|
|
return template.isDefault() || template.alwaysShow
|
|
})
|
|
};
|
|
$scope.filterTemplates = function() {
|
|
return $scope.uniqueTemplates = _.uniqBy($scope.allTemplates, "label"), $scope.uniqueTemplates = $scope.uniqueTemplates.filter(function(template) {
|
|
return !template.label.includes("Room To Assign Emergency") && !template.label.includes("Room To Assign")
|
|
}), $scope.consultation.searchParameter && ($scope.uniqueTemplates = _.filter($scope.uniqueTemplates, function(template) {
|
|
return _.includes(template.label.toLowerCase(), $scope.consultation.searchParameter.toLowerCase())
|
|
})), $scope.uniqueTemplates
|
|
};
|
|
var showOnlyTemplatesFilledInProgram = function() {
|
|
spinner.forPromise(conceptSetService.getObsTemplatesForProgram($state.params.programUuid).success(function(data) {
|
|
data.results.length > 0 && data.results[0].mappings.length > 0 && (_.map(allConceptSections, function(conceptSection) {
|
|
conceptSection.isAdded = !1, conceptSection.alwaysShow = !1
|
|
}), _.map(data.results[0].mappings, function(template) {
|
|
var matchedTemplate = _.find(allConceptSections, {
|
|
uuid: template.uuid
|
|
});
|
|
matchedTemplate && (matchedTemplate.alwaysShow = !0)
|
|
}))
|
|
}))
|
|
},
|
|
createConceptSections = function(allTemplates) {
|
|
_.map(allTemplates, function(template) {
|
|
var conceptSetExtension = _.find(extensions, function(extension) {
|
|
return extension.extensionParams.conceptName === template.name.name
|
|
}) || {},
|
|
conceptSetConfig = configs[template.name.name] || {},
|
|
observationsForTemplate = getObservationsForTemplate(template);
|
|
observationsForTemplate && observationsForTemplate.length > 0 ? _.each(observationsForTemplate, function(observation) {
|
|
allConceptSections.push(new Bahmni.ConceptSet.ConceptSetSection(conceptSetExtension, $rootScope.currentUser, conceptSetConfig, [observation], template))
|
|
}) : allConceptSections.push(new Bahmni.ConceptSet.ConceptSetSection(conceptSetExtension, $rootScope.currentUser, conceptSetConfig, [], template))
|
|
})
|
|
},
|
|
collectObservationsFromConceptSets = function() {
|
|
$scope.consultation.observations = [], _.each($scope.consultation.selectedObsTemplate, function(conceptSetSection) {
|
|
conceptSetSection.observations[0] && $scope.consultation.observations.push(conceptSetSection.observations[0])
|
|
})
|
|
},
|
|
getObservationsForTemplate = function(template) {
|
|
return _.filter($scope.consultation.observations, function(observation) {
|
|
return !observation.formFieldPath && observation.concept.uuid === template.uuid
|
|
})
|
|
},
|
|
getSelectedObsTemplate = function(allConceptSections) {
|
|
return allConceptSections.filter(function(conceptSet) {
|
|
if (conceptSet.isAvailable($scope.context)) return !0
|
|
})
|
|
};
|
|
$scope.stopAutoClose = function($event) {
|
|
$event.stopPropagation()
|
|
}, $scope.addTemplate = function(template) {
|
|
$scope.scrollingEnabled = !0, $scope.showTemplatesList = !1;
|
|
var index = _.findLastIndex($scope.consultation.selectedObsTemplate, function(consultationTemplate) {
|
|
return consultationTemplate.label == template.label
|
|
});
|
|
if (index != -1 && $scope.consultation.selectedObsTemplate[index].allowAddMore) {
|
|
var clonedObj = template.clone();
|
|
clonedObj.klass = "active", $scope.consultation.selectedObsTemplate.splice(index + 1, 0, clonedObj)
|
|
} else template.toggle(), template.klass = "active", $scope.consultation.selectedObsTemplate.push(template);
|
|
$scope.consultation.searchParameter = "", messagingService.showMessage("info", $translate.instant("CLINICAL_TEMPLATE_ADDED_SUCCESS_KEY", {
|
|
label: template.label
|
|
}))
|
|
}, $scope.getNormalized = function(conceptName) {
|
|
return conceptName.replace(/['\.\s\(\)\/,\\]+/g, "_")
|
|
}, $scope.consultation.preSaveHandler.register("collectObservationsFromConceptSets", collectObservationsFromConceptSets);
|
|
var getObservationForms = function(observationsForms) {
|
|
var forms = [],
|
|
observations = $scope.consultation.observations || [];
|
|
return _.each(observationsForms, function(observationForm) {
|
|
var formUuid = observationForm.formUuid || observationForm.uuid,
|
|
formName = observationForm.name || observationForm.formName,
|
|
formVersion = observationForm.version || observationForm.formVersion;
|
|
forms.push(new Bahmni.ObservationForm(formUuid, $rootScope.currentUser, formName, formVersion, observations))
|
|
}), forms
|
|
};
|
|
init()
|
|
}]), angular.module("bahmni.clinical").controller("DrugOrderHistoryController", ["$scope", "$filter", "$stateParams", "activeDrugOrders", "treatmentConfig", "treatmentService", "spinner", "drugOrderHistoryHelper", "visitHistory", "$translate", "$rootScope", function($scope, $filter, $stateParams, activeDrugOrders, treatmentConfig, treatmentService, spinner, drugOrderHistoryHelper, visitHistory, $translate, $rootScope) {
|
|
var DrugOrderViewModel = Bahmni.Clinical.DrugOrderViewModel,
|
|
DateUtil = Bahmni.Common.Util.DateUtil,
|
|
currentVisit = visitHistory.activeVisit,
|
|
prescribedDrugOrders = [];
|
|
$scope.dispensePrivilege = Bahmni.Clinical.Constants.dispensePrivilege, $scope.scheduledDate = DateUtil.getDateWithoutTime(DateUtil.addDays(DateUtil.now(), 1));
|
|
var createPrescriptionGroups = function(activeAndScheduledDrugOrders) {
|
|
$scope.consultation.drugOrderGroups = [], createPrescribedDrugOrderGroups(), createRecentDrugOrderGroup(activeAndScheduledDrugOrders)
|
|
},
|
|
getPreviousVisitDrugOrders = function() {
|
|
var currentVisitIndex = _.findIndex($scope.consultation.drugOrderGroups, function(group) {
|
|
return group.isCurrentVisit
|
|
});
|
|
return $scope.consultation.drugOrderGroups[currentVisitIndex + 1] ? $scope.consultation.drugOrderGroups[currentVisitIndex + 1].drugOrders : []
|
|
},
|
|
sortOrderSetDrugsFollowedByDrugOrders = function(drugOrders, showOnlyActive) {
|
|
var orderSetOrdersAndDrugOrders = _.groupBy(drugOrders, function(drugOrder) {
|
|
return drugOrder.orderGroupUuid ? "orderSetOrders" : "drugOrders"
|
|
}),
|
|
refillableDrugOrders = drugOrderHistoryHelper.getRefillableDrugOrders(orderSetOrdersAndDrugOrders.drugOrders, getPreviousVisitDrugOrders(), showOnlyActive);
|
|
return _(orderSetOrdersAndDrugOrders.orderSetOrders).concat(refillableDrugOrders).uniqBy("uuid").value()
|
|
},
|
|
createRecentDrugOrderGroup = function(activeAndScheduledDrugOrders) {
|
|
var showOnlyActive = treatmentConfig.drugOrderHistoryConfig.showOnlyActive,
|
|
refillableGroup = {
|
|
label: $translate.instant("MEDICATION_RECENT_TAB"),
|
|
selected: !0,
|
|
drugOrders: sortOrderSetDrugsFollowedByDrugOrders(activeAndScheduledDrugOrders, showOnlyActive)
|
|
};
|
|
$scope.consultation.drugOrderGroups.unshift(refillableGroup), void 0 !== treatmentConfig.drugOrderHistoryConfig.numberOfVisits && null !== treatmentConfig.drugOrderHistoryConfig.numberOfVisits && 0 === treatmentConfig.drugOrderHistoryConfig.numberOfVisits && ($scope.consultation.drugOrderGroups = [$scope.consultation.drugOrderGroups[0]])
|
|
},
|
|
createPrescribedDrugOrderGroups = function() {
|
|
if (0 === prescribedDrugOrders.length) return [];
|
|
var drugOrderGroupedByDate = _.groupBy(prescribedDrugOrders, function(drugOrder) {
|
|
return DateUtil.parse(drugOrder.visit.startDateTime)
|
|
}),
|
|
createDrugOrder = function(drugOrder) {
|
|
return DrugOrderViewModel.createFromContract(drugOrder, treatmentConfig)
|
|
},
|
|
drugOrderGroups = _.map(drugOrderGroupedByDate, function(drugOrders, visitStartDate) {
|
|
return {
|
|
label: $filter("bahmniDate")(visitStartDate),
|
|
visitStartDate: DateUtil.parse(visitStartDate),
|
|
drugOrders: drugOrders.map(createDrugOrder),
|
|
isCurrentVisit: currentVisit && DateUtil.isSameDateTime(visitStartDate, currentVisit.startDatetime)
|
|
}
|
|
});
|
|
$scope.consultation.drugOrderGroups = $scope.consultation.drugOrderGroups.concat(drugOrderGroups), $scope.consultation.drugOrderGroups = _.sortBy($scope.consultation.drugOrderGroups, "visitStartDate").reverse()
|
|
};
|
|
$scope.stoppedOrderReasons = treatmentConfig.stoppedOrderReasonConcepts;
|
|
var init = function() {
|
|
var numberOfVisits = treatmentConfig.drugOrderHistoryConfig.numberOfVisits ? treatmentConfig.drugOrderHistoryConfig.numberOfVisits : 3;
|
|
spinner.forPromise(treatmentService.getPrescribedDrugOrders($stateParams.patientUuid, !0, numberOfVisits, $stateParams.dateEnrolled, $stateParams.dateCompleted).then(function(data) {
|
|
prescribedDrugOrders = data, createPrescriptionGroups($scope.consultation.activeAndScheduledDrugOrders)
|
|
}))
|
|
};
|
|
$scope.getOrderReasonConcept = function(drugOrder) {
|
|
if (drugOrder.orderReasonConcept) return drugOrder.orderReasonConcept.display || drugOrder.orderReasonConcept.name
|
|
}, $scope.toggleShowAdditionalInstructions = function(line) {
|
|
line.showAdditionalInstructions = !line.showAdditionalInstructions
|
|
}, $scope.drugOrderGroupsEmpty = function() {
|
|
return _.isEmpty($scope.consultation.drugOrderGroups)
|
|
}, $scope.isDrugOrderGroupEmpty = function(drugOrders) {
|
|
return _.isEmpty(drugOrders)
|
|
}, $scope.showEffectiveFromDate = function(visitStartDate, effectiveStartDate) {
|
|
return $filter("bahmniDate")(effectiveStartDate) !== $filter("bahmniDate")(visitStartDate)
|
|
}, $scope.refill = function(drugOrder) {
|
|
$rootScope.$broadcast("event:refillDrugOrder", drugOrder)
|
|
}, $scope.refillAll = function(drugOrders) {
|
|
$rootScope.$broadcast("event:refillDrugOrders", drugOrders)
|
|
}, $scope.revise = function(drugOrder, drugOrders) {
|
|
$scope.consultation.drugOrdersWithUpdatedOrderAttributes[drugOrder.uuid] && (delete $scope.consultation.drugOrdersWithUpdatedOrderAttributes[drugOrder.uuid], $scope.toggleDrugOrderAttribute(drugOrder.orderAttributes[0])), drugOrder.isEditAllowed && $rootScope.$broadcast("event:reviseDrugOrder", drugOrder, drugOrders)
|
|
}, $scope.updateFormConditions = function(drugOrder) {
|
|
var formCondition = Bahmni.ConceptSet.FormConditions.rules ? Bahmni.ConceptSet.FormConditions.rules["Medication Stop Reason"] : void 0;
|
|
formCondition ? drugOrder.orderReasonConcept ? formCondition(drugOrder, drugOrder.orderReasonConcept.name.name) || disableAndClearReasonText(drugOrder) : disableAndClearReasonText(drugOrder) : drugOrder.orderReasonNotesEnabled = !0
|
|
};
|
|
var disableAndClearReasonText = function(drugOrder) {
|
|
drugOrder.orderReasonText = null, drugOrder.orderReasonNotesEnabled = !1
|
|
};
|
|
$scope.discontinue = function(drugOrder) {
|
|
drugOrder.isDiscontinuedAllowed && ($rootScope.$broadcast("event:discontinueDrugOrder", drugOrder), $scope.updateFormConditions(drugOrder))
|
|
}, $scope.undoDiscontinue = function(drugOrder) {
|
|
$rootScope.$broadcast("event:undoDiscontinueDrugOrder", drugOrder)
|
|
}, $scope.shouldBeDisabled = function(drugOrder, orderAttribute) {
|
|
return !!drugOrder.isBeingEdited || (!drugOrder.isActive() || orderAttribute.obsUuid)
|
|
}, $scope.updateOrderAttribute = function(drugOrder, orderAttribute, valueToSet) {
|
|
$scope.shouldBeDisabled(drugOrder, orderAttribute) || ($scope.toggleDrugOrderAttribute(orderAttribute, valueToSet), $scope.consultation.drugOrdersWithUpdatedOrderAttributes[drugOrder.uuid] = drugOrder)
|
|
}, $scope.toggleDrugOrderAttribute = function(orderAttribute, valueToSet) {
|
|
orderAttribute.value = void 0 !== valueToSet ? valueToSet : !orderAttribute.value
|
|
}, $scope.getOrderAttributes = function() {
|
|
return treatmentConfig.orderAttributes
|
|
}, $scope.updateAllOrderAttributesByName = function(orderAttribute, drugOrderGroup) {
|
|
drugOrderGroup[orderAttribute.name] = drugOrderGroup[orderAttribute.name] || {}, drugOrderGroup[orderAttribute.name].selected = !drugOrderGroup[orderAttribute.name].selected, drugOrderGroup.drugOrders.forEach(function(drugOrder) {
|
|
var selectedOrderAttribute = getAttribute(drugOrder, orderAttribute.name);
|
|
$scope.updateOrderAttribute(drugOrder, selectedOrderAttribute, drugOrderGroup[orderAttribute.name].selected)
|
|
})
|
|
}, $scope.allOrderAttributesOfNameSet = function(drugOrderGroup, orderAttributeName) {
|
|
var allAttributesSelected = !0;
|
|
drugOrderGroup.drugOrders.forEach(function(drugOrder) {
|
|
var orderAttributeOfName = getAttribute(drugOrder, orderAttributeName);
|
|
$scope.shouldBeDisabled(drugOrder, orderAttributeOfName) || orderAttributeOfName.value || (allAttributesSelected = !1)
|
|
}), drugOrderGroup[orderAttributeName] = drugOrderGroup[orderAttributeName] || {}, drugOrderGroup[orderAttributeName].selected = allAttributesSelected
|
|
}, $scope.canUpdateAtLeastOneOrderAttributeOfName = function(drugOrderGroup, orderAttributeName) {
|
|
var canBeUpdated = !1;
|
|
return drugOrderGroup.drugOrders.forEach(function(drugOrder) {
|
|
var orderAttributeOfName = getAttribute(drugOrder, orderAttributeName);
|
|
$scope.shouldBeDisabled(drugOrder, orderAttributeOfName) || (canBeUpdated = !0)
|
|
}), canBeUpdated
|
|
}, $scope.getMinDateForDiscontinue = function(drugOrder) {
|
|
var minDate = DateUtil.today();
|
|
return DateUtil.isBeforeDate(drugOrder.effectiveStartDate, minDate) && (minDate = drugOrder.effectiveStartDate), DateUtil.getDateWithoutTime(minDate)
|
|
};
|
|
var getAttribute = function(drugOrder, attributeName) {
|
|
return _.find(drugOrder.orderAttributes, {
|
|
name: attributeName
|
|
})
|
|
};
|
|
init()
|
|
}]), angular.module("bahmni.clinical").controller("CustomDrugOrderHistoryController", ["$scope", "treatmentConfig", function($scope, treatmentConfig) {
|
|
var drugOrderHistoryConfig = treatmentConfig.drugOrderHistoryConfig || {};
|
|
$scope.treatmentConfig = treatmentConfig, $scope.drugOrderHistorySections = _.values(drugOrderHistoryConfig.sections)
|
|
}]), angular.module("bahmni.clinical").controller("LatestPrescriptionPrintController", ["$scope", "visitActionsService", "messagingService", function($scope, visitActionsService, messagingService) {
|
|
var print = function(visitStartDate, visitUuid) {
|
|
visitActionsService.printPrescription($scope.patient, visitStartDate, visitUuid), messagingService.showMessage("info", "Please close this tab.")
|
|
};
|
|
$scope.visitHistory.activeVisit ? print($scope.visitHistory.activeVisit.startDatetime, $scope.visitHistory.activeVisit.uuid) : messagingService.showMessage("error", "No Active visit found for this patient.")
|
|
}]), angular.module("bahmni.clinical").controller("BacteriologyController", ["$scope", "$rootScope", "contextChangeHandler", "spinner", "conceptSetService", "messagingService", "bacteriologyConceptSet", "appService", "retrospectiveEntryService", function($scope, $rootScope, contextChangeHandler, spinner, conceptSetService, messagingService, bacteriologyConceptSet, appService, retrospectiveEntryService) {
|
|
$scope.consultation.extensions = $scope.consultation.extensions ? $scope.consultation.extensions : {
|
|
mdrtbSpecimen: []
|
|
};
|
|
var initializeBacteriologyScope = function() {
|
|
$scope.savedSpecimens = $scope.consultation.savedSpecimens || $scope.consultation.extensions.mdrtbSpecimen, $scope.newSpecimens = $scope.consultation.newlyAddedSpecimens || [], $scope.deletedSpecimens = $scope.consultation.deletedSpecimens || []
|
|
};
|
|
initializeBacteriologyScope(), $scope.today = Bahmni.Common.Util.DateUtil.getDateWithoutTime(Bahmni.Common.Util.DateUtil.now()), $scope.isRetrospectiveMode = function() {
|
|
return !_.isEmpty(retrospectiveEntryService.getRetrospectiveEntry())
|
|
};
|
|
var init = function() {
|
|
appService.getAppDescriptor().getConfigValue("showSaveConfirmDialog") && $scope.$broadcast("event:pageUnload");
|
|
var additionalAttributes = _.find(bacteriologyConceptSet.setMembers, function(member) {
|
|
return "Bacteriology Attributes" === member.conceptClass.name
|
|
});
|
|
$scope.additionalAttributesConceptName = additionalAttributes && additionalAttributes.name.name;
|
|
var results = _.find(bacteriologyConceptSet.setMembers, function(member) {
|
|
return "Bacteriology Results" === member.conceptClass.name
|
|
});
|
|
$scope.resultsConceptName = results && results.name.name;
|
|
var sampleSource = _.find(bacteriologyConceptSet.setMembers, function(member) {
|
|
return "Specimen Sample Source" === member.name.name
|
|
});
|
|
$scope.allSamples = void 0 !== sampleSource && _.map(sampleSource.answers, function(answer) {
|
|
return (new Bahmni.Common.Domain.ConceptMapper).map(answer)
|
|
}), $scope.savedSpecimens && ($scope.savedSpecimens = _.sortBy($scope.savedSpecimens, "dateCollected").reverse()), 0 === $scope.newSpecimens.length && $scope.createNewSpecimen(), handleSampleTypeOther()
|
|
};
|
|
$scope.createNewSpecimen = function() {
|
|
var newSpecimen = new Bahmni.Clinical.Specimen(null, $scope.allSamples);
|
|
$scope.newSpecimens.push(newSpecimen)
|
|
};
|
|
var contextChange = function() {
|
|
$scope.consultation.newlyAddedSpecimens = $scope.newSpecimens, $scope.consultation.deletedSpecimens = $scope.deletedSpecimens, $scope.consultation.savedSpecimens = $scope.savedSpecimens;
|
|
var dirtySpecimens = _.filter($scope.newSpecimens, function(specimen) {
|
|
return specimen.isDirty()
|
|
});
|
|
return _.each(dirtySpecimens, function(dirtySpecimen) {
|
|
dirtySpecimen.hasIllegalDateCollected = !dirtySpecimen.dateCollected, dirtySpecimen.hasIllegalType = !dirtySpecimen.type, dirtySpecimen.hasIllegalTypeFreeText = !dirtySpecimen.typeFreeText
|
|
}), {
|
|
allow: void 0 === dirtySpecimens[0]
|
|
}
|
|
},
|
|
saveSpecimens = function() {
|
|
var savableSpecimens = _.filter($scope.newSpecimens, function(specimen) {
|
|
return !specimen.isEmpty() || specimen.voidIfEmpty()
|
|
});
|
|
savableSpecimens = savableSpecimens.concat($scope.deletedSpecimens);
|
|
var specimenMapper = new Bahmni.Clinical.SpecimenMapper,
|
|
specimens = [];
|
|
_.each(savableSpecimens, function(specimen) {
|
|
specimens.push(specimenMapper.mapSpecimenToObservation(specimen))
|
|
}), $scope.consultation.newlyAddedSpecimens = specimens, $scope.consultation.extensions.mdrtbSpecimen || ($scope.consultation.extensions.mdrtbSpecimen = [])
|
|
};
|
|
$scope.editSpecimen = function(specimen) {
|
|
$scope.savedSpecimens = _.without($scope.savedSpecimens, specimen), $scope.newSpecimens.push(new Bahmni.Clinical.Specimen(specimen, $scope.allSamples)), handleSampleTypeOther()
|
|
}, $scope.handleUpdate = function() {
|
|
handleSampleTypeOther()
|
|
}, $scope.deleteSpecimen = function(specimen) {
|
|
specimen.isExistingSpecimen() && (specimen.setMandatoryFieldsBeforeSavingVoidedSpecimen(), $scope.deletedSpecimens.push(specimen)), $scope.savedSpecimens = _.without($scope.savedSpecimens, specimen), $scope.newSpecimens = _.without($scope.newSpecimens, specimen), 0 === $scope.newSpecimens.length && $scope.createNewSpecimen()
|
|
}, $scope.getDisplayName = function(specimen) {
|
|
var type = specimen.type,
|
|
displayName = type && (type.shortName ? type.shortName : type.name);
|
|
return displayName === Bahmni.Clinical.Constants.bacteriologyConstants.otherSampleType && (displayName = specimen.typeFreeText), displayName
|
|
}, $scope.consultation.preSaveHandler.register("bacteriologySaveHandlerKey", saveSpecimens), $scope.consultation.postSaveHandler.register("bacteriologyPostSaveHandlerKey", initializeBacteriologyScope);
|
|
var handleSampleTypeOther = function() {
|
|
for (var specimen in $scope.newSpecimens) $scope.newSpecimens[specimen].type && $scope.newSpecimens[specimen].type.name === Bahmni.Clinical.Constants.bacteriologyConstants.otherSampleType ? ($scope.newSpecimens[specimen].showTypeFreeText = !0, $scope.freeText && ($scope.newSpecimens[specimen].typeFreeText = $scope.freeText)) : ($scope.newSpecimens[specimen].showTypeFreeText = !1, $scope.newSpecimens[specimen].type && ($scope.freeText = $scope.newSpecimens[specimen].typeFreeText, $scope.newSpecimens[specimen].typeFreeText = null))
|
|
};
|
|
contextChangeHandler.add(contextChange), init()
|
|
}]), Bahmni.Clinical.TabularLabOrderResults = function() {
|
|
var TabularLabOrderResults = function(tabularResult, accessionConfig) {
|
|
var self = this;
|
|
this.tabularResult = tabularResult;
|
|
var filterData = function(list, filteredOn) {
|
|
var indices = _.uniq(_.map(self.tabularResult.values, filteredOn));
|
|
return _.filter(list, function(element) {
|
|
return _.includes(indices, element.index)
|
|
})
|
|
},
|
|
init = function() {
|
|
if (accessionConfig && (accessionConfig.initialAccessionCount || accessionConfig.latestAccessionCount)) {
|
|
var tabularValues = _.groupBy(self.tabularResult.values, function(value) {
|
|
return new Date(value.accessionDateTime)
|
|
});
|
|
tabularValues = _.sortBy(tabularValues, function(value) {
|
|
return value[0].accessionDateTime
|
|
});
|
|
var initial = _.first(tabularValues, accessionConfig.initialAccessionCount || 0),
|
|
latest = _.last(tabularValues, accessionConfig.latestAccessionCount || 0);
|
|
self.tabularResult.values = _.flatten(_.union(initial, latest)), self.tabularResult.dates = filterData(self.tabularResult.dates, "dateIndex"), self.tabularResult.orders = filterData(self.tabularResult.orders, "testOrderIndex")
|
|
}
|
|
};
|
|
init(), this.getDateLabels = function() {
|
|
return this.tabularResult.dates.map(function(date) {
|
|
return moment(date.date, "DD-MMM-YYYY", !0).isValid() && (date.date = moment(date.date, "DD-MMM-YYYY").toDate()), date
|
|
})
|
|
}, this.getTestOrderLabels = function() {
|
|
return this.tabularResult.orders
|
|
}, this.hasRange = function(testOrderLabel) {
|
|
return testOrderLabel.minNormal && testOrderLabel.maxNormal
|
|
}, this.hasUnits = function(testOrderLabel) {
|
|
return void 0 != testOrderLabel.testUnitOfMeasurement && null != testOrderLabel.testUnitOfMeasurement
|
|
}, this.hasOrders = function() {
|
|
return this.tabularResult.orders.length > 0
|
|
}, this.getResult = function(dateLabel, testOrderLabel) {
|
|
var filteredResultValue = this.tabularResult.values.filter(function(value) {
|
|
return value.dateIndex === dateLabel.index && value.testOrderIndex === testOrderLabel.index
|
|
});
|
|
return 0 === filteredResultValue.length && (filteredResultValue = [{
|
|
result: " "
|
|
}]), filteredResultValue
|
|
}, this.hasUploadedFiles = function(dateLabel, testOrderLabel) {
|
|
return this.getResult(dateLabel, testOrderLabel).some(function(res) {
|
|
return res.uploadedFileName
|
|
})
|
|
}
|
|
};
|
|
return TabularLabOrderResults
|
|
}(), angular.module("bahmni.clinical").directive("investigationTableRow", function() {
|
|
var controller = function($scope) {
|
|
var urlFrom = function(fileName) {
|
|
return Bahmni.Common.Constants.labResultUploadedFileNameUrl + fileName
|
|
},
|
|
defaultParams = {
|
|
showDetailsButton: !0
|
|
};
|
|
$scope.params = angular.extend(defaultParams, $scope.params), $scope.hasNotes = function() {
|
|
return !(!$scope.test.notes && !$scope.test.showNotes)
|
|
}, $scope.showTestNotes = function() {
|
|
return $scope.hasNotes($scope.test)
|
|
}, $scope.test.showNotes = $scope.hasNotes(), $scope.test.showDetailsButton = $scope.params.showDetailsButton, $scope.test.labReportUrl = $scope.test.uploadedFileName ? urlFrom($scope.test.uploadedFileName) : null, $scope.toggle = function() {
|
|
$scope.test.showDetails = !$scope.test.showDetails
|
|
}, $scope.isValidResultToShow = function(result) {
|
|
return void 0 != result && null != result && "undefined" != result.toLowerCase(result) && "null" != result.toLowerCase(result)
|
|
}
|
|
};
|
|
return {
|
|
restrict: "A",
|
|
controller: controller,
|
|
scope: {
|
|
test: "=",
|
|
params: "="
|
|
},
|
|
templateUrl: "displaycontrols/investigationresults/views/investigationTableRow.html"
|
|
}
|
|
}), angular.module("bahmni.clinical").directive("investigationTable", function() {
|
|
var controller = function($scope) {
|
|
var defaultParams = {
|
|
noLabOrdersMessage: "NO_LAB_ORDERS_FOR_PATIENT_MESSAGE_KEY",
|
|
showNormalLabResults: !0,
|
|
showAccessionNotes: !0,
|
|
title: "Lab Investigations",
|
|
translationKey: "LAB_INVESTIGATIONS_KEY"
|
|
},
|
|
hasAbnormalTests = function(labOrderResult) {
|
|
if (labOrderResult.isPanel) {
|
|
var hasAbnormal = !1;
|
|
return labOrderResult.tests.forEach(function(test) {
|
|
test.abnormal && (hasAbnormal = !0)
|
|
}), hasAbnormal
|
|
}
|
|
return labOrderResult.abnormal
|
|
};
|
|
$scope.params = angular.extend(defaultParams, $scope.params), $scope.hasLabOrders = function() {
|
|
return !!($scope.accessions && $scope.accessions.length > 0) || $scope.$emit("no-data-present-event") && !1
|
|
}, $scope.shouldShowResults = function(labOrderResult) {
|
|
return $scope.params.showNormalLabResults || hasAbnormalTests(labOrderResult)
|
|
}, $scope.toggle = function(item) {
|
|
event.stopPropagation(), item.show = !item.show
|
|
}, $scope.getAccessionDetailsFrom = function(labOrderResults) {
|
|
var labResultLine = labOrderResults[0].isPanel ? labOrderResults[0].tests[0] : labOrderResults[0];
|
|
return {
|
|
accessionUuid: labResultLine.accessionUuid,
|
|
accessionDateTime: labResultLine.accessionDateTime,
|
|
accessionNotes: labResultLine.accessionNotes
|
|
}
|
|
}, $scope.toggleAccession = function(labOrderResults) {
|
|
labOrderResults.isOpen = !labOrderResults.isOpen
|
|
}, $scope.showAccessionNotes = function(labOrderResults) {
|
|
return $scope.getAccessionDetailsFrom(labOrderResults).accessionNotes && $scope.params.showAccessionNotes
|
|
}, $scope.$watch("accessions", function() {
|
|
$scope.accessions && $scope.accessions[0] && ($scope.accessions[0].isOpen = !0)
|
|
})
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
controller: controller,
|
|
scope: {
|
|
accessions: "=",
|
|
params: "="
|
|
},
|
|
templateUrl: "displaycontrols/investigationresults/views/investigationTable.html"
|
|
}
|
|
}), angular.module("bahmni.clinical").directive("investigationChart", function() {
|
|
var controller = function($scope) {
|
|
var defaultParams = {
|
|
noLabOrdersMessage: "No Lab Orders for this patient."
|
|
};
|
|
$scope.params = angular.extend(defaultParams, $scope.params), $scope.showChart = !1, $scope.toggleChart = function() {
|
|
$scope.showChart = !$scope.showChart
|
|
}, $scope.getUploadedFileUrl = function(uploadedFileName) {
|
|
return Bahmni.Common.Constants.labResultUploadedFileNameUrl + uploadedFileName
|
|
}
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
controller: controller,
|
|
scope: {
|
|
accessions: "=",
|
|
params: "="
|
|
},
|
|
templateUrl: "displaycontrols/investigationresults/views/investigationChart.html"
|
|
}
|
|
}), angular.module("bahmni.clinical").directive("investigationResults", ["labOrderResultService", "spinner", function(labOrderResultService, spinner) {
|
|
var controller = function($scope) {
|
|
var defaultParams = {
|
|
showTable: !0,
|
|
showChart: !0,
|
|
numberOfVisits: 1
|
|
};
|
|
$scope.params = angular.extend(defaultParams, $scope.params);
|
|
var params = {
|
|
patientUuid: $scope.params.patientUuid,
|
|
numberOfVisits: $scope.params.numberOfVisits,
|
|
visitUuids: $scope.params.visitUuids,
|
|
initialAccessionCount: $scope.params.initialAccessionCount,
|
|
latestAccessionCount: $scope.params.latestAccessionCount
|
|
};
|
|
$scope.initialization = labOrderResultService.getAllForPatient(params).then(function(results) {
|
|
$scope.investigationResults = results
|
|
})
|
|
},
|
|
link = function($scope, element) {
|
|
spinner.forPromise($scope.initialization, element)
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
controller: controller,
|
|
link: link,
|
|
templateUrl: "displaycontrols/investigationresults/views/investigationResults.html",
|
|
scope: {
|
|
params: "="
|
|
}
|
|
}
|
|
}]), angular.module("bahmni.clinical").directive("treatmentData", ["treatmentService", "appService", "spinner", "$stateParams", "$q", "treatmentConfig", function(treatmentService, appService, spinner, $stateParams, $q, treatmentConfig) {
|
|
var controller = function($scope) {
|
|
var Constants = Bahmni.Clinical.Constants,
|
|
defaultParams = {
|
|
showListView: !0,
|
|
showRoute: !1,
|
|
showDrugForm: !1,
|
|
numberOfVisits: 1
|
|
};
|
|
$scope.params = angular.extend(defaultParams, $scope.params);
|
|
var init = function() {
|
|
var getToDate = function() {
|
|
return $scope.visitSummary.stopDateTime || Bahmni.Common.Util.DateUtil.now()
|
|
},
|
|
programConfig = appService.getAppDescriptor().getConfigValue("program") || {},
|
|
startDate = null,
|
|
endDate = null,
|
|
getEffectiveOrdersOnly = !1;
|
|
return programConfig.showDetailsWithinDateRange && (startDate = $stateParams.dateEnrolled, endDate = $stateParams.dateCompleted, (startDate || endDate) && ($scope.params.showOtherActive = !1), getEffectiveOrdersOnly = !0), $q.all([treatmentConfig(), treatmentService.getPrescribedAndActiveDrugOrders($scope.params.patientUuid, $scope.params.numberOfVisits, $scope.params.showOtherActive, $scope.params.visitUuids || [], startDate, endDate, getEffectiveOrdersOnly)]).then(function(results) {
|
|
var config = results[0],
|
|
drugOrderResponse = results[1].data,
|
|
createDrugOrderViewModel = function(drugOrder) {
|
|
return Bahmni.Clinical.DrugOrderViewModel.createFromContract(drugOrder, config)
|
|
};
|
|
for (var key in drugOrderResponse) drugOrderResponse[key] = drugOrderResponse[key].map(createDrugOrderViewModel);
|
|
var groupedByVisit = _.groupBy(drugOrderResponse.visitDrugOrders, function(drugOrder) {
|
|
return drugOrder.visit.startDateTime
|
|
}),
|
|
treatmentSections = [];
|
|
for (var key in groupedByVisit) {
|
|
var values = Bahmni.Clinical.DrugOrder.Util.mergeContinuousTreatments(groupedByVisit[key]);
|
|
treatmentSections.push({
|
|
visitDate: key,
|
|
drugOrders: values
|
|
})
|
|
}
|
|
if (!_.isEmpty(drugOrderResponse[Constants.otherActiveDrugOrders])) {
|
|
var mergedOtherActiveDrugOrders = Bahmni.Clinical.DrugOrder.Util.mergeContinuousTreatments(drugOrderResponse[Constants.otherActiveDrugOrders]);
|
|
treatmentSections.push({
|
|
visitDate: Constants.otherActiveDrugOrders,
|
|
drugOrders: mergedOtherActiveDrugOrders
|
|
})
|
|
}
|
|
$scope.treatmentSections = treatmentSections, $scope.visitSummary && ($scope.ipdDrugOrders = Bahmni.Clinical.VisitDrugOrder.createFromDrugOrders(drugOrderResponse.visitDrugOrders, $scope.visitSummary.startDateTime, getToDate()))
|
|
})
|
|
};
|
|
$scope.initialization = init()
|
|
},
|
|
link = function($scope, element) {
|
|
spinner.forPromise($scope.initialization, element)
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
controller: controller,
|
|
link: link,
|
|
scope: {
|
|
params: "=",
|
|
visitSummary: "=?"
|
|
},
|
|
templateUrl: "displaycontrols/treatmentData/views/treatmentData.html"
|
|
}
|
|
}]), angular.module("bahmni.clinical").directive("treatmentTable", function() {
|
|
var controller = function($scope) {
|
|
$scope.isOtherActiveSection = function(dateString) {
|
|
return dateString === Bahmni.Clinical.Constants.otherActiveDrugOrders
|
|
}, $scope.isDataPresent = function() {
|
|
return !$scope.drugOrderSections || 0 != $scope.drugOrderSections.length || $scope.$emit("no-data-present-event") && !1
|
|
}
|
|
};
|
|
return {
|
|
templateUrl: "displaycontrols/treatmentData/views/treatmentTable.html",
|
|
scope: {
|
|
drugOrderSections: "=",
|
|
params: "="
|
|
},
|
|
controller: controller
|
|
}
|
|
}), angular.module("bahmni.clinical").directive("treatmentChart", function() {
|
|
var controller = function($scope) {
|
|
$scope.atLeastOneDrugForDay = function(day) {
|
|
var atLeastOneDrugForDay = !1;
|
|
return $scope.ipdDrugOrders.getIPDDrugs().forEach(function(drug) {
|
|
drug.isActiveOnDate(day.date) && (atLeastOneDrugForDay = !0)
|
|
}), atLeastOneDrugForDay
|
|
}, $scope.getVisitStopDateTime = function() {
|
|
return $scope.visitSummary.stopDateTime || Bahmni.Common.Util.DateUtil.now()
|
|
}
|
|
};
|
|
return {
|
|
templateUrl: "displaycontrols/treatmentData/views/treatmentChart.html",
|
|
scope: {
|
|
ipdDrugOrders: "=",
|
|
visitSummary: "=",
|
|
params: "="
|
|
},
|
|
controller: controller
|
|
}
|
|
}), angular.module("bahmni.clinical").directive("treatmentTableRow", function() {
|
|
var controller = function($scope) {
|
|
$scope.showDetails = !1, void 0 === $scope.params.showProvider && ($scope.params.showProvider = !0), $scope.toggle = function() {
|
|
$scope.showDetails = !$scope.showDetails
|
|
}
|
|
};
|
|
return {
|
|
restrict: "A",
|
|
controller: controller,
|
|
scope: {
|
|
drugOrder: "=",
|
|
params: "="
|
|
},
|
|
templateUrl: "displaycontrols/treatmentData/views/treatmentTableRow.html"
|
|
}
|
|
}), Bahmni.Clinical.DrugOrder.Util = {
|
|
mergeContinuousTreatments: function(continuousDrugOrders) {
|
|
var sortedDrugOrders = _.sortBy(continuousDrugOrders, "effectiveStartDate"),
|
|
drugOrders = [];
|
|
return sortedDrugOrders.forEach(function(drugOrder) {
|
|
drugOrder.span = {};
|
|
var areValuesEqual = function(value1, value2) {
|
|
return "boolean" == typeof value1 && "boolean" == typeof value2 ? value1 === value2 : value1 === value2 || _.isEmpty(value1) && _.isEmpty(value2)
|
|
},
|
|
foundDrugOrder = _.find(drugOrders, function(existingOrder) {
|
|
return areValuesEqual(existingOrder.drugNonCoded, drugOrder.drugNonCoded) && existingOrder.drug && drugOrder.drug && areValuesEqual(existingOrder.drug.uuid, drugOrder.drug.uuid) && areValuesEqual(existingOrder.instructions, drugOrder.instructions) && areValuesEqual(existingOrder.getDoseInformation(), drugOrder.getDoseInformation()) && areValuesEqual(existingOrder.route, drugOrder.route) && areValuesEqual(existingOrder.additionalInstructions, drugOrder.additionalInstructions) && areValuesEqual(existingOrder.asNeeded, drugOrder.asNeeded) && areValuesEqual(existingOrder.isDiscontinuedOrStopped(), drugOrder.isDiscontinuedOrStopped()) && Bahmni.Common.Util.DateUtil.diffInDaysRegardlessOfTime(new Date(existingOrder.lastStopDate), new Date(drugOrder.scheduledDate)) <= 1
|
|
});
|
|
foundDrugOrder ? (foundDrugOrder.span.hasOwnProperty(drugOrder.durationUnit) ? foundDrugOrder.span[drugOrder.durationUnit] += drugOrder.duration : foundDrugOrder.span[drugOrder.durationUnit] = drugOrder.duration, foundDrugOrder.lastStopDate = drugOrder.effectiveStopDate) : (drugOrder.span[drugOrder.durationUnit] = drugOrder.duration, drugOrder.lastStopDate = drugOrder.effectiveStopDate, drugOrders.push(drugOrder))
|
|
}), drugOrders
|
|
},
|
|
sortDrugOrders: function(activeAndScheduledDrugOrders) {
|
|
var descendingOrderFactor = -1;
|
|
return Bahmni.Clinical.DrugOrder.Util.sortOrders(activeAndScheduledDrugOrders, descendingOrderFactor)
|
|
},
|
|
sortDrugOrdersInChronologicalOrder: function(activeAndScheduledDrugOrders) {
|
|
var ascendingOrderFactor = 1;
|
|
return Bahmni.Clinical.DrugOrder.Util.sortOrders(activeAndScheduledDrugOrders, ascendingOrderFactor)
|
|
},
|
|
sortOrders: function(drugOrders, sortOrderFactor) {
|
|
if (_.isEmpty(drugOrders)) return [];
|
|
var DateUtil = Bahmni.Common.Util.DateUtil;
|
|
return drugOrders.sort(function(drug1, drug2) {
|
|
var timeDifference = DateUtil.diffInSeconds(drug1.effectiveStartDate, drug2.effectiveStartDate);
|
|
return DateUtil.isSameDate(drug1.effectiveStartDate, drug2.effectiveStartDate) ? 0 === timeDifference ? drug1.orderNumber - drug2.orderNumber : timeDifference : timeDifference * sortOrderFactor
|
|
})
|
|
}
|
|
}, angular.module("bahmni.clinical").directive("visitsTable", ["patientVisitHistoryService", "conceptSetService", "spinner", "$state", "$q", function(patientVisitHistoryService, conceptSetService, spinner, $state, $q) {
|
|
var controller = function($scope) {
|
|
var emitNoDataPresentEvent = function() {
|
|
$scope.$emit("no-data-present-event")
|
|
};
|
|
$scope.openVisit = function(visit) {
|
|
$scope.$parent.closeThisDialog && $scope.$parent.closeThisDialog("closing modal"), $state.go("patient.dashboard.visit", {
|
|
visitUuid: visit.uuid
|
|
})
|
|
}, $scope.hasVisits = function() {
|
|
return $scope.visits && $scope.visits.length > 0
|
|
}, $scope.params = angular.extend({
|
|
maximumNoOfVisits: 4,
|
|
title: "Visits"
|
|
}, $scope.params), $scope.noVisitsMessage = "No Visits for this patient.", $scope.toggle = function(visit) {
|
|
visit.isOpen = !visit.isOpen, visit.cacheOpenedHtml = !0
|
|
}, $scope.filteredObservations = function(observation, observationTemplates) {
|
|
var observationTemplateArray = [];
|
|
for (var observationTemplateIndex in observationTemplates) observationTemplateArray.push(observationTemplates[observationTemplateIndex].display);
|
|
var obsArrayFiltered = [];
|
|
for (var ob in observation) _.includes(observationTemplateArray, observation[ob].concept.display) && obsArrayFiltered.push(observation[ob]);
|
|
return obsArrayFiltered
|
|
}, $scope.editConsultation = function(encounter) {
|
|
showNotApplicablePopup(), $scope.$parent.closeThisDialog && $scope.$parent.closeThisDialog("closing modal"), $state.go("patient.dashboard.show.observations", {
|
|
conceptSetGroupName: "observations",
|
|
encounterUuid: encounter.uuid
|
|
})
|
|
}, $scope.getDisplayName = function(data) {
|
|
var concept = data.concept,
|
|
displayName = data.concept.displayString;
|
|
return concept.names && 1 === concept.names.length && "" !== concept.names[0].name ? displayName = concept.names[0].name : concept.names && 2 === concept.names.length && (displayName = _.find(concept.names, {
|
|
conceptNameType: "SHORT"
|
|
}).name), displayName
|
|
}, $scope.getProviderDisplayName = function(encounter) {
|
|
return encounter.encounterProviders.length > 0 ? encounter.encounterProviders[0].provider.display : null
|
|
};
|
|
var getVisits = function() {
|
|
return patientVisitHistoryService.getVisitHistory($scope.patientUuid)
|
|
},
|
|
init = function() {
|
|
return $q.all([getVisits()]).then(function(results) {
|
|
$scope.visits = results[0].visits, $scope.patient = {
|
|
uuid: $scope.patientUuid
|
|
}, $scope.hasVisits() || emitNoDataPresentEvent()
|
|
})
|
|
};
|
|
$scope.initialization = init(), $scope.params = angular.extend({
|
|
maximumNoOfVisits: 4,
|
|
title: "Visits"
|
|
}, $scope.params), $scope.noVisitsMessage = "No Visits for this patient."
|
|
},
|
|
link = function($scope, element) {
|
|
spinner.forPromise($scope.initialization, element)
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
link: link,
|
|
controller: controller,
|
|
templateUrl: "displaycontrols/allvisits/views/visitsTable.html",
|
|
scope: {
|
|
params: "=",
|
|
patientUuid: "="
|
|
}
|
|
}
|
|
}]), angular.module("bahmni.clinical").directive("observationData", [function() {
|
|
var controller = function($scope) {
|
|
$scope.hasGroupMembers = function() {
|
|
return $scope.observation.groupMembers && $scope.observation.groupMembers.length > 0
|
|
}, $scope.getDisplayValue = function() {
|
|
return $scope.observation.value ? $scope.observation.value.display || $scope.observation.value : null
|
|
}
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
template: "<ng-include src=\"'../clinical/displaycontrols/observationData/views/observationData.html'\" />",
|
|
scope: {
|
|
observation: "="
|
|
},
|
|
controller: controller
|
|
}
|
|
}]), angular.module("bahmni.clinical").directive("observationGraph", ["appService", "observationsService", "patientService", "conceptSetService", "$q", "spinner", "$translate", function(appService, observationsService, patientService, conceptSetService, $q, spinner, $translate) {
|
|
var generateGraph = function($scope, element, config, observationGraphModel) {
|
|
var bindToElement = document.getElementById($scope.graphId),
|
|
graphWidth = $(element).parent().width(),
|
|
chart = Bahmni.Graph.c3Chart.create();
|
|
chart.render(bindToElement, graphWidth, config, observationGraphModel)
|
|
},
|
|
link = function($scope, element) {
|
|
if ($scope.graphId = "graph" + $scope.$id, $scope.params) {
|
|
var config = new Bahmni.Clinical.ObservationGraphConfig($scope.params.config);
|
|
config.validate($scope.params.title);
|
|
var promises = [],
|
|
numberOfLevels = 1,
|
|
fields = ["uuid", "name", "names", "hiNormal", "lowNormal", "units", "datatype"],
|
|
customRepresentation = Bahmni.ConceptSet.CustomRepresentationBuilder.build(fields, "setMembers", numberOfLevels),
|
|
conceptValue = conceptSetService.getConcept({
|
|
name: config.getAllConcepts(),
|
|
v: "custom:" + customRepresentation
|
|
});
|
|
promises.push(conceptValue);
|
|
var observationsPromise = observationsService.fetch($scope.patientUuid, config.getAllConcepts(), null, config.numberOfVisits, $scope.visitUuid, null, !1);
|
|
promises.push(observationsPromise), config.displayForAge() && promises.push(patientService.getPatient($scope.patientUuid)), config.shouldDrawReferenceLines() && promises.push(appService.loadCsvFileFromConfig(config.getReferenceDataFileName()));
|
|
var checkWhetherYAxisIsNumericDataType = function(yAxisConceptDetails) {
|
|
if ("Numeric" !== yAxisConceptDetails.datatype.name) {
|
|
var errorMsg = $translate.instant(Bahmni.Clinical.Constants.errorMessages.conceptNotNumeric).replace(":conceptName", yAxisConceptDetails.name.name).replace(":placeErrorAccurred", $scope.params.title + " config in growthChartReference.csv");
|
|
throw new Error(errorMsg)
|
|
}
|
|
};
|
|
spinner.forPromise($q.all(promises).then(function(results) {
|
|
var referenceLines, yAxisConceptDetails = results[0].data && results[0].data.results && results[0].data.results[0],
|
|
observations = results[1].data,
|
|
patient = results[2] && results[2].data.person;
|
|
if (config.shouldDrawReferenceLines()) {
|
|
checkWhetherYAxisIsNumericDataType(yAxisConceptDetails);
|
|
var referenceData = results[3].data,
|
|
ageInMonths = Bahmni.Common.Util.AgeUtil.differenceInMonths(patient.birthdate),
|
|
yAxisUnit = yAxisConceptDetails.units,
|
|
observationGraphReferenceModel = new Bahmni.Clinical.ObservationGraphReference(referenceData, config, patient.gender, ageInMonths, yAxisUnit);
|
|
observationGraphReferenceModel.validate(), referenceLines = observationGraphReferenceModel.createObservationGraphReferenceLines()
|
|
}
|
|
if (0 === observations.length) return void $scope.$emit("no-data-present-event");
|
|
void 0 !== yAxisConceptDetails && (config.lowNormal = yAxisConceptDetails.lowNormal, config.hiNormal = yAxisConceptDetails.hiNormal);
|
|
var model = Bahmni.Clinical.ObservationGraph.create(observations, patient, config, referenceLines);
|
|
generateGraph($scope, element, config, model)
|
|
}), element)
|
|
}
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
templateUrl: "displaycontrols/graph/views/observationGraph.html",
|
|
scope: {
|
|
params: "=",
|
|
visitUuid: "=",
|
|
patientUuid: "="
|
|
},
|
|
link: link
|
|
}
|
|
}]),
|
|
function() {
|
|
Bahmni = Bahmni || {}, Bahmni.Clinical = Bahmni.Clinical || {}, Bahmni.Clinical.ObservationGraph = function(model) {
|
|
angular.extend(this, model)
|
|
};
|
|
var fixCaseMismatchIssues = function(config, observations) {
|
|
var conceptNamesFromConfig = config.yAxisConcepts.slice(0);
|
|
conceptNamesFromConfig.push(config.xAxisConcept), _.each(observations, function(obs) {
|
|
obs.concept.name = _.find(conceptNamesFromConfig, function(configConceptName) {
|
|
return configConceptName.toLowerCase() === obs.concept.name.toLowerCase()
|
|
})
|
|
})
|
|
},
|
|
createObservationPoint = function(config, obs, xAxisValues) {
|
|
var observation = {};
|
|
return observation[config.xAxisConcept] = xAxisValues, observation[obs.concept.name] = obs.value, observation
|
|
},
|
|
findMatchingLine = function(lines, obs) {
|
|
return _(lines).find(function(line) {
|
|
return line.name === obs.concept.name
|
|
})
|
|
};
|
|
Bahmni.Clinical.ObservationGraph.create = function(allObservations, person, config, referenceLines) {
|
|
fixCaseMismatchIssues(config, allObservations);
|
|
var yAxisObservations = _.filter(allObservations, function(obs) {
|
|
return obs.concept.name !== config.xAxisConcept
|
|
}),
|
|
xAxisObservations = _.filter(allObservations, function(obs) {
|
|
return obs.concept.name === config.xAxisConcept
|
|
}),
|
|
lines = _(yAxisObservations).uniqBy(function(item) {
|
|
return item.concept.name + item.concept.units
|
|
}).map(function(item) {
|
|
return new Bahmni.Clinical.ObservationGraphLine({
|
|
name: item.concept.name,
|
|
units: item.concept.units,
|
|
values: []
|
|
})
|
|
}).value();
|
|
if (_.forEach(yAxisObservations, function(yAxisObs) {
|
|
var xValue;
|
|
if (config.displayForObservationDateTime()) config.type = "timeseries", xValue = Bahmni.Common.Util.DateUtil.parseDatetime(yAxisObs.observationDateTime).toDate();
|
|
else if (config.displayForAge()) xValue = Bahmni.Common.Util.AgeUtil.differenceInMonths(person.birthdate, yAxisObs.observationDateTime);
|
|
else {
|
|
config.type = "indexed";
|
|
var matchingObservation = _.find(xAxisObservations, function(xObs) {
|
|
return yAxisObs.observationDateTime === xObs.observationDateTime
|
|
});
|
|
xValue = matchingObservation ? matchingObservation.value : void 0
|
|
}
|
|
if (void 0 !== xValue) {
|
|
var line = findMatchingLine(lines, yAxisObs),
|
|
observationPoint = createObservationPoint(config, yAxisObs, xValue);
|
|
line.addPoint(observationPoint)
|
|
}
|
|
}), void 0 !== referenceLines) {
|
|
lines = lines.concat(referenceLines);
|
|
var referenceLinesYAxisConcepts = _.map(referenceLines, "name");
|
|
config.yAxisConcepts = config.yAxisConcepts.concat(referenceLinesYAxisConcepts)
|
|
}
|
|
return new Bahmni.Clinical.ObservationGraph(lines)
|
|
}
|
|
}(),
|
|
function() {
|
|
Bahmni = Bahmni || {}, Bahmni.Clinical = Bahmni.Clinical || {}, Bahmni.Clinical.ObservationGraphLine = function(proto) {
|
|
angular.extend(this, proto)
|
|
}, Bahmni.Clinical.ObservationGraphLine.prototype.addPoint = function(point) {
|
|
point[this.name] && this.values.push(point)
|
|
}
|
|
}(),
|
|
function() {
|
|
Bahmni = Bahmni || {}, Bahmni.Clinical = Bahmni.Clinical || {}, Bahmni.Clinical.ObservationGraphReference = function(csvString, config, gender, ageInMonths, yAxisUnit) {
|
|
var that = this,
|
|
monthBuffer = 1;
|
|
this.config = config, this.csvString = csvString, this.yAxisUnit = yAxisUnit, this.referenceChartValues = asMatrix(this.csvString), this.header = this.referenceChartValues.shift(), this.ageColumnIndex = _.findIndex(this.header, function(columnName) {
|
|
return columnName.toLowerCase() === Bahmni.Clinical.Constants.concepts.age.toLowerCase()
|
|
}), this.genderColumnIndex = _.findIndex(this.header, function(columnName) {
|
|
return columnName.toLowerCase() === Bahmni.Clinical.Constants.gender.toLowerCase()
|
|
});
|
|
var maxNoOfMonths = ageInMonths + monthBuffer;
|
|
this.referenceChartValues = _.filter(this.referenceChartValues, function(value) {
|
|
return value[that.genderColumnIndex] === gender && (void 0 === maxNoOfMonths || value[that.ageColumnIndex] <= maxNoOfMonths)
|
|
})
|
|
};
|
|
var asMatrix = function(csvString) {
|
|
return _.map(csvString.split("\n"), function(line) {
|
|
return line.split(",")
|
|
})
|
|
};
|
|
Bahmni.Clinical.ObservationGraphReference.prototype.createValues = function(columnName) {
|
|
var that = this;
|
|
return _.map(this.referenceChartValues, function(rowOfValues) {
|
|
var point = {};
|
|
return point[columnName] = rowOfValues[that.header.indexOf(columnName)], point[Bahmni.Clinical.Constants.concepts.age] = rowOfValues[that.ageColumnIndex], point
|
|
})
|
|
}, Bahmni.Clinical.ObservationGraphReference.prototype.createObservationGraphReferenceLines = function() {
|
|
var that = this,
|
|
headersToBeExcluded = function(column, index) {
|
|
return index === that.genderColumnIndex || index === that.ageColumnIndex
|
|
},
|
|
newObservationGraphLine = function(columnName) {
|
|
return new Bahmni.Clinical.ObservationGraphLine({
|
|
name: columnName,
|
|
reference: !0,
|
|
unit: that.yAxisUnit,
|
|
values: that.createValues(columnName)
|
|
})
|
|
};
|
|
return _(this.header).reject(headersToBeExcluded).map(newObservationGraphLine).value()
|
|
}, Bahmni.Clinical.ObservationGraphReference.prototype.validate = function() {
|
|
if (this.ageColumnIndex === -1) throw new Error("Age column is not defined in reference lines csv: " + this.config.getReferenceDataFileName());
|
|
if (this.genderColumnIndex === -1) throw new Error("Gender column is not defined in reference lines csv: " + this.config.getReferenceDataFileName())
|
|
}
|
|
}(),
|
|
function() {
|
|
Bahmni = Bahmni || {}, Bahmni.Clinical = Bahmni.Clinical || {}, Bahmni.Clinical.ObservationGraphConfig = function(config) {
|
|
angular.extend(this, config), this.shouldDrawReferenceLines() && (this.xAxisConcept = Bahmni.Clinical.Constants.concepts.age)
|
|
};
|
|
var OBSERVATION_DATETIME = "observationdatetime",
|
|
configPrototype = Bahmni.Clinical.ObservationGraphConfig.prototype;
|
|
configPrototype.validate = function(title) {
|
|
if (!this.yAxisConcepts || 0 === this.yAxisConcepts.length) throw new Error("y axis not defined for graph: " + title);
|
|
if (!this.xAxisConcept && !this.shouldDrawReferenceLines()) throw new Error("x axis not defined for graph: " + title)
|
|
}, configPrototype.displayForConcept = function() {
|
|
return !(this.displayForAge() || this.displayForObservationDateTime())
|
|
}, configPrototype.displayForAge = function() {
|
|
return this.xAxisConcept.toLowerCase() === Bahmni.Clinical.Constants.concepts.age.toLowerCase()
|
|
}, configPrototype.displayForObservationDateTime = function() {
|
|
return this.xAxisConcept.toLowerCase() === OBSERVATION_DATETIME
|
|
}, configPrototype.getAllConcepts = function() {
|
|
var concepts = this.yAxisConcepts.slice(0);
|
|
return this.displayForConcept() && concepts.push(this.xAxisConcept), concepts
|
|
}, configPrototype.shouldDrawReferenceLines = function() {
|
|
return void 0 !== this.referenceData && this.yAxisConcepts && 1 === this.yAxisConcepts.length
|
|
}, configPrototype.getReferenceDataFileName = function() {
|
|
return this.referenceData
|
|
}
|
|
}(), angular.module("bahmni.clinical").directive("patientContext", ["$state", "$translate", "$sce", "patientService", "spinner", "appService", function($state, $translate, $sce, patientService, spinner, appService) {
|
|
var controller = function($scope, $rootScope) {
|
|
var patientContextConfig = appService.getAppDescriptor().getConfigValue("patientContext") || {};
|
|
$scope.initPromise = patientService.getPatientContext($scope.patient.uuid, $state.params.enrollment, patientContextConfig.personAttributes, patientContextConfig.programAttributes, patientContextConfig.additionalPatientIdentifiers), $scope.initPromise.then(function(response) {
|
|
$scope.patientContext = response.data;
|
|
var programAttributes = $scope.patientContext.programAttributes,
|
|
personAttributes = $scope.patientContext.personAttributes;
|
|
convertBooleanValuesToEnglish(personAttributes), convertBooleanValuesToEnglish(programAttributes);
|
|
var preferredIdentifier = patientContextConfig.preferredIdentifier;
|
|
preferredIdentifier && (programAttributes[preferredIdentifier] ? ($scope.patientContext.identifier = programAttributes[preferredIdentifier].value, delete programAttributes[preferredIdentifier]) : personAttributes[preferredIdentifier] && ($scope.patientContext.identifier = personAttributes[preferredIdentifier].value, delete personAttributes[preferredIdentifier])), $scope.showNameAndImage = void 0 === $scope.showNameAndImage || $scope.showNameAndImage, $scope.showNameAndImage && ($scope.patientContext.image = Bahmni.Common.Constants.patientImageUrlByPatientUuid + $scope.patientContext.uuid), $scope.patientContext.gender = $rootScope.genderMap[$scope.patientContext.gender]
|
|
})
|
|
},
|
|
link = function($scope, element) {
|
|
spinner.forPromise($scope.initPromise, element)
|
|
},
|
|
convertBooleanValuesToEnglish = function(attributes) {
|
|
var booleanMap = {
|
|
"true": "Yes",
|
|
"false": "No"
|
|
};
|
|
_.forEach(attributes, function(value) {
|
|
value.value = booleanMap[value.value] ? booleanMap[value.value] : value.value
|
|
})
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
templateUrl: "displaycontrols/patientContext/views/patientContext.html",
|
|
scope: {
|
|
patient: "=",
|
|
showNameAndImage: "=?"
|
|
},
|
|
controller: controller,
|
|
link: link
|
|
}
|
|
}]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.DisplayControl = Bahmni.Common.DisplayControl || {}, Bahmni.Common.DisplayControl.AdmissionDetails = Bahmni.Common.DisplayControl.AdmissionDetails || {}, angular.module("bahmni.common.displaycontrol.admissiondetails", []), angular.module("bahmni.common.displaycontrol.admissiondetails").directive("admissionDetails", ["bedService", function(bedService) {
|
|
var controller = function($scope) {
|
|
$scope.showDetailsButton = function(encounter) {
|
|
return $scope.params && $scope.params.showDetailsButton && !encounter.notes
|
|
}, $scope.toggle = function(element) {
|
|
element.show = !element.show
|
|
}, init($scope)
|
|
},
|
|
isReady = function($scope) {
|
|
return !_.isUndefined($scope.patientUuid) && !_.isUndefined($scope.visitSummary)
|
|
},
|
|
onReady = function($scope) {
|
|
var visitUuid = _.get($scope.visitSummary, "uuid");
|
|
bedService.getAssignedBedForPatient($scope.patientUuid, visitUuid).then(function(bedDetails) {
|
|
$scope.bedDetails = bedDetails
|
|
})
|
|
},
|
|
init = function($scope) {
|
|
var stopWatching = $scope.$watchGroup(["patientUuid", "visitSummary"], function() {
|
|
isReady($scope) && (stopWatching(), onReady($scope))
|
|
});
|
|
$scope.isDataPresent = function() {
|
|
return !(!$scope.visitSummary || !$scope.visitSummary.admissionDetails && !$scope.visitSummary.dischargeDetails) || $scope.$emit("no-data-present-event") && !1
|
|
}
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
controller: controller,
|
|
templateUrl: "../common/displaycontrols/admissiondetails/views/admissionDetails.html",
|
|
scope: {
|
|
params: "=",
|
|
patientUuid: "=",
|
|
visitSummary: "="
|
|
}
|
|
}
|
|
}]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.DisplayControl = Bahmni.Common.DisplayControl || {}, Bahmni.Common.DisplayControl.DrugOrderDetails = Bahmni.Common.DisplayControl.DrugOrderDetails || {}, angular.module("bahmni.common.displaycontrol.drugOrderDetails", []), angular.module("bahmni.common.displaycontrol.drugOrderDetails").directive("drugOrderDetails", ["treatmentService", "spinner", "treatmentConfig", "$q", function(treatmentService, spinner, treatmentConfig, $q) {
|
|
var controller = function($scope) {
|
|
var init = function() {
|
|
return $q.all([treatmentService.getAllDrugOrdersFor($scope.patient.uuid, $scope.section.dashboardConfig.drugConceptSet, void 0, void 0, $scope.enrollment), treatmentConfig()]).then(function(results) {
|
|
var createDrugOrder = function(drugOrder) {
|
|
var treatmentConfig = results[1];
|
|
return Bahmni.Clinical.DrugOrderViewModel.createFromContract(drugOrder, treatmentConfig)
|
|
},
|
|
drugOrderResponse = results[0],
|
|
drugOrders = drugOrderResponse.map(createDrugOrder);
|
|
$scope.drugOrders = sortOrders(drugOrders), _.isEmpty($scope.drugOrders) && $scope.$emit("no-data-present-event")
|
|
})
|
|
};
|
|
$scope.columnHeaders = ["DRUG_DETAILS_DRUG_NAME", "DRUG_DETAILS_DOSE_INFO", "DRUG_DETAILS_QUANTITY_TEXT", "DRUG_DETAILS_ROUTE", "DRUG_DETAILS_FREQUENCY", "DRUG_DETAILS_START_DATE", "DRUG_DETAILS_INSTRUCTIONS_TEXT", "DRUG_DETAILS_ADDITIONAL_INSTRUCTIONS"], $scope.showDetails = !1, $scope.toggle = function(drugOrder) {
|
|
drugOrder.showDetails = !drugOrder.showDetails
|
|
};
|
|
var sortOrders = function(response) {
|
|
var drugOrderUtil = Bahmni.Clinical.DrugOrder.Util,
|
|
sortedDrugOrders = [];
|
|
if ($scope.section.dashboardConfig.showOnlyActive) {
|
|
var activeAndScheduled = _.filter(response, function(order) {
|
|
return order.isActive() || order.isScheduled()
|
|
});
|
|
sortedDrugOrders.push(drugOrderUtil.sortDrugOrdersInChronologicalOrder(activeAndScheduled))
|
|
} else sortedDrugOrders.push(drugOrderUtil.sortDrugOrdersInChronologicalOrder(response));
|
|
return _.flatten(sortedDrugOrders)
|
|
};
|
|
$scope.initialization = init()
|
|
},
|
|
link = function($scope, element) {
|
|
spinner.forPromise($scope.initialization, element)
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
controller: controller,
|
|
link: link,
|
|
scope: {
|
|
section: "=",
|
|
patient: "=",
|
|
enrollment: "="
|
|
},
|
|
templateUrl: "../common/displaycontrols/drugOrderDetails/views/drugOrderDetails.html"
|
|
}
|
|
}]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.DisplayControl = Bahmni.Common.DisplayControl || {}, Bahmni.Common.DisplayControl.DrugOrdersSection = Bahmni.Common.DisplayControl.DrugOrdersSection || {}, angular.module("bahmni.common.displaycontrol.drugOrdersSection", []), angular.module("bahmni.common.displaycontrol.drugOrdersSection").directive("drugOrdersSection", ["treatmentService", "spinner", "$rootScope", function(treatmentService, spinner, $rootScope) {
|
|
var controller = function($scope) {
|
|
var DateUtil = Bahmni.Common.Util.DateUtil;
|
|
$scope.showAdditionalInstructions = !0, $scope.toggle = !0, $scope.toggleDisplay = function() {
|
|
$scope.toggle = !$scope.toggle
|
|
};
|
|
var treatmentConfigColumnHeaders = $scope.config.columnHeaders;
|
|
$scope.columnHeaders = {
|
|
drugName: treatmentConfigColumnHeaders && treatmentConfigColumnHeaders.drugName || "DRUG_DETAILS_DRUG_NAME",
|
|
dosage: treatmentConfigColumnHeaders && treatmentConfigColumnHeaders.dosage || "DRUG_DETAILS_DOSE_INFO",
|
|
route: treatmentConfigColumnHeaders && treatmentConfigColumnHeaders.route || "DRUG_DETAILS_ROUTE",
|
|
duration: treatmentConfigColumnHeaders && treatmentConfigColumnHeaders.duration || "DRUG_DETAILS_DURATION",
|
|
frequency: treatmentConfigColumnHeaders && treatmentConfigColumnHeaders.frequency || "DRUG_DETAILS_FREQUENCY",
|
|
startDate: treatmentConfigColumnHeaders && treatmentConfigColumnHeaders.startDate || "DRUG_DETAILS_START_DATE",
|
|
stopDate: treatmentConfigColumnHeaders && treatmentConfigColumnHeaders.stopDate || "DRUG_DETAILS_STOP_DATE",
|
|
stopReason: treatmentConfigColumnHeaders && treatmentConfigColumnHeaders.stopReason || "DRUG_DETAILS_ORDER_REASON_CODED",
|
|
instructions: treatmentConfigColumnHeaders && treatmentConfigColumnHeaders.instructions || "DRUG_DETAILS_INSTRUCTIONS_TEXT",
|
|
quantity: treatmentConfigColumnHeaders && treatmentConfigColumnHeaders.quantity || "DRUG_DETAILS_QUANTITY_TEXT"
|
|
}, $scope.scheduledDate = DateUtil.getDateWithoutTime(DateUtil.addDays(DateUtil.now(), 1));
|
|
var initialiseColumns = function() {
|
|
var mandatoryColumns = ["drugName", "dosage", "startDate"],
|
|
defaultColumns = ["frequency", "route"];
|
|
_.isEmpty($scope.config.columns) ? $scope.columns = _.union(mandatoryColumns, defaultColumns) : $scope.columns = _.union($scope.config.columns, defaultColumns, mandatoryColumns)
|
|
},
|
|
mergeActiveAndScheduledWithDiscontinuedOrders = function() {
|
|
_.each($scope.discontinuedDrugs, function(discontinuedDrug) {
|
|
_.remove($scope.drugOrders, {
|
|
uuid: discontinuedDrug.uuid
|
|
}), $scope.drugOrders.push(discontinuedDrug)
|
|
})
|
|
},
|
|
init = function() {
|
|
return initialiseColumns(), _.isEmpty($scope.config.title) && _.isEmpty($scope.config.translationKey) && ($scope.config.title = "Drug Orders"), $scope.isOrderSet ? void($scope.isDrugOrderSet = !0) : treatmentService.getAllDrugOrdersFor($scope.patientUuid, $scope.config.includeConceptSet, $scope.config.excludeConceptSet, $scope.config.active, $scope.enrollment).then(function(drugOrderResponse) {
|
|
var createDrugOrder = function(drugOrder) {
|
|
return Bahmni.Clinical.DrugOrderViewModel.createFromContract(drugOrder, $scope.treatmentConfig)
|
|
};
|
|
$scope.drugOrders = sortOrders(drugOrderResponse.map(createDrugOrder)), $scope.config.active && mergeActiveAndScheduledWithDiscontinuedOrders(), $scope.stoppedOrderReasons = $scope.treatmentConfig.stoppedOrderReasonConcepts
|
|
})
|
|
},
|
|
sortOrders = function(drugOrders) {
|
|
var drugOrderUtil = Bahmni.Clinical.DrugOrder.Util,
|
|
sortedDrugOrders = [];
|
|
return sortedDrugOrders.push(drugOrderUtil.sortDrugOrdersInChronologicalOrder(drugOrders)), _.flatten(sortedDrugOrders)
|
|
},
|
|
clearOtherDrugOrderActions = function(revisedDrugOrder) {
|
|
$scope.drugOrders.forEach(function(drugOrder) {
|
|
drugOrder != revisedDrugOrder && (drugOrder.isDiscontinuedAllowed = !0, drugOrder.isBeingEdited = !1)
|
|
})
|
|
};
|
|
$scope.$on("event:reviseDrugOrder", function(event, drugOrder) {
|
|
clearOtherDrugOrderActions(drugOrder)
|
|
}), $scope.refill = function(drugOrder) {
|
|
$rootScope.$broadcast("event:refillDrugOrder", drugOrder)
|
|
}, $scope.remove = function(drugOrder) {
|
|
var promise = treatmentService.voidDrugOrder(drugOrder);
|
|
spinner.forPromise(promise), promise.then(function() {
|
|
$rootScope.$broadcast("event:sectionUpdated", drugOrder)
|
|
})
|
|
}, $scope.$on("event:sectionUpdated", function() {
|
|
init()
|
|
}), $scope.revise = function(drugOrder, drugOrders) {
|
|
drugOrder.isEditAllowed && $rootScope.$broadcast("event:reviseDrugOrder", drugOrder, drugOrders)
|
|
}, $scope.checkConflictingDrug = function(drugOrder) {
|
|
$rootScope.$broadcast("event:includeOrderSetDrugOrder", drugOrder)
|
|
}, $scope.edit = function(drugOrder) {
|
|
var index = _.indexOf($scope.drugOrders, drugOrder);
|
|
$rootScope.$broadcast("event:editDrugOrder", drugOrder, index)
|
|
}, $scope.toggleShowAdditionalInstructions = function(line) {
|
|
line.showAdditionalInstructions = !line.showAdditionalInstructions
|
|
}, $scope.discontinue = function(drugOrder) {
|
|
drugOrder.isDiscontinuedAllowed && ($rootScope.$broadcast("event:discontinueDrugOrder", drugOrder), $scope.updateFormConditions(drugOrder))
|
|
}, $scope.undoDiscontinue = function(drugOrder) {
|
|
$rootScope.$broadcast("event:undoDiscontinueDrugOrder", drugOrder)
|
|
}, $scope.getMinDateForDiscontinue = function(drugOrder) {
|
|
var minDate = DateUtil.today();
|
|
return DateUtil.isBeforeDate(drugOrder.effectiveStartDate, minDate) && (minDate = drugOrder.effectiveStartDate), DateUtil.getDateWithoutTime(minDate)
|
|
}, $scope.updateFormConditions = function(drugOrder) {
|
|
var formCondition = Bahmni.ConceptSet.FormConditions.rules ? Bahmni.ConceptSet.FormConditions.rules["Medication Stop Reason"] : void 0;
|
|
formCondition ? drugOrder.orderReasonConcept ? formCondition(drugOrder, drugOrder.orderReasonConcept.name.name) || disableAndClearReasonText(drugOrder) : disableAndClearReasonText(drugOrder) : drugOrder.orderReasonNotesEnabled = !0
|
|
};
|
|
var disableAndClearReasonText = function(drugOrder) {
|
|
drugOrder.orderReasonText = null, drugOrder.orderReasonNotesEnabled = !1
|
|
},
|
|
promise = init();
|
|
promise && spinner.forPromise(promise)
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
controller: controller,
|
|
scope: {
|
|
config: "=",
|
|
patientUuid: "=",
|
|
treatmentConfig: "=",
|
|
discontinuedDrugs: "=",
|
|
enrollment: "=",
|
|
drugOrders: "=?",
|
|
isOrderSet: "=?"
|
|
},
|
|
templateUrl: "../common/displaycontrols/drugOrdersSection/views/drugOrdersSection.html"
|
|
}
|
|
}]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.DisplayControl = Bahmni.Common.DisplayControl || {}, Bahmni.Common.DisplayControl.Diagnosis = Bahmni.Common.DisplayControl.Diagnosis || {}, angular.module("bahmni.common.displaycontrol.diagnosis", []), angular.module("bahmni.common.displaycontrol.diagnosis").filter("primaryDiagnosisFirst", function() {
|
|
return function(diagnoses) {
|
|
var primaryDiagnoses = _.filter(diagnoses, function(diagnosis) {
|
|
return diagnosis.isPrimary()
|
|
}),
|
|
otherDiagnoses = _.filter(diagnoses, function(diagnosis) {
|
|
return !diagnosis.isPrimary()
|
|
});
|
|
return primaryDiagnoses.concat(otherDiagnoses)
|
|
}
|
|
}), angular.module("bahmni.common.displaycontrol.diagnosis").directive("bahmniDiagnosis", ["diagnosisService", "$q", "spinner", "$rootScope", "$filter", function(diagnosisService, $q, spinner, $rootScope, $filter) {
|
|
var controller = function($scope) {
|
|
var getAllDiagnosis = function() {
|
|
return diagnosisService.getDiagnoses($scope.patientUuid, $scope.visitUuid).then(function(response) {
|
|
var diagnosisMapper = new Bahmni.DiagnosisMapper($rootScope.diagnosisStatus);
|
|
$scope.allDiagnoses = diagnosisMapper.mapDiagnoses(response.data), 0 == $scope.showRuledOutDiagnoses && ($scope.allDiagnoses = _.filter($scope.allDiagnoses, function(diagnoses) {
|
|
return diagnoses.diagnosisStatus !== $rootScope.diagnosisStatus
|
|
})), $scope.isDataPresent = function() {
|
|
return !$scope.allDiagnoses || 0 != $scope.allDiagnoses.length || ($scope.$emit("no-data-present-event"), !1)
|
|
}
|
|
})
|
|
};
|
|
$scope.title = $scope.config.title, $scope.toggle = function(diagnosis, toggleLatest) {
|
|
toggleLatest ? (diagnosis.showDetails = !1, diagnosis.showLatestDetails = !diagnosis.showLatestDetails) : (diagnosis.showLatestDetails = !1, diagnosis.showDetails = !diagnosis.showDetails)
|
|
};
|
|
var getPromises = function() {
|
|
return [getAllDiagnosis()]
|
|
};
|
|
$scope.isLatestDiagnosis = function(diagnosis) {
|
|
return !!diagnosis.latestDiagnosis && diagnosis.existingObs == diagnosis.latestDiagnosis.existingObs
|
|
}, $scope.initialization = $q.all(getPromises())
|
|
},
|
|
link = function($scope, element) {
|
|
spinner.forPromise($scope.initialization, element)
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
controller: controller,
|
|
link: link,
|
|
templateUrl: "../common/displaycontrols/diagnosis/views/diagnosisDisplayControl.html",
|
|
scope: {
|
|
patientUuid: "=",
|
|
config: "=",
|
|
visitUuid: "=?",
|
|
showRuledOutDiagnoses: "=?",
|
|
hideTitle: "=?",
|
|
showLatestDiagnosis: "@showLatestDiagnosis"
|
|
}
|
|
}
|
|
}]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.DisplayControl = Bahmni.Common.DisplayControl || {}, Bahmni.Common.DisplayControl.Orders = Bahmni.Common.DisplayControl.Orders || {}, angular.module("bahmni.common.displaycontrol.orders", []);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.DisplayControl = Bahmni.Common.DisplayControl || {}, Bahmni.Common.DisplayControl.bacteriologyresults = Bahmni.Common.DisplayControl.bacteriologyresults || {}, angular.module("bahmni.common.displaycontrol.bacteriologyresults", []), angular.module("bahmni.common.displaycontrol.orders").directive("ordersControl", ["orderService", "orderTypeService", "$q", "spinner", "$filter", function(orderService, orderTypeService, $q, spinner, $filter) {
|
|
var controller = function($scope) {
|
|
$scope.orderTypeUuid = orderTypeService.getOrderTypeUuid($scope.orderType), null !== $scope.config.showHeader && void 0 !== $scope.config.showHeader || ($scope.config.showHeader = !0);
|
|
var includeAllObs = !0,
|
|
getOrders = function() {
|
|
var params = {
|
|
patientUuid: $scope.patient.uuid,
|
|
orderTypeUuid: $scope.orderTypeUuid,
|
|
conceptNames: $scope.config.conceptNames,
|
|
includeObs: includeAllObs,
|
|
numberOfVisits: $scope.config.numberOfVisits,
|
|
obsIgnoreList: $scope.config.obsIgnoreList,
|
|
visitUuid: $scope.visitUuid,
|
|
orderUuid: $scope.orderUuid
|
|
};
|
|
return orderService.getOrders(params).then(function(response) {
|
|
$scope.bahmniOrders = response.data
|
|
})
|
|
},
|
|
init = function() {
|
|
return getOrders().then(function() {
|
|
_.forEach($scope.bahmniOrders, function(order) {
|
|
0 === order.bahmniObservations.length && (order.hideIfEmpty = !0)
|
|
}), _.isEmpty($scope.bahmniOrders) ? $scope.noOrdersMessage = $scope.getSectionTitle() : $scope.bahmniOrders[0].isOpen = !0
|
|
})
|
|
};
|
|
$scope.getTitle = function(order) {
|
|
return order.conceptName + " on " + $filter("bahmniDateTime")(order.orderDate) + " by " + order.provider
|
|
}, $scope.toggle = function(element) {
|
|
element.isOpen = !element.isOpen
|
|
}, $scope.dialogData = {
|
|
patient: $scope.patient,
|
|
section: $scope.section
|
|
}, $scope.isClickable = function() {
|
|
return $scope.isOnDashboard && $scope.section.expandedViewConfig
|
|
}, $scope.hasTitleToBeShown = function() {
|
|
return !$scope.isClickable() && $scope.getSectionTitle()
|
|
}, $scope.message = Bahmni.Common.Constants.messageForNoFulfillment, $scope.getSectionTitle = function() {
|
|
return $filter("titleTranslate")($scope.section)
|
|
}, $scope.initialization = init()
|
|
},
|
|
link = function($scope, element) {
|
|
spinner.forPromise($scope.initialization, element)
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
controller: controller,
|
|
link: link,
|
|
templateUrl: "../common/displaycontrols/orders/views/ordersControl.html",
|
|
scope: {
|
|
patient: "=",
|
|
section: "=",
|
|
orderType: "=",
|
|
orderUuid: "=",
|
|
config: "=",
|
|
isOnDashboard: "=",
|
|
visitUuid: "="
|
|
}
|
|
}
|
|
}]), angular.module("bahmni.common.displaycontrol.bacteriologyresults").directive("bacteriologyResultsControl", ["bacteriologyResultsService", "appService", "$q", "spinner", "$filter", "ngDialog", "bacteriologyTabInitialization", "$controller", "consultationInitialization", "messagingService", "$rootScope", "$translate", function(bacteriologyResultsService, appService, $q, spinner, $filter, ngDialog, bacteriologyTabInitialization, $controller, consultationInitialization, messagingService, $rootScope, $translate) {
|
|
var controller = function($scope) {
|
|
var shouldPromptBeforeClose = !0,
|
|
expandAllSpecimensIfDashboardIsBeingPrinted = function() {
|
|
$rootScope.isBeingPrinted && _.each($scope.specimens, function(specimen) {
|
|
specimen.isOpen = !0
|
|
})
|
|
},
|
|
init = function() {
|
|
$scope.title = "bacteriology results";
|
|
var params = {
|
|
patientUuid: $scope.patient.uuid,
|
|
patientProgramUuid: $scope.enrollment
|
|
};
|
|
return $scope.initializationPromise = bacteriologyTabInitialization().then(function(data) {
|
|
$scope.bacteriologyTabData = data, bacteriologyResultsService.getBacteriologyResults(params).then(function(response) {
|
|
handleResponse(response), expandAllSpecimensIfDashboardIsBeingPrinted()
|
|
})
|
|
}), $scope.initializationPromise
|
|
},
|
|
handleResponse = function(response) {
|
|
if ($scope.observations = response.data.results, $scope.observations && $scope.observations.length > 0) {
|
|
$scope.specimens = [];
|
|
var sampleSource = _.find($scope.bacteriologyTabData.setMembers, function(member) {
|
|
return member.name.name === Bahmni.Clinical.Constants.bacteriologyConstants.specimenSampleSourceConceptName
|
|
});
|
|
$scope.allSamples = void 0 != sampleSource && _.map(sampleSource.answers, function(answer) {
|
|
return (new Bahmni.Common.Domain.ConceptMapper).map(answer)
|
|
});
|
|
var specimenMapper = new Bahmni.Clinical.SpecimenMapper,
|
|
conceptsConfig = appService.getAppDescriptor().getConfigValue("conceptSetUI") || {},
|
|
dontSortByObsDateTime = !0;
|
|
_.forEach($scope.observations, function(observation) {
|
|
$scope.specimens.push(specimenMapper.mapObservationToSpecimen(observation, $scope.allSamples, conceptsConfig, dontSortByObsDateTime))
|
|
})
|
|
} else $scope.specimens = [];
|
|
$scope.isDataPresent = function() {
|
|
return !(!$scope.specimens || !$scope.specimens.length) || $scope.$emit("no-data-present-event") && !1
|
|
}
|
|
};
|
|
$scope.editBacteriologySample = function(specimen) {
|
|
var configForPrompt = appService.getAppDescriptor().getConfigValue("showSaveConfirmDialog");
|
|
$scope.editDialogInitializationPromise = consultationInitialization($scope.patient.uuid, null, null).then(function(consultationContext) {
|
|
$scope.consultation = consultationContext, $scope.consultation.newlyAddedSpecimens = [], $scope.isOnDashboard = !0, $scope.consultation.newlyAddedSpecimens.push(specimen), $scope.dialogElement = ngDialog.open({
|
|
template: "../common/displaycontrols/bacteriologyresults/views/editBacteriologySample.html",
|
|
scope: $scope,
|
|
className: "ngdialog-theme-default ng-dialog-all-details-page ng-dialog-edit",
|
|
controller: $controller("BacteriologyController", {
|
|
$scope: $scope,
|
|
bacteriologyConceptSet: $scope.bacteriologyTabData
|
|
}),
|
|
preCloseCallback: function() {
|
|
return configForPrompt && shouldPromptBeforeClose ? !!confirm($translate.instant("POP_UP_CLOSE_DIALOG_MESSAGE_KEY")) && ($rootScope.hasVisitedConsultation || (window.onbeforeunload = null), init(), !0) : void init()
|
|
}
|
|
}), $scope.scrollOnEdit = "scrollOnEdit"
|
|
})
|
|
}, $scope.saveBacteriologySample = function(specimen) {
|
|
if (specimen.hasIllegalDateCollected = !specimen.dateCollected, specimen.hasIllegalType = !specimen.type, specimen.hasIllegalTypeFreeText = !specimen.typeFreeText, specimen.isDirty()) messagingService.showMessage("error", "{{'CLINICAL_FORM_ERRORS_MESSAGE_KEY' | translate }}");
|
|
else {
|
|
shouldPromptBeforeClose = !1;
|
|
var specimenMapper = new Bahmni.Clinical.SpecimenMapper;
|
|
specimen.voidIfEmpty(), $scope.saveBacteriologyResultsPromise = bacteriologyResultsService.saveBacteriologyResults(specimenMapper.mapSpecimenToObservation(specimen)), $scope.saveBacteriologyResultsPromise.then(function() {
|
|
$rootScope.hasVisitedConsultation || (window.onbeforeunload = null), $rootScope.hasVisitedConsultation = !1, ngDialog.close(), messagingService.showMessage("info", "{{'CLINICAL_SAVE_SUCCESS_MESSAGE_KEY' | translate}}")
|
|
})
|
|
}
|
|
}, $scope.getDisplayName = function(specimen) {
|
|
var type = specimen.type,
|
|
displayName = type.shortName ? type.shortName : type.name;
|
|
return displayName === Bahmni.Clinical.Constants.bacteriologyConstants.otherSampleType && (displayName = specimen.typeFreeText), displayName
|
|
}, $scope.hasResults = function(test) {
|
|
return test && test.groupMembers
|
|
}, init()
|
|
},
|
|
link = function($scope, element) {
|
|
$scope.$watch("initializationPromise", function() {
|
|
$scope.initializationPromise && spinner.forPromise($scope.initializationPromise, element)
|
|
}), $scope.$watch("editDialogInitializationPromise", function() {
|
|
$scope.editDialogInitializationPromise && spinner.forPromise($scope.editDialogInitializationPromise, element)
|
|
}), $scope.$watch("saveBacteriologyResultsPromise", function() {
|
|
$scope.saveBacteriologyResultsPromise && spinner.forPromise($scope.saveBacteriologyResultsPromise, $("#" + $scope.dialogElement.id))
|
|
})
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
controller: controller,
|
|
templateUrl: "../common/displaycontrols/bacteriologyresults/views/bacteriologyResultsControl.html",
|
|
scope: {
|
|
patient: "=",
|
|
section: "=",
|
|
observationUuid: "=",
|
|
config: "=",
|
|
visitUuid: "=",
|
|
enrollment: "@"
|
|
},
|
|
link: link
|
|
}
|
|
}]), angular.module("bahmni.common.displaycontrol.orders").controller("AllOrdersDetailsController", ["$scope", function($scope) {
|
|
$scope.patient = $scope.ngDialogData.patient, $scope.section = $scope.ngDialogData.section, $scope.title = $scope.section.title, $scope.config = $scope.ngDialogData.section ? $scope.ngDialogData.section.expandedViewConfig : {}
|
|
}]), angular.module("bahmni.common.displaycontrol.programs", ["bahmni.common.domain", "bahmni.common.uiHelper"]), angular.module("bahmni.common.displaycontrol.programs").directive("programs", ["programService", "$state", "spinner", function(programService, $state, spinner) {
|
|
var controller = function($scope) {
|
|
$scope.initialization = programService.getPatientPrograms($scope.patient.uuid, !0, $state.params.enrollment).then(function(patientPrograms) {
|
|
_.isEmpty(patientPrograms.activePrograms) && _.isEmpty(patientPrograms.endedPrograms) && $scope.$emit("no-data-present-event"), $scope.activePrograms = patientPrograms.activePrograms, $scope.pastPrograms = patientPrograms.endedPrograms
|
|
}), $scope.hasPatientAnyActivePrograms = function() {
|
|
return !_.isEmpty($scope.activePrograms)
|
|
}, $scope.hasPatientAnyPastPrograms = function() {
|
|
return !_.isEmpty($scope.pastPrograms)
|
|
}, $scope.hasPatientAnyPrograms = function() {
|
|
return $scope.hasPatientAnyPastPrograms() || $scope.hasPatientAnyActivePrograms()
|
|
}, $scope.showProgramStateInTimeline = function() {
|
|
return programService.getProgramStateConfig()
|
|
}, $scope.hasStates = function(program) {
|
|
return !_.isEmpty(program.states)
|
|
}, $scope.getAttributeValue = function(attribute) {
|
|
if (isDateFormat(attribute.attributeType.format)) return Bahmni.Common.Util.DateUtil.formatDateWithoutTime(attribute.value);
|
|
if (isCodedConceptFormat(attribute.attributeType.format)) {
|
|
var mrsAnswer = attribute.value,
|
|
displayName = mrsAnswer.display;
|
|
return mrsAnswer.names && 2 == mrsAnswer.names.length && "FULLY_SPECIFIED" == mrsAnswer.name.conceptNameType && (displayName = mrsAnswer.names[0].display == displayName ? mrsAnswer.names[1].display : mrsAnswer.names[0].display), displayName
|
|
}
|
|
return attribute.value
|
|
}, $scope.isIncluded = function(attributeType, program) {
|
|
return !(program.program && _.includes(attributeType.excludeFrom, program.program.name))
|
|
};
|
|
var isDateFormat = function(format) {
|
|
return "org.openmrs.customdatatype.datatype.DateDatatype" == format
|
|
},
|
|
isCodedConceptFormat = function(format) {
|
|
return "org.bahmni.module.bahmnicore.customdatatype.datatype.CodedConceptDatatype" == format
|
|
}
|
|
},
|
|
link = function($scope, element) {
|
|
spinner.forPromise($scope.initialization, element)
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
link: link,
|
|
controller: controller,
|
|
templateUrl: "../common/displaycontrols/programs/views/programs.html",
|
|
scope: {
|
|
patient: "="
|
|
}
|
|
}
|
|
}]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.DisplayControl = Bahmni.Common.DisplayControl || {}, Bahmni.Common.DisplayControl.ObsToObsFlowSheet = Bahmni.Common.DisplayControl.ObsToObsFlowSheet || {}, angular.module("bahmni.common.displaycontrol.obsVsObsFlowSheet", []), angular.module("bahmni.common.displaycontrol.obsVsObsFlowSheet").directive("obsToObsFlowSheet", ["$translate", "spinner", "observationsService", "conceptSetService", "$q", "conceptSetUiConfigService", function($translate, spinner, observationsService, conceptSetService, $q, conceptSetUiConfigService) {
|
|
var link = function($scope, element) {
|
|
$scope.config = $scope.isOnDashboard ? $scope.section.dashboardConfig : $scope.section.expandedViewConfig, $scope.isEditable = $scope.config.isEditable;
|
|
var patient = $scope.patient,
|
|
getTemplateDisplayName = function() {
|
|
return conceptSetService.getConcept({
|
|
name: $scope.config.templateName,
|
|
v: "custom:(uuid,names,displayString)"
|
|
}).then(function(result) {
|
|
var templateConcept = result && result.data && result.data.results && result.data.results[0],
|
|
displayName = templateConcept && templateConcept.displayString;
|
|
templateConcept && templateConcept.names && 1 === templateConcept.names.length && "" != templateConcept.names[0].name ? displayName = templateConcept.names[0].name : templateConcept && templateConcept.names && 2 === templateConcept.names.length && (displayName = _.find(templateConcept.names, {
|
|
conceptNameType: "SHORT"
|
|
}).name), $scope.conceptDisplayName = displayName
|
|
})
|
|
};
|
|
const removeEmptyRecords = function(records) {
|
|
return records.headers = _.filter(records.headers, function(header) {
|
|
return !_.every(records.rows, function(record) {
|
|
return _.isEmpty(record.columns[header.name])
|
|
})
|
|
}), records
|
|
};
|
|
var getObsInFlowSheet = function() {
|
|
return observationsService.getObsInFlowSheet(patient.uuid, $scope.config.templateName, $scope.config.groupByConcept, $scope.config.orderByConcept, $scope.config.conceptNames, $scope.config.numberOfVisits, $scope.config.initialCount, $scope.config.latestCount, $scope.config.type, $scope.section.startDate, $scope.section.endDate, $scope.enrollment).success(function(data) {
|
|
var obsInFlowSheet = data,
|
|
groupByElement = _.find(obsInFlowSheet.headers, function(header) {
|
|
return header.name === $scope.config.groupByConcept
|
|
});
|
|
obsInFlowSheet.headers = _.without(obsInFlowSheet.headers, groupByElement), obsInFlowSheet.headers.unshift(groupByElement), $scope.config.hideEmptyRecords && (obsInFlowSheet = removeEmptyRecords(obsInFlowSheet)), $scope.obsTable = obsInFlowSheet, _.isEmpty($scope.obsTable.rows) && $scope.$emit("no-data-present-event")
|
|
})
|
|
},
|
|
init = function() {
|
|
return $q.all([getObsInFlowSheet(), getTemplateDisplayName()]).then(function() {})
|
|
};
|
|
$scope.isClickable = function() {
|
|
return $scope.isOnDashboard && $scope.section.expandedViewConfig
|
|
}, $scope.dialogData = {
|
|
patient: $scope.patient,
|
|
section: $scope.section
|
|
}, $scope.getEditObsData = function(observation) {
|
|
return {
|
|
observation: {
|
|
encounterUuid: observation.encounterUuid,
|
|
uuid: observation.obsGroupUuid
|
|
},
|
|
conceptSetName: $scope.config.templateName,
|
|
conceptDisplayName: $scope.conceptDisplayName
|
|
}
|
|
}, $scope.getPivotOn = function() {
|
|
return $scope.config.pivotOn
|
|
}, $scope.getHeaderName = function(header) {
|
|
var abbreviation = getSourceCode(header, $scope.section.headingConceptSource),
|
|
headerName = abbreviation || header.shortName || header.name;
|
|
return header.units && (headerName = headerName + " (" + header.units + ")"), headerName
|
|
};
|
|
var getSourceCode = function(concept, conceptSource) {
|
|
var result;
|
|
return concept && concept.mappings && concept.mappings.length > 0 && (result = _.result(_.find(concept.mappings, {
|
|
source: conceptSource
|
|
}), "code"), result = $translate.instant(result)), result
|
|
},
|
|
getName = function(obs) {
|
|
return getSourceCode(obs.value, $scope.section.dataConceptSource) || obs && obs.value && obs.value.shortName || obs && obs.value && obs.value.name || obs.value
|
|
};
|
|
$scope.commafy = function(observations) {
|
|
var list = [],
|
|
config = conceptSetUiConfigService.getConfig(),
|
|
unBoolean = function(boolValue) {
|
|
return boolValue ? $translate.instant("OBS_BOOLEAN_YES_KEY") : $translate.instant("OBS_BOOLEAN_NO_KEY")
|
|
};
|
|
for (var index in observations) {
|
|
var name = getName(observations[index]);
|
|
if ("Boolean" === observations[index].concept.dataType && (name = unBoolean(name)), "Date" === observations[index].concept.dataType) {
|
|
var conceptName = observations[index].concept.name;
|
|
name = conceptName && config[conceptName] && 1 == config[conceptName].displayMonthAndYear ? Bahmni.Common.Util.DateUtil.getDateInMonthsAndYears(name) : Bahmni.Common.Util.DateUtil.formatDateWithoutTime(name)
|
|
}
|
|
list.push(name)
|
|
}
|
|
return list.join($scope.config && $scope.config.obsDelimiter ? $scope.config.obsDelimiter : ", ")
|
|
}, $scope.isMonthAvailable = function() {
|
|
return null != $scope.obsTable.rows[0].columns.Month
|
|
}, $scope.hasPDFAsValue = function(data) {
|
|
return !!data.value && data.value.indexOf(".pdf") > 0
|
|
}, spinner.forPromise(init(), element)
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
link: link,
|
|
scope: {
|
|
patient: "=",
|
|
section: "=",
|
|
visitSummary: "=",
|
|
isOnDashboard: "=",
|
|
enrollment: "=",
|
|
startDate: "=",
|
|
endDate: "="
|
|
},
|
|
templateUrl: "../common/displaycontrols/tabularview/views/obsToObsFlowSheet.html"
|
|
}
|
|
}]), angular.module("bahmni.common.displaycontrol.observation").controller("AllObsToObsFlowSheetDetailsController", ["$scope", function($scope) {
|
|
$scope.patient = $scope.ngDialogData.patient, $scope.section = $scope.ngDialogData.section, $scope.config = $scope.ngDialogData.section ? $scope.ngDialogData.section.expandedViewConfig : {}
|
|
}]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.DisplayControl = Bahmni.Common.DisplayControl || {}, Bahmni.Common.DisplayControl.DrugOGram = Bahmni.Common.DisplayControl.DrugOGram || {}, angular.module("bahmni.common.displaycontrol", []), angular.module("bahmni.common.displaycontrol.chronicTreatmentChart", []), angular.module("bahmni.common.displaycontrol.chronicTreatmentChart").directive("chronicTreatmentChart", ["$translate", "spinner", "drugService", function($translate, spinner, drugService) {
|
|
var link = function($scope, element) {
|
|
$scope.config = $scope.isOnDashboard ? $scope.section.dashboardConfig : $scope.section.expandedViewConfig;
|
|
var patient = $scope.patient,
|
|
init = function() {
|
|
return drugService.getRegimen(patient.uuid, $scope.enrollment, $scope.config.drugs).success(function(data) {
|
|
var filterNullRow = function() {
|
|
for (var row in $scope.regimen.rows) {
|
|
var nullFlag = !0;
|
|
for (var drug in $scope.regimen.rows[row].drugs)
|
|
if ($scope.regimen.rows[row].drugs[drug]) {
|
|
nullFlag = !1;
|
|
break
|
|
} nullFlag && $scope.regimen.rows.splice(row, 1)
|
|
}
|
|
};
|
|
$scope.regimen = data, _.isEmpty($scope.regimen.rows) && $scope.$emit("no-data-present-event"), filterNullRow()
|
|
})
|
|
};
|
|
$scope.getAbbreviation = function(concept) {
|
|
var result;
|
|
return concept && concept.mappings && concept.mappings.length > 0 && $scope.section.headingConceptSource && (result = _.result(_.find(concept.mappings, {
|
|
source: $scope.section.headingConceptSource
|
|
}), "code"), result = $translate.instant(result)), result || concept.shortName || concept.name
|
|
}, $scope.isMonthNumberRequired = function() {
|
|
var month = $scope.regimen && $scope.regimen.rows && $scope.regimen.rows[0] && $scope.regimen.rows[0].month;
|
|
return month
|
|
}, $scope.isClickable = function() {
|
|
return $scope.isOnDashboard && $scope.section.expandedViewConfig
|
|
}, $scope.dialogData = {
|
|
patient: $scope.patient,
|
|
section: $scope.section,
|
|
enrollment: $scope.enrollment
|
|
}, spinner.forPromise(init(), element)
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
link: link,
|
|
scope: {
|
|
patient: "=",
|
|
section: "=",
|
|
isOnDashboard: "=",
|
|
enrollment: "="
|
|
},
|
|
templateUrl: "../common/displaycontrols/chronicTreatmentChart/views/chronicTreatmentChart.html"
|
|
}
|
|
}]), angular.module("bahmni.common.displaycontrol.chronicTreatmentChart").filter("decimalFilter", function() {
|
|
return function(value) {
|
|
return isNaN(value) || "" === value ? value : (value = +value, Math.floor(value))
|
|
}
|
|
}), angular.module("bahmni.common.displaycontrol.chronicTreatmentChart").controller("AllChronicTreatmentChartController", ["$scope", function($scope) {
|
|
$scope.patient = $scope.ngDialogData.patient, $scope.enrollment = $scope.ngDialogData.enrollment, $scope.section = $scope.ngDialogData.section, $scope.config = $scope.ngDialogData.section ? $scope.ngDialogData.section.expandedViewConfig : {}
|
|
}]), angular.module("bahmni.common.displaycontrol.dashboard").controller("PatientDashboardDiagnosisController", ["$scope", "ngDialog", function($scope, ngDialog) {
|
|
$scope.section = $scope.dashboard.getSectionByType("diagnosis") || {}, $scope.openSummaryDialog = function() {
|
|
ngDialog.open({
|
|
template: "../common/displaycontrols/dashboard/views/sections/diagnosisSummary.html",
|
|
className: "ngdialog-theme-default ng-dialog-all-details-page",
|
|
scope: $scope
|
|
})
|
|
};
|
|
var cleanUpListener = $scope.$on("ngDialog.closing", function() {
|
|
$("body").removeClass("ngdialog-open")
|
|
});
|
|
$scope.$on("$destroy", cleanUpListener)
|
|
}]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.DisplayControl = Bahmni.Common.DisplayControl || {}, Bahmni.Common.DisplayControl.forms = Bahmni.Common.DisplayControl.forms || {}, angular.module("bahmni.common.displaycontrol.forms", []), angular.module("bahmni.clinical").controller("patientDashboardAllFormsController", ["$scope", function($scope) {
|
|
$scope.patient = $scope.ngDialogData.patient, $scope.section = $scope.ngDialogData.section
|
|
}]), angular.module("bahmni.common.displaycontrol.forms").directive("formsTable", ["conceptSetService", "spinner", "$q", "visitFormService", "appService", "$state", function(conceptSetService, spinner, $q, visitFormService, appService, $state) {
|
|
var controller = function($scope) {
|
|
$scope.shouldPromptBrowserReload = !0, $scope.showFormsDate = appService.getAppDescriptor().getConfigValue("showFormsDate");
|
|
var getAllObservationTemplates = function() {
|
|
return conceptSetService.getConcept({
|
|
name: "All Observation Templates",
|
|
v: "custom:(setMembers:(display))"
|
|
})
|
|
},
|
|
obsFormData = function() {
|
|
return visitFormService.formData($scope.patient.uuid, $scope.section.dashboardConfig.maximumNoOfVisits, $scope.section.formGroup, $state.params.enrollment)
|
|
},
|
|
filterFormData = function(formData) {
|
|
var filterList = [];
|
|
return _.each(formData, function(item) {
|
|
var foundElement = _.find(filterList, function(filteredItem) {
|
|
return item.concept.uuid == filteredItem.concept.uuid
|
|
});
|
|
void 0 == foundElement && filterList.push(item)
|
|
}), filterList
|
|
},
|
|
sortedFormDataByLatestDate = function(formData) {
|
|
return _.sortBy(formData, "obsDatetime").reverse()
|
|
},
|
|
init = function() {
|
|
return $scope.noFormFoundMessage = "No Form found for this patient", $scope.isFormFound = !1, $q.all([getAllObservationTemplates(), obsFormData()]).then(function(results) {
|
|
$scope.observationTemplates = results[0].data.results[0].setMembers;
|
|
var sortedFormDataByDate = sortedFormDataByLatestDate(results[1].data.results);
|
|
$scope.isOnDashboard ? $scope.formData = filterFormData(sortedFormDataByDate) : $scope.formData = sortedFormDataByDate, 0 == $scope.formData.length && ($scope.isFormFound = !0, $scope.$emit("no-data-present-event"))
|
|
})
|
|
};
|
|
$scope.getDisplayName = function(data) {
|
|
var concept = data.concept,
|
|
displayName = data.concept.displayString;
|
|
if (concept.names && 1 === concept.names.length && "" != concept.names[0].name) displayName = concept.names[0].name;
|
|
else if (concept.names && 2 === concept.names.length) {
|
|
var shortName = _.find(concept.names, {
|
|
conceptNameType: "SHORT"
|
|
});
|
|
displayName = shortName && shortName.name ? shortName.name : displayName
|
|
}
|
|
return displayName
|
|
}, $scope.initialization = init(), $scope.getEditObsData = function(observation) {
|
|
return {
|
|
observation: observation,
|
|
conceptSetName: observation.concept.displayString,
|
|
conceptDisplayName: $scope.getDisplayName(observation)
|
|
}
|
|
}, $scope.shouldPromptBeforeClose = !0, $scope.getConfigToFetchDataAndShow = function(data) {
|
|
return {
|
|
patient: $scope.patient,
|
|
config: {
|
|
conceptNames: [data.concept.displayString],
|
|
showGroupDateTime: !1,
|
|
encounterUuid: data.encounterUuid,
|
|
observationUuid: data.uuid
|
|
},
|
|
section: {
|
|
title: data.concept.displayString
|
|
}
|
|
}
|
|
}, $scope.dialogData = {
|
|
patient: $scope.patient,
|
|
section: $scope.section
|
|
}
|
|
},
|
|
link = function($scope, element) {
|
|
spinner.forPromise($scope.initialization, element)
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
controller: controller,
|
|
link: link,
|
|
templateUrl: "../common/displaycontrols/forms/views/formsTable.html",
|
|
scope: {
|
|
section: "=",
|
|
patient: "=",
|
|
isOnDashboard: "="
|
|
}
|
|
}
|
|
}]), angular.module("bahmni.clinical").service("visitFormService", ["$http", function($http) {
|
|
var formData = function(patientUuid, numberOfVisits, formGroup, patientProgramUuid) {
|
|
var params = {
|
|
s: "byPatientUuid",
|
|
patient: patientUuid,
|
|
numberOfVisits: numberOfVisits,
|
|
v: "visitFormDetails",
|
|
conceptNames: formGroup || null,
|
|
patientProgramUuid: patientProgramUuid
|
|
};
|
|
return $http.get(Bahmni.Common.Constants.formDataUrl, {
|
|
params: params
|
|
})
|
|
};
|
|
return {
|
|
formData: formData
|
|
}
|
|
}]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.DisplayControl = Bahmni.Common.DisplayControl || {}, Bahmni.Common.DisplayControl.hint = Bahmni.Common.DisplayControl.hint || {}, angular.module("bahmni.common.displaycontrol.hint", []), angular.module("bahmni.common.displaycontrol.hint").directive("hint", [function() {
|
|
var link = function($scope) {
|
|
$scope.hintForNumericConcept = Bahmni.Common.Domain.Helper.getHintForNumericConcept($scope.conceptDetails)
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
link: link,
|
|
template: '<small class="hint" ng-if="::hintForNumericConcept">{{::hintForNumericConcept}}</small>',
|
|
scope: {
|
|
conceptDetails: "="
|
|
}
|
|
}
|
|
}]), angular.module("bahmni.common.orders", []), angular.module("bahmni.common.orders").factory("orderService", ["$http", function($http) {
|
|
var getOrders = function(data) {
|
|
var params = {
|
|
concept: data.conceptNames,
|
|
includeObs: data.includeObs,
|
|
patientUuid: data.patientUuid,
|
|
numberOfVisits: data.numberOfVisits
|
|
};
|
|
return data.obsIgnoreList && (params.obsIgnoreList = data.obsIgnoreList), data.orderTypeUuid && (params.orderTypeUuid = data.orderTypeUuid), data.orderUuid && (params.orderUuid = data.orderUuid), data.visitUuid && (params.visitUuid = data.visitUuid), data.locationUuids && data.locationUuids.length > 0 && (params.numberOfVisits = 0, params.locationUuids = data.locationUuids), $http.get(Bahmni.Common.Constants.bahmniOrderUrl, {
|
|
params: params,
|
|
withCredentials: !0
|
|
})
|
|
};
|
|
return {
|
|
getOrders: getOrders
|
|
}
|
|
}]), angular.module("bahmni.common.orders").service("orderSetService", ["$http", "$q", function($http, $q) {
|
|
this.getOrderSetsByQuery = function(name) {
|
|
return $http.get(Bahmni.Common.Constants.orderSetUrl, {
|
|
params: {
|
|
v: "full",
|
|
s: "byQuery",
|
|
q: name
|
|
}
|
|
})
|
|
}, this.getCalculatedDose = function(patientUuid, drugName, baseDose, doseUnit, orderSetName, dosingRule, visitUuid) {
|
|
if ("undefined" != typeof dosingRule && "" != dosingRule && null != dosingRule) {
|
|
var requestString = JSON.stringify({
|
|
patientUuid: patientUuid,
|
|
drugName: drugName,
|
|
baseDose: baseDose,
|
|
doseUnit: doseUnit,
|
|
orderSetName: orderSetName,
|
|
dosingRule: dosingRule,
|
|
visitUuid: visitUuid
|
|
});
|
|
return $http.get(Bahmni.Common.Constants.calculateDose, {
|
|
params: {
|
|
dosageRequest: requestString
|
|
},
|
|
withCredentials: !0,
|
|
headers: {
|
|
Accept: "application/json",
|
|
"Content-Type": "application/json"
|
|
}
|
|
}).then(function(response) {
|
|
return {
|
|
dose: round(response.data.value),
|
|
doseUnit: response.data.doseUnit
|
|
}
|
|
})
|
|
}
|
|
var deferred = $q.defer();
|
|
return deferred.resolve({
|
|
dose: baseDose,
|
|
doseUnit: doseUnit
|
|
}), deferred.promise
|
|
};
|
|
var round = function(value) {
|
|
var leastRoundableDose = .49,
|
|
leastPrescribableDose = .1;
|
|
return value = value <= leastRoundableDose ? value : _.round(value), value < leastPrescribableDose ? leastPrescribableDose : value
|
|
}
|
|
}]), angular.module("bahmni.common.bacteriologyresults", []), angular.module("bahmni.common.bacteriologyresults").factory("bacteriologyResultsService", ["$http", function($http) {
|
|
var getBacteriologyResults = function(data) {
|
|
var params = {
|
|
patientUuid: data.patientUuid,
|
|
name: "BACTERIOLOGY CONCEPT SET",
|
|
v: "full"
|
|
};
|
|
return data.patientProgramUuid && (params = {
|
|
patientProgramUuid: data.patientProgramUuid,
|
|
s: "byPatientProgram",
|
|
v: "full"
|
|
}), $http.get(Bahmni.Common.Constants.bahmniBacteriologyResultsUrl, {
|
|
method: "GET",
|
|
params: params,
|
|
withCredentials: !0
|
|
})
|
|
},
|
|
saveBacteriologyResults = function(specimen) {
|
|
return $http.post(Bahmni.Common.Constants.bahmniBacteriologyResultsUrl, specimen, {
|
|
withCredentials: !0
|
|
})
|
|
};
|
|
return {
|
|
getBacteriologyResults: getBacteriologyResults,
|
|
saveBacteriologyResults: saveBacteriologyResults
|
|
}
|
|
}]);
|
|
var Bahmni = Bahmni || {};
|
|
Bahmni.Common = Bahmni.Common || {}, Bahmni.Common.I18n = Bahmni.Common.I18n || {}, angular.module("bahmni.common.i18n", []), angular.module("bahmni.common.i18n", ["pascalprecht.translate"]).provider("$bahmniTranslate", ["$translateProvider", function($translateProvider) {
|
|
this.init = function(options) {
|
|
var preferredLanguage = window.localStorage.NG_TRANSLATE_LANG_KEY || "en";
|
|
$translateProvider.useLoader("mergeLocaleFilesService", options), $translateProvider.useSanitizeValueStrategy("escaped"), $translateProvider.preferredLanguage(preferredLanguage), $translateProvider.useLocalStorage()
|
|
}, this.$get = [function() {
|
|
return $translateProvider
|
|
}]
|
|
}]).filter("titleTranslate", ["$translate", function($translate) {
|
|
return function(input) {
|
|
return input ? input.translationKey ? $translate.instant(input.translationKey) : input.dashboardName ? input.dashboardName : input.title ? input.title : input.label ? input.label : input.display ? input.display : $translate.instant(input) : input
|
|
}
|
|
}]), angular.module("bahmni.common.i18n").service("mergeLocaleFilesService", ["$http", "$q", "mergeService", function($http, $q, mergeService) {
|
|
return function(options) {
|
|
var baseLocaleUrl = "../i18n/",
|
|
customLocaleUrl = Bahmni.Common.Constants.rootDir + "/bahmni_config/openmrs/i18n/",
|
|
loadFile = function(url) {
|
|
return $http.get(url, {
|
|
withCredentials: !0
|
|
})
|
|
},
|
|
mergeLocaleFile = function(options) {
|
|
var fileURL = options.app + "/locale_" + options.key + ".json",
|
|
loadBahmniTranslations = function() {
|
|
return loadFile(baseLocaleUrl + fileURL).then(function(result) {
|
|
return result
|
|
}, function() {})
|
|
},
|
|
loadCustomTranslations = function() {
|
|
return loadFile(customLocaleUrl + fileURL).then(function(result) {
|
|
return result
|
|
}, function() {})
|
|
},
|
|
mergeTranslations = function(result) {
|
|
var baseFileData = result[0] ? result[0].data : void 0,
|
|
customFileData = result[1] ? result[1].data : void 0;
|
|
return options.shouldMerge || void 0 === options.shouldMerge ? mergeService.merge(baseFileData, customFileData) : [baseFileData, customFileData]
|
|
};
|
|
return $q.all([loadBahmniTranslations(), loadCustomTranslations()]).then(mergeTranslations)
|
|
};
|
|
return mergeLocaleFile(options)
|
|
}
|
|
}]), angular.module("bahmni.common.patient").directive("patientControlPanel", ["$q", "$rootScope", "$stateParams", "$state", "contextChangeHandler", "encounterService", "configurations", "clinicalAppConfigService", "$bahmniCookieStore", "$translate", function($q, $rootScope, $stateParams, $state, contextChangeHandler, encounterService, configurations, clinicalAppConfigService, $bahmniCookieStore, $translate) {
|
|
var controller = function($scope) {
|
|
$scope.activeVisit = $scope.visitHistory.activeVisit;
|
|
var DateUtil = Bahmni.Common.Util.DateUtil,
|
|
retrieveProviderCookieData = function() {
|
|
return $bahmniCookieStore.get(Bahmni.Common.Constants.grantProviderAccessDataCookieName)
|
|
};
|
|
$scope.encounterProvider = retrieveProviderCookieData(), $scope.isValidProvider = function() {
|
|
return retrieveProviderCookieData() && retrieveProviderCookieData().value
|
|
}, $scope.retrospectivePrivilege = Bahmni.Common.Constants.retrospectivePrivilege, $scope.encounterProviderPrivilege = Bahmni.Common.Constants.grantProviderAccess, $scope.today = DateUtil.getDateWithoutTime(DateUtil.now()), $scope.getDashboardLink = function() {
|
|
var dashboardUrl = "#/" + $stateParams.configName + "/patient/" + $scope.patient.uuid + "/dashboard";
|
|
if ($stateParams.programUuid) {
|
|
var programParams = "programUuid=" + $stateParams.programUuid + "&enrollment=" + $stateParams.enrollment + "&dateEnrolled=" + $stateParams.dateEnrolled;
|
|
dashboardUrl = dashboardUrl + "?" + programParams
|
|
}
|
|
return dashboardUrl
|
|
}, $scope.changeContext = function($event) {
|
|
var allowContextChange = contextChangeHandler.execute().allow;
|
|
return allowContextChange ? void $rootScope.toggleControlPanel() : void $event.preventDefault()
|
|
}, $scope.isCurrentVisit = function(visit) {
|
|
return $stateParams.visitUuid === visit.uuid
|
|
}, $scope.isInEditEncounterMode = function() {
|
|
return void 0 !== $stateParams.encounterUuid && "active" !== $stateParams.encounterUuid
|
|
};
|
|
var getLinks = function() {
|
|
var state = $state.current.name;
|
|
if (state.match("patient.consultation")) return [{
|
|
text: $translate.instant("CONTROL_PANEL_DASHBOARD_TEXT"),
|
|
icon: "btn-summary dashboard-btn",
|
|
href: $scope.getDashboardLink()
|
|
}];
|
|
var links = [];
|
|
return $scope.activeVisit ? links.push({
|
|
text: $translate.instant("CONTROL_PANEL_CONSULTATION_TEXT"),
|
|
icon: "btn-consultation dashboard-btn",
|
|
href: "#" + clinicalAppConfigService.getConsultationBoardLink()
|
|
}) : state.match("patient.visit") && links.push({
|
|
text: $translate.instant("CONTROL_PANEL_DASHBOARD_TEXT"),
|
|
icon: "btn-summary dashboard-btn",
|
|
href: $scope.getDashboardLink()
|
|
}), links
|
|
};
|
|
$scope.links = getLinks();
|
|
var cleanUpListenerStateChangeSuccess = $rootScope.$on("$stateChangeSuccess", function() {
|
|
$scope.links = getLinks($state.current.name)
|
|
});
|
|
$scope.$on("$destroy", cleanUpListenerStateChangeSuccess);
|
|
var encounterTypeUuid = configurations.encounterConfig().getPatientDocumentEncounterTypeUuid();
|
|
$scope.documentsPromise = encounterService.getEncountersForEncounterType($scope.patient.uuid, encounterTypeUuid).then(function(response) {
|
|
return (new Bahmni.Clinical.PatientFileObservationsMapper).map(response.data.results)
|
|
})
|
|
};
|
|
return {
|
|
restrict: "E",
|
|
templateUrl: "patientcontrolpanel/views/controlPanel.html",
|
|
controller: controller,
|
|
scope: {
|
|
patient: "=",
|
|
visitHistory: "=",
|
|
visit: "=",
|
|
consultation: "="
|
|
}
|
|
}
|
|
}]), angular.module("bahmni.clinical").factory("initialization", ["$rootScope", "authenticator", "appService", "spinner", "configurations", "orderTypeService", "mergeService", "$q", "messagingService", function($rootScope, authenticator, appService, spinner, configurations, orderTypeService, mergeService, $q, messagingService) {
|
|
return function(config) {
|
|
var loadConfigPromise = function() {
|
|
return configurations.load(["patientConfig", "encounterConfig", "consultationNoteConfig", "labOrderNotesConfig", "radiologyImpressionConfig", "allTestsAndPanelsConcept", "dosageFrequencyConfig", "dosageInstructionConfig", "stoppedOrderReasonConfig", "genderMap", "relationshipTypeMap", "defaultEncounterType"]).then(function() {
|
|
$rootScope.genderMap = configurations.genderMap(), $rootScope.relationshipTypeMap = configurations.relationshipTypeMap(), $rootScope.diagnosisStatus = appService.getAppDescriptor().getConfig("diagnosisStatus") && appService.getAppDescriptor().getConfig("diagnosisStatus").value || "RULED OUT"
|
|
})
|
|
},
|
|
checkPrivilege = function() {
|
|
return appService.checkPrivilege("app:clinical")
|
|
},
|
|
initApp = function() {
|
|
return appService.initApp("clinical", {
|
|
app: !0,
|
|
extension: !0
|
|
}, config, ["dashboard", "visit", "medication"])
|
|
},
|
|
mergeFormConditions = function() {
|
|
var formConditions = Bahmni.ConceptSet.FormConditions;
|
|
formConditions && (formConditions.rules = mergeService.merge(formConditions.rules, formConditions.rulesOverride))
|
|
};
|
|
return spinner.forPromise(authenticator.authenticateUser().then(initApp).then(checkPrivilege).then(loadConfigPromise).then(mergeFormConditions).then(orderTypeService.loadAll))
|
|
}
|
|
}]), angular.module("bahmni.clinical").factory("ordersTabInitialization", ["conceptSetService", "spinner", function(conceptSetService, spinner) {
|
|
return function() {
|
|
var allOrderables = spinner.forPromise(conceptSetService.getConcept({
|
|
name: "All Orderables",
|
|
v: "custom:(uuid,name:(display,uuid),names:(display,conceptNameType,name),set,setMembers:(uuid,name:(display,uuid),names:(display,conceptNameType,name),set,setMembers:(uuid,name:(display,uuid),names:(display,conceptNameType,name),set,conceptClass:(uuid,name,description),setMembers:(uuid,name:(display,uuid),names:(display,conceptNameType,name),set,conceptClass:(uuid,name,description),setMembers:(uuid,name:(display,uuid),names:(display,conceptNameType,name),set,conceptClass:(uuid,name,description))))))"
|
|
})).then(function(response) {
|
|
var allOrderables = {};
|
|
return _.forEach(response.data.results[0].setMembers, function(orderable) {
|
|
var conceptName = _.find(orderable.names, {
|
|
conceptNameType: "SHORT"
|
|
}) || _.find(orderable.names, {
|
|
conceptNameType: "FULLY_SPECIFIED"
|
|
});
|
|
conceptName = conceptName ? conceptName.name : conceptName, allOrderables["'" + conceptName + "'"] = orderable
|
|
}), allOrderables
|
|
});
|
|
return allOrderables
|
|
}
|
|
}]), angular.module("bahmni.clinical").factory("bacteriologyTabInitialization", ["conceptSetService", function(conceptSetService) {
|
|
return function() {
|
|
var conceptSetName = "BACTERIOLOGY CONCEPT SET";
|
|
return conceptSetService.getConcept({
|
|
name: conceptSetName,
|
|
v: "custom:(uuid,setMembers:(uuid,name,conceptClass,answers:(uuid,name,mappings,names),setMembers:(uuid,name,conceptClass,answers:(uuid,name,mappings),setMembers:(uuid,name,conceptClass))))"
|
|
}, !0).then(function(response) {
|
|
return response.data.results[0]
|
|
})
|
|
}
|
|
}]), angular.module("bahmni.clinical").factory("patientInitialization", ["$q", "$rootScope", "patientService", "configurations", "$translate", function($q, $rootScope, patientService, configurations, $translate) {
|
|
return function(patientUuid) {
|
|
var getPatient = function() {
|
|
var patientMapper = new Bahmni.PatientMapper(configurations.patientConfig(), $rootScope, $translate);
|
|
return patientService.getPatient(patientUuid).then(function(openMRSPatientResponse) {
|
|
var patient = patientMapper.map(openMRSPatientResponse.data);
|
|
return {
|
|
patient: patient
|
|
}
|
|
})
|
|
};
|
|
return getPatient()
|
|
}
|
|
}]), angular.module("bahmni.clinical").factory("visitHistoryInitialization", ["patientVisitHistoryService", "sessionService", "locationService", function(patientVisitHistoryService, sessionService, locationService) {
|
|
return function(patientUuid) {
|
|
var loginLocationUuid = sessionService.getLoginLocationUuid();
|
|
return locationService.getVisitLocation(loginLocationUuid).then(function(response) {
|
|
var visitLocationUuid = response.data ? response.data.uuid : null;
|
|
return patientVisitHistoryService.getVisitHistory(patientUuid, visitLocationUuid)
|
|
})
|
|
}
|
|
}]), angular.module("bahmni.clinical").factory("consultationInitialization", ["$q", "diagnosisService", "$rootScope", "encounterService", "sessionService", "configurations", "$bahmniCookieStore", "retrospectiveEntryService", "conditionsService", function($q, diagnosisService, $rootScope, encounterService, sessionService, configurations, $bahmniCookieStore, retrospectiveEntryService, conditionsService) {
|
|
return function(patientUuid, encounterUuid, programUuid, enrollment, followUpConditionConcept) {
|
|
"active" === encounterUuid && (encounterUuid = void 0);
|
|
var getEncounterType = function() {
|
|
return encounterService.getEncounterType(programUuid, sessionService.getLoginLocationUuid())
|
|
},
|
|
consultationMapper = new Bahmni.ConsultationMapper(configurations.dosageFrequencyConfig(), configurations.dosageInstructionConfig(), configurations.consultationNoteConcept(), configurations.labOrderNotesConcept(), followUpConditionConcept),
|
|
dateUtil = Bahmni.Common.Util.DateUtil,
|
|
getActiveEncounter = function() {
|
|
var currentProviderUuid = $rootScope.currentProvider ? $rootScope.currentProvider.uuid : null,
|
|
providerData = $bahmniCookieStore.get(Bahmni.Common.Constants.grantProviderAccessDataCookieName);
|
|
return findEncounter(providerData, currentProviderUuid, null)
|
|
},
|
|
getRetrospectiveEncounter = function() {
|
|
var currentProviderUuid = $rootScope.currentProvider ? $rootScope.currentProvider.uuid : null,
|
|
providerData = $bahmniCookieStore.get(Bahmni.Common.Constants.grantProviderAccessDataCookieName),
|
|
encounterDateWithoutHours = dateUtil.getDateWithoutHours(retrospectiveEntryService.getRetrospectiveDate()),
|
|
encounterDate = dateUtil.parseLongDateToServerFormat(encounterDateWithoutHours);
|
|
return findEncounter(providerData, currentProviderUuid, encounterDate).then(function(consultation) {
|
|
return consultation.encounterDateTime = encounterDateWithoutHours, consultation
|
|
})
|
|
},
|
|
findEncounter = function(providerData, currentProviderUuid, encounterDate) {
|
|
return getEncounterType().then(function(encounterType) {
|
|
return encounterService.find({
|
|
patientUuid: patientUuid,
|
|
providerUuids: _.isEmpty(providerData) ? [currentProviderUuid] : [providerData.uuid],
|
|
includeAll: Bahmni.Common.Constants.includeAllObservations,
|
|
encounterDateTimeFrom: encounterDate,
|
|
encounterDateTimeTo: encounterDate,
|
|
encounterTypeUuids: [encounterType.uuid],
|
|
patientProgramUuid: enrollment,
|
|
locationUuid: $bahmniCookieStore.get(Bahmni.Common.Constants.locationCookieName).uuid
|
|
}).then(function(encounterTransactionResponse) {
|
|
return consultationMapper.map(encounterTransactionResponse.data)
|
|
})
|
|
})
|
|
},
|
|
getEncounter = function() {
|
|
return encounterUuid ? encounterService.findByEncounterUuid(encounterUuid).then(function(response) {
|
|
return consultationMapper.map(response.data)
|
|
}) : _.isEmpty($rootScope.retrospectiveEntry) ? getActiveEncounter() : getRetrospectiveEncounter()
|
|
};
|
|
return getEncounter().then(function(consultation) {
|
|
return diagnosisService.populateDiagnosisInformation(patientUuid, consultation).then(function(diagnosisConsultation) {
|
|
return diagnosisConsultation.preSaveHandler = new Bahmni.Clinical.Notifier, diagnosisConsultation.postSaveHandler = new Bahmni.Clinical.Notifier, diagnosisConsultation
|
|
})
|
|
}).then(function(consultation) {
|
|
return conditionsService.getConditions(patientUuid).then(function(conditions) {
|
|
return consultation.conditions = conditions, consultation
|
|
})
|
|
})
|
|
}
|
|
}]), angular.module("bahmni.clinical").factory("visitSummaryInitialization", ["visitService", function(visitService) {
|
|
return function(visitUuid) {
|
|
return visitUuid ? visitService.getVisitSummary(visitUuid).then(function(visitSummaryResponse) {
|
|
return new Bahmni.Common.VisitSummary(visitSummaryResponse.data)
|
|
}) : null
|
|
}
|
|
}]), Bahmni.Clinical.Constants = function() {
|
|
var orderTypes = {
|
|
lab: "Lab Order",
|
|
radiology: "Radiology Order"
|
|
},
|
|
dosingTypes = {
|
|
uniform: "uniform",
|
|
variable: "variable"
|
|
},
|
|
orderActions = {
|
|
discontinue: "DISCONTINUE",
|
|
"new": "NEW",
|
|
revise: "REVISE"
|
|
},
|
|
concepts = {
|
|
age: "Age",
|
|
weight: "Weight"
|
|
},
|
|
errorMessages = {
|
|
discontinuingAndOrderingSameDrug: "DISCONTINUING_AND_ORDERING_SAME_DRUG_NOT_ALLOWED",
|
|
incompleteForm: "INCOMPLETE_FORM_ERROR_MESSAGE",
|
|
invalidItems: "Highlighted items in New Prescription section are incomplete. Please edit or remove them to continue",
|
|
conceptNotNumeric: "CONCEPT_NOT_NUMERIC"
|
|
},
|
|
bacteriologyConstants = {
|
|
otherSampleType: "Other",
|
|
specimenSampleSourceConceptName: "Specimen Sample Source"
|
|
};
|
|
return {
|
|
patientsListUrl: "/patient/search",
|
|
diagnosisObservationConceptName: "Visit Diagnoses",
|
|
orderConceptName: "Diagnosis order",
|
|
certaintyConceptName: "Diagnosis Certainty",
|
|
nonCodedDiagnosisConceptName: "Non-coded Diagnosis",
|
|
codedDiagnosisConceptName: "Coded Diagnosis",
|
|
orderTypes: orderTypes,
|
|
labOrderType: "Lab Order",
|
|
drugOrderType: "Drug Order",
|
|
labConceptSetName: "Lab Samples",
|
|
testConceptName: "LabTest",
|
|
labSetConceptName: "LabSet",
|
|
labDepartmentsConceptSetName: "Lab Departments",
|
|
otherInvestigationsConceptSetName: "Other Investigations",
|
|
otherInvestigationCategoriesConceptSetName: "Other Investigations Categories",
|
|
commentConceptName: "COMMENTS",
|
|
messageForNoLabOrders: "NO_LAB_ORDERS_MESSAGE",
|
|
messageForNoObservation: "NO_OBSERVATIONS_CAPTURED",
|
|
messageForNoActiveVisit: "NO_ACTIVE_VISIT_MESSAGE",
|
|
dischargeSummaryConceptName: "Discharge Summary",
|
|
flexibleDosingInstructionsClass: "org.openmrs.module.bahmniemrapi.drugorder.dosinginstructions.FlexibleDosingInstructions",
|
|
reviseAction: "REVISE",
|
|
asDirectedInstruction: "As directed",
|
|
dosingTypes: dosingTypes,
|
|
orderActions: orderActions,
|
|
errorMessages: errorMessages,
|
|
caseIntakeConceptClass: "Case Intake",
|
|
dialog: "DIALOG",
|
|
dashboard: "DASHBOARD",
|
|
"default": "DEFAULT",
|
|
gender: "Gender",
|
|
concepts: concepts,
|
|
otherActiveDrugOrders: "Other Active DrugOrders",
|
|
dispensePrivilege: "bahmni:clinical:dispense",
|
|
mandatoryVisitConfigUrl: "config/visitMandatoryTab.json",
|
|
defaultExtensionName: "default",
|
|
bacteriologyConstants: bacteriologyConstants,
|
|
globalPropertyToFetchActivePatients: "emrapi.sqlSearch.activePatients",
|
|
adtPrivilege: "app:adt",
|
|
adtForwardUrl: "../adt/#/patient/{{patientUuid}}/visit/{{visitUuid}}/"
|
|
}
|
|
}(), angular.module("consultation", ["ui.router", "bahmni.clinical", "bahmni.common.config", "bahmni.common.patient", "bahmni.common.uiHelper", "bahmni.common.patientSearch", "bahmni.common.obs", "bahmni.common.i18n", "bahmni.common.domain", "bahmni.common.conceptSet", "authentication", "bahmni.common.appFramework", "bahmni.common.displaycontrol.documents", "bahmni.common.displaycontrol.observation", "bahmni.common.displaycontrol.pivottable", "bahmni.common.displaycontrol.dashboard", "bahmni.common.gallery", "bahmni.common.displaycontrol.disposition", "bahmni.common.displaycontrol.custom", "bahmni.common.displaycontrol.admissiondetails", "bahmni.common.routeErrorHandler", "bahmni.common.displaycontrol.disposition", "httpErrorInterceptor", "pasvaz.bindonce", "infinite-scroll", "bahmni.common.util", "ngAnimate", "ngDialog", "bahmni.common.displaycontrol.patientprofile", "bahmni.common.displaycontrol.diagnosis", "bahmni.common.displaycontrol.conditionsList", "RecursionHelper", "ngSanitize", "bahmni.common.orders", "bahmni.common.displaycontrol.orders", "bahmni.common.displaycontrol.prescription", "bahmni.common.displaycontrol.navigationlinks", "bahmni.common.displaycontrol.programs", "bahmni.common.displaycontrol.pacsOrders", "bahmni.common.uicontrols", "bahmni.common.uicontrols.programmanagment", "pascalprecht.translate", "ngCookies", "monospaced.elastic", "bahmni.common.bacteriologyresults", "bahmni.common.displaycontrol.bacteriologyresults", "bahmni.common.displaycontrol.obsVsObsFlowSheet", "bahmni.common.displaycontrol.chronicTreatmentChart", "bahmni.common.displaycontrol.forms", "bahmni.common.displaycontrol.drugOrderDetails", "bahmni.common.displaycontrol.hint", "bahmni.common.displaycontrol.drugOrdersSection", "bahmni.common.attributeTypes", "bahmni.common.services", "bahmni.common.models"]), angular.module("consultation").config(["$stateProvider", "$httpProvider", "$urlRouterProvider", "$bahmniTranslateProvider", "$compileProvider", function($stateProvider, $httpProvider, $urlRouterProvider, $bahmniTranslateProvider, $compileProvider) {
|
|
$urlRouterProvider.otherwise("/" + Bahmni.Clinical.Constants.defaultExtensionName + "/patient/search");
|
|
var patientSearchBackLink = {
|
|
label: "",
|
|
state: "search.patientsearch",
|
|
accessKey: "p",
|
|
id: "patients-link",
|
|
icon: "fa-users"
|
|
},
|
|
homeBackLink = {
|
|
label: "",
|
|
url: "../home/index.html",
|
|
accessKey: "h",
|
|
icon: "fa-home"
|
|
};
|
|
$compileProvider.debugInfoEnabled(!1), $stateProvider.state("search", {
|
|
"abstract": !0,
|
|
views: {
|
|
content: {
|
|
template: '<div ui-view="patientSearchPage-header"></div> <div ui-view="patientSearchPage-content"></div>'
|
|
}
|
|
},
|
|
data: {
|
|
backLinks: [homeBackLink]
|
|
},
|
|
resolve: {
|
|
retrospectiveIntialization: function(retrospectiveEntryService) {
|
|
return retrospectiveEntryService.initializeRetrospectiveEntry()
|
|
}
|
|
}
|
|
}).state("search.patientsearch", {
|
|
url: "/:configName/patient/search",
|
|
views: {
|
|
"patientSearchPage-header": {
|
|
templateUrl: "../common/ui-helper/header.html",
|
|
controller: "PatientListHeaderController"
|
|
},
|
|
"patientSearchPage-content": {
|
|
templateUrl: "../common/patient-search/views/patientsList.html",
|
|
controller: "PatientsListController"
|
|
}
|
|
},
|
|
resolve: {
|
|
initializeConfigs: function(initialization, $stateParams) {
|
|
return $stateParams.configName = $stateParams.configName || Bahmni.Clinical.Constants.defaultExtensionName, patientSearchBackLink.state = 'search.patientsearch({configName: "' + $stateParams.configName + '"})', initialization($stateParams.configName)
|
|
}
|
|
}
|
|
}).state("patient", {
|
|
url: "/:configName/patient/:patientUuid?encounterUuid,programUuid,enrollment",
|
|
"abstract": !0,
|
|
data: {
|
|
backLinks: [patientSearchBackLink]
|
|
},
|
|
views: {
|
|
content: {
|
|
template: '<div ui-view="content"></div>',
|
|
controller: function($scope, patientContext) {
|
|
$scope.patient = patientContext.patient
|
|
}
|
|
}
|
|
},
|
|
resolve: {
|
|
initialization: function(initialization, $stateParams) {
|
|
return $stateParams.configName = $stateParams.configName || Bahmni.Clinical.Constants.defaultExtensionName, patientSearchBackLink.state = 'search.patientsearch({configName: "' + $stateParams.configName + '"})', initialization($stateParams.configName)
|
|
},
|
|
patientContext: function(initialization, patientInitialization, $stateParams) {
|
|
return patientInitialization($stateParams.patientUuid)
|
|
}
|
|
}
|
|
}).state("patient.dashboard", {
|
|
"abstract": !0,
|
|
views: {
|
|
content: {
|
|
template: '<div ui-view="dashboard-header"></div> <div ui-view="dashboard-content"></div><patient-control-panel patient="patient" visit-history="visitHistory" visit="visit" show="showControlPanel" consultation="consultation"/>',
|
|
controller: function($scope, visitHistory, consultationContext, followUpConditionConcept) {
|
|
$scope.visitHistory = visitHistory, $scope.consultation = consultationContext, $scope.followUpConditionConcept = followUpConditionConcept, $scope.lastConsultationTabUrl = {
|
|
url: void 0
|
|
}
|
|
}
|
|
}
|
|
},
|
|
resolve: {
|
|
visitHistory: function(visitHistoryInitialization, $stateParams, $rootScope) {
|
|
return visitHistoryInitialization($stateParams.patientUuid, $rootScope.visitLocation)
|
|
},
|
|
retrospectiveIntialization: function(retrospectiveEntryService) {
|
|
return retrospectiveEntryService.initializeRetrospectiveEntry()
|
|
},
|
|
followUpConditionConcept: function(conditionsService) {
|
|
return conditionsService.getFollowUpConditionConcept().then(function(response) {
|
|
return response.data.results[0]
|
|
})
|
|
},
|
|
consultationContext: function(consultationInitialization, initialization, $stateParams, followUpConditionConcept) {
|
|
return consultationInitialization($stateParams.patientUuid, $stateParams.encounterUuid, $stateParams.programUuid, $stateParams.enrollment, followUpConditionConcept)
|
|
},
|
|
dashboardInitialization: function($rootScope, initialization, patientContext, clinicalDashboardConfig, userService) {
|
|
return clinicalDashboardConfig.load().then(function() {
|
|
return $rootScope.currentUser.addToRecentlyViewed(patientContext.patient, clinicalDashboardConfig.getMaxRecentlyViewedPatients()), userService.savePreferences()
|
|
})
|
|
},
|
|
visitSummary: function(visitSummaryInitialization, initialization, visitHistory) {
|
|
return visitHistory.activeVisit ? visitSummaryInitialization(visitHistory.activeVisit.uuid) : null
|
|
},
|
|
visitConfig: function(initialization, visitTabConfig) {
|
|
return visitTabConfig.load()
|
|
}
|
|
}
|
|
}).state("patient.dashboard.show", {
|
|
url: "/dashboard?dateEnrolled,dateCompleted",
|
|
params: {
|
|
dashboardCachebuster: null
|
|
},
|
|
views: {
|
|
"dashboard-header": {
|
|
templateUrl: "dashboard/views/clinicalDashboardHeader.html",
|
|
controller: "ConsultationController"
|
|
},
|
|
"dashboard-content": {
|
|
templateUrl: "dashboard/views/dashboard.html",
|
|
controller: "PatientDashboardController"
|
|
}
|
|
}
|
|
}).state("patient.dashboard.show.observations", {
|
|
url: "/concept-set-group/:conceptSetGroupName",
|
|
params: {
|
|
cachebuster: null,
|
|
lastOpenedTemplate: null
|
|
},
|
|
views: {
|
|
"consultation-content": {
|
|
templateUrl: "consultation/views/conceptSet.html",
|
|
controller: "ConceptSetPageController"
|
|
}
|
|
}
|
|
}).state("patient.dashboard.show.diagnosis", {
|
|
url: "/diagnosis",
|
|
params: {
|
|
cachebuster: null
|
|
},
|
|
views: {
|
|
"consultation-content": {
|
|
templateUrl: "consultation/views/diagnosis.html",
|
|
controller: "DiagnosisController"
|
|
}
|
|
}
|
|
}).state("patient.dashboard.show.treatment", {
|
|
"abstract": !0,
|
|
params: {
|
|
tabConfigName: null
|
|
},
|
|
resolve: {
|
|
treatmentConfig: function(initialization, treatmentConfig, $stateParams) {
|
|
return treatmentConfig($stateParams.tabConfigName)
|
|
}
|
|
},
|
|
views: {
|
|
"consultation-content": {
|
|
controller: "TreatmentController",
|
|
templateUrl: "consultation/views/treatment.html"
|
|
}
|
|
}
|
|
}).state("patient.dashboard.show.treatment.page", {
|
|
url: "/treatment?tabConfigName",
|
|
params: {
|
|
cachebuster: null
|
|
},
|
|
resolve: {
|
|
activeDrugOrders: function(treatmentService, $stateParams) {
|
|
return treatmentService.getActiveDrugOrders($stateParams.patientUuid, $stateParams.dateEnrolled, $stateParams.dateCompleted)
|
|
}
|
|
},
|
|
views: {
|
|
addTreatment: {
|
|
controller: "AddTreatmentController",
|
|
templateUrl: "consultation/views/treatmentSections/addTreatment.html",
|
|
resolve: {
|
|
treatmentConfig: "treatmentConfig"
|
|
}
|
|
},
|
|
defaultHistoryView: {
|
|
controller: "DrugOrderHistoryController",
|
|
templateUrl: "consultation/views/treatmentSections/drugOrderHistory.html"
|
|
},
|
|
customHistoryView: {
|
|
controller: "CustomDrugOrderHistoryController",
|
|
templateUrl: "consultation/views/treatmentSections/customDrugOrderHistory.html"
|
|
}
|
|
}
|
|
}).state("patient.dashboard.show.disposition", {
|
|
url: "/disposition",
|
|
params: {
|
|
cachebuster: null
|
|
},
|
|
views: {
|
|
"consultation-content": {
|
|
templateUrl: "consultation/views/disposition.html",
|
|
controller: "DispositionController"
|
|
}
|
|
}
|
|
}).state("patient.dashboard.show.summary", {
|
|
url: "/consultation",
|
|
params: {
|
|
cachebuster: null
|
|
},
|
|
views: {
|
|
"consultation-content": {
|
|
templateUrl: "consultation/views/consultation.html",
|
|
controller: "ConsultationSummaryController"
|
|
}
|
|
}
|
|
}).state("patient.dashboard.show.orders", {
|
|
url: "/orders",
|
|
params: {
|
|
cachebuster: null
|
|
},
|
|
views: {
|
|
"consultation-content": {
|
|
templateUrl: "consultation/views/orders.html",
|
|
controller: "OrderController"
|
|
}
|
|
},
|
|
resolve: {
|
|
allOrderables: function(ordersTabInitialization) {
|
|
return ordersTabInitialization()
|
|
}
|
|
}
|
|
}).state("patient.dashboard.show.bacteriology", {
|
|
url: "/bacteriology",
|
|
params: {
|
|
cachebuster: null
|
|
},
|
|
views: {
|
|
"consultation-content": {
|
|
templateUrl: "consultation/views/bacteriology.html",
|
|
controller: "BacteriologyController"
|
|
}
|
|
},
|
|
resolve: {
|
|
bacteriologyConceptSet: function(bacteriologyTabInitialization) {
|
|
return bacteriologyTabInitialization()
|
|
}
|
|
}
|
|
}).state("patient.dashboard.show.investigation", {
|
|
url: "/investigation",
|
|
params: {
|
|
cachebuster: null
|
|
},
|
|
views: {
|
|
"consultation-content": {
|
|
templateUrl: "consultation/views/investigations.html",
|
|
controller: "InvestigationController"
|
|
}
|
|
}
|
|
}).state("patient.visit", {
|
|
"abstract": !0,
|
|
views: {
|
|
content: {
|
|
template: '<div ui-view="visit-content"></div>',
|
|
controller: function($scope, visitHistory) {
|
|
$scope.visitHistory = visitHistory
|
|
}
|
|
}
|
|
},
|
|
resolve: {
|
|
visitHistory: function(visitHistoryInitialization, $stateParams) {
|
|
return visitHistoryInitialization($stateParams.patientUuid)
|
|
}
|
|
}
|
|
}).state("patient.visit.summaryprint", {
|
|
url: "/latest-prescription-print",
|
|
views: {
|
|
"visit-content": {
|
|
controller: "LatestPrescriptionPrintController"
|
|
}
|
|
}
|
|
}).state("patient.dashboard.visit", {
|
|
url: "/dashboard/visit/:visitUuid/:tab",
|
|
data: {
|
|
backLinks: [patientSearchBackLink]
|
|
},
|
|
views: {
|
|
"dashboard-header": {
|
|
templateUrl: "common/views/visitHeader.html",
|
|
controller: "VisitHeaderController"
|
|
},
|
|
"dashboard-content": {
|
|
templateUrl: "common/views/visit.html",
|
|
controller: "VisitController"
|
|
}
|
|
},
|
|
resolve: {
|
|
visitSummary: function(visitSummaryInitialization, $stateParams) {
|
|
return visitSummaryInitialization($stateParams.visitUuid)
|
|
}
|
|
}
|
|
}).state("patient.dashboard.visitPrint", {
|
|
url: "/dashboard/visit/:visitUuid/:tab/:print",
|
|
views: {
|
|
"dashboard-content": {
|
|
template: "<div>Print is getting ready</div>",
|
|
controller: "VisitController"
|
|
},
|
|
"print-content": {
|
|
templateUrl: "common/views/visit.html"
|
|
}
|
|
},
|
|
resolve: {
|
|
visitSummary: function(visitSummaryInitialization, $stateParams) {
|
|
return visitSummaryInitialization($stateParams.visitUuid)
|
|
}
|
|
}
|
|
}).state("patient.dashboard.observation", {
|
|
url: "/dashboard/observation/:observationUuid",
|
|
data: {
|
|
backLinks: [homeBackLink]
|
|
},
|
|
resolve: {
|
|
observation: function(observationsService, $stateParams) {
|
|
return observationsService.getRevisedObsByUuid($stateParams.observationUuid).then(function(results) {
|
|
return results.data
|
|
})
|
|
}
|
|
},
|
|
views: {
|
|
"dashboard-header": {
|
|
templateUrl: "../common/ui-helper/header.html",
|
|
controller: "PatientListHeaderController"
|
|
},
|
|
"dashboard-content": {
|
|
controller: function($scope, observation, patientContext) {
|
|
$scope.observation = observation, $scope.patient = patientContext.patient
|
|
},
|
|
template: '<patient-context patient="patient"></patient-context><edit-observation observation="observation" concept-set-name="{{observation.concept.name}}" concept-display-name="{{observation.conceptNameToDisplay}}"></edit-observation>'
|
|
}
|
|
}
|
|
}).state("patient.dahsboard.visit.tab", {
|
|
url: "/:tab",
|
|
data: {
|
|
backLinks: [patientSearchBackLink]
|
|
},
|
|
views: {
|
|
"additional-header": {
|
|
templateUrl: "common/views/visitHeader.html",
|
|
controller: "VisitHeaderController"
|
|
},
|
|
content: {
|
|
templateUrl: "common/views/visit.html",
|
|
controller: "VisitController"
|
|
}
|
|
},
|
|
resolve: {
|
|
visitSummary: function(visitSummaryInitialization, $stateParams) {
|
|
return visitSummaryInitialization($stateParams.visitUuid, $stateParams.tab)
|
|
},
|
|
visitConfig: function(initialization, visitTabConfig) {
|
|
return visitTabConfig.load()
|
|
}
|
|
}
|
|
}).state("patient.patientProgram", {
|
|
"abstract": !0,
|
|
views: {
|
|
content: {
|
|
template: '<div ui-view="patientProgram-header"></div> <div ui-view="patientProgram-content" class="patientProgram-content-container"></div>'
|
|
}
|
|
},
|
|
resolve: {
|
|
retrospectiveIntialization: function(retrospectiveEntryService) {
|
|
return retrospectiveEntryService.initializeRetrospectiveEntry()
|
|
}
|
|
}
|
|
}).state("patient.patientProgram.show", {
|
|
url: "/consultationContext",
|
|
data: {
|
|
backLinks: [patientSearchBackLink]
|
|
},
|
|
views: {
|
|
"patientProgram-header": {
|
|
templateUrl: "../common/ui-helper/header.html",
|
|
controller: "PatientListHeaderController"
|
|
},
|
|
"patientProgram-content": {
|
|
templateUrl: "common/views/consultationContext.html",
|
|
controller: "consultationContextController"
|
|
}
|
|
},
|
|
resolve: {
|
|
visitHistory: function(visitHistoryInitialization, $stateParams) {
|
|
return visitHistoryInitialization($stateParams.patientUuid)
|
|
}
|
|
}
|
|
}), $httpProvider.defaults.headers.common["Disable-WWW-Authenticate"] = !0, $bahmniTranslateProvider.init({
|
|
app: "clinical",
|
|
shouldMerge: !0
|
|
})
|
|
}]).run(["stateChangeSpinner", "$rootScope", "auditLogService", "$window", function(stateChangeSpinner, $rootScope, auditLogService, $window) {
|
|
moment.locale($window.localStorage.NG_TRANSLATE_LANG_KEY || "en"), FastClick.attach(document.body), stateChangeSpinner.activate();
|
|
var cleanUpStateChangeSuccess = $rootScope.$on("$stateChangeSuccess", function(event, toState, toParams) {
|
|
auditLogService.log(toParams.patientUuid, Bahmni.Clinical.StateNameEvenTypeMap[toState.name], void 0, "MODULE_LABEL_CLINICAL_KEY"), $window.scrollTo(0, 0)
|
|
}),
|
|
cleanUpNgDialogOpened = $rootScope.$on("ngDialog.opened", function() {
|
|
$("html").addClass("ngdialog-open")
|
|
}),
|
|
cleanUpNgDialogClosing = $rootScope.$on("ngDialog.closing", function() {
|
|
$("html").removeClass("ngdialog-open")
|
|
});
|
|
$rootScope.$on("$destroy", function() {
|
|
cleanUpStateChangeSuccess(), cleanUpNgDialogOpened(), cleanUpNgDialogClosing()
|
|
})
|
|
}]); |