=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry-controller.js' --- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry-controller.js 2016-01-07 19:39:37 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry-controller.js 2016-01-07 21:16:02 +0000 @@ -53,6 +53,7 @@ $scope.hiddenSections = {}; $scope.tableMaxNumberOfDataElements = 7; $scope.xVisitScheduleDataElement = false; + $scope.eventsLoaded = false; //Labels @@ -352,7 +353,8 @@ TrackerRulesFactory.getRules($scope.selectedProgram.id).then(function(rules){ $scope.allProgramRules = rules; - $scope.getEvents(); + $scope.getEvents(); + $scope.getEventPageForEvent($scope.currentEvent); $rootScope.$broadcast('dataEntryControllerData', {programStages: $scope.programStages, eventsByStage: $scope.eventsByStage, addNewEvent: $scope.addNewEvent }); }); }); @@ -421,6 +423,7 @@ $scope.allEventsSorted = orderByFilter($scope.allEventsSorted, '-sortingDate').reverse(); sortEventsByStage(null); $scope.showDataEntry($scope.currentEvent, true); + $scope.eventsLoaded = true; } }; @@ -495,7 +498,7 @@ if (stage.displayEventsInTable) { return true; } - + if ($scope.eventsByStage[stage.id].length === 0) { return true; } @@ -513,6 +516,28 @@ return false; }; + $scope.creatableStagesExist = function(stageList) { + if(stageList && stageList.length > 0) { + return true; + } + + return false; + }; + + $scope.neverShowStageTasksInTopLine = {}; + $scope.displayStageTasksInTopLine = function(stage) { + if($scope.neverShowStageTasksInTopLine[stage.id]){ + return false; + } + + return $scope.stageNeedsEvent(stage); + }; + + $scope.showStageTasks = false; + $scope.toggleShowStageTasks = function(){ + $scope.showStageTasks = !$scope.showStageTasks; + }; + $scope.addNewEvent = function(newEvent) { //Have to make sure the event is preprocessed - this does not happen unless "Dashboardwidgets" is invoked. newEvent = EventUtils.processEvent(newEvent, $scope.stagesById[newEvent.programStage], $scope.optionSets, $scope.prStDes); @@ -522,29 +547,31 @@ sortEventsByStage('ADD', newEvent); }; - $scope.showCreateEvent = function (stage, eventCreationAction) { - - var stages = []; + $scope.showCreateEvent = function (stage, eventCreationAction) { + + var availableStages = []; if(!stage){ if(!$scope.allEventsSorted || $scope.allEventsSorted.length === 0){ - stages = $scope.programStages; - } - for(var key in $scope.eventsByStage){ - var st = $scope.stagesById[key]; - var needEvent = true; - if(st && st.repeatable){ - for (var j = 0; j < $scope.eventsByStage[st.id].length; j++) { - if (!$scope.eventsByStage[st.id][j].eventDate && $scope.eventsByStage[st.id][j].status !== 'SKIPPED') { - needEvent = false; - } - } - if(needEvent){ - stages.push(st); - } - } - } - } - + availableStages = $scope.programStages; + } + else{ + angular.forEach($scope.programStages, function(stage){ + if($scope.stageNeedsEvent(stage)){ + availableStages.push(stage); + } + }); + } + if(availableStages.length === 0) { + var dialogOptions = { + headerText: 'error', + bodyText: 'no_stages_available' + }; + + DialogService.showDialog({}, dialogOptions); + + return; + } + } var modalInstance = $modal.open({ templateUrl: 'components/dataentry/new-event.html', @@ -557,7 +584,10 @@ return stage; }, stages: function(){ - return stages; + return availableStages; + }, + allStages: function(){ + return $scope.programStages; }, tei: function(){ return $scope.selectedEntity; @@ -577,32 +607,45 @@ }, eventCreationAction: function(){ return eventCreationAction; - } + }, + events: function(){ + return $scope.allEventsSorted; + } } }); - - modalInstance.result.then(function (dummyEvent, ev) { - if (angular.isObject(ev) && angular.isObject(dummyEvent)) { - - var newEvent = ev; - newEvent.orgUnitName = dummyEvent.orgUnitName; - newEvent.name = dummyEvent.name; - newEvent.excecutionDateLabel = dummyEvent.excecutionDateLabel; - newEvent.sortingDate = ev.eventDate ? ev.eventDate : ev.dueDate, - newEvent.statusColor = EventUtils.getEventStatusColor(ev); - newEvent.eventDate = DateUtils.formatFromApiToUser(ev.eventDate); - newEvent.dueDate = DateUtils.formatFromApiToUser(ev.dueDate); - newEvent.enrollmentStatus = dummyEvent.enrollmentStatus; - - if (dummyEvent.coordinate) { - newEvent.coordinate = {}; + + modalInstance.result.then(function (eventContainer) { + + if(angular.isDefined(eventContainer)){ + var ev = eventContainer.ev; + var dummyEvent = eventContainer.dummyEvent; + + if (angular.isObject(ev) && angular.isObject(dummyEvent)) { + + var newEvent = ev; + newEvent.orgUnitName = dummyEvent.orgUnitName; + newEvent.name = dummyEvent.name; + newEvent.excecutionDateLabel = dummyEvent.excecutionDateLabel; + newEvent.sortingDate = ev.eventDate ? ev.eventDate : ev.dueDate, + newEvent.statusColor = EventUtils.getEventStatusColor(ev); + newEvent.eventDate = DateUtils.formatFromApiToUser(ev.eventDate); + newEvent.dueDate = DateUtils.formatFromApiToUser(ev.dueDate); + newEvent.enrollmentStatus = dummyEvent.enrollmentStatus; + + if (dummyEvent.coordinate) { + newEvent.coordinate = {}; + } + + //get stage from created event + $scope.currentStage = $scope.stagesById[dummyEvent.programStage]; + + $scope.addNewEvent(newEvent); + + $scope.currentEvent = null; + $scope.showDataEntry(newEvent, true); + //show page with event in event-layout + $scope.getEventPageForEvent(newEvent); } - - $scope.currentStage = stage; - $scope.addNewEvent(newEvent); - - $scope.currentEvent = null; - $scope.showDataEntry(newEvent, true); } }, function () { }); @@ -628,7 +671,7 @@ } } if(index !== -1){ - $scope.currentEvent = $scope.eventsByStage[event.programStage][index]; + $scope.currentEvent = $scope.eventsByStage[event.programStage][index]; } $scope.showDataEntryDiv = true; @@ -909,13 +952,17 @@ var i = item; }; - $scope.saveDataValueForEvent = function (prStDe, field, eventToSave, suppressRulesExecution) { - //Blank out the input-saved class on the last saved due date: - $scope.eventDateSaved = false; - $scope.currentElement = {id: prStDe.dataElement.id, pending: true, saved: false, failed: false, event: eventToSave.event}; - - //check for input validity - $scope.updateSuccess = false; + $scope.saveDataValueForEvent = function (prStDe, field, eventToSave, backgroundUpdate) { + + //Do not change the input notification variables for background updates + if(!backgroundUpdate) { + //Blank out the input-saved class on the last saved due date: + $scope.eventDateSaved = false; + + //check for input validity + $scope.updateSuccess = false; + } + if (field && field.$invalid) { return false; } @@ -934,10 +981,12 @@ value = CommonUtils.formatDataValue(value, prStDe.dataElement, $scope.optionSets, 'API'); - $scope.updateSuccess = false; - - $scope.currentElement = {id: prStDe.dataElement.id, event: eventToSave.event, saved: false}; - + //Do not change the input notification variables for background updates + if(!backgroundUpdate) { + $scope.updateSuccess = false; + $scope.currentElement = {id: prStDe.dataElement.id, event: eventToSave.event, saved: false, failed:false, pending:true}; + } + var ev = {event: eventToSave.event, orgUnit: eventToSave.orgUnit, program: eventToSave.program, @@ -954,9 +1003,11 @@ }; return DHIS2EventFactory.updateForSingleValue(ev).then(function (response) { - $scope.currentElement.saved = true; - $scope.currentElement.pending = false; - $scope.currentElement.failed = false; + if(!backgroundUpdate) { + $scope.currentElement.saved = true; + $scope.currentElement.pending = false; + $scope.currentElement.failed = false; + } $scope.currentEventOriginal = angular.copy($scope.currentEvent); @@ -965,10 +1016,20 @@ //In some cases, the rules execution should be suppressed to avoid the //possibility of infinite loops(rules updating datavalues, that triggers a new //rule execution) - if(!suppressRulesExecution) { + if(!backgroundUpdate) { //Run rules on updated data: $scope.executeRules(); } + }, function(error) { + //Do not change the input notification variables for background updates + if(!backgroundUpdate) { + $scope.currentElement.saved = false; + $scope.currentElement.pending = false; + $scope.currentElement.failed = true; + } else { + $log.warn("Could not perform background update of " + prStDe.dataElement.id + " with value " + + value); + } }); } @@ -1002,8 +1063,8 @@ } }; - $scope.saveEventDate = function () { - $scope.saveEventDateForEvent($scope.currentEvent); + $scope.saveEventDate = function () { + $scope.saveEventDateForEvent($scope.currentEvent); }; $scope.saveEventDateForEvent = function (eventToSave) { @@ -1047,6 +1108,7 @@ $scope.validatedDateSetForEvent = {date: eventToSave.eventDate, event: eventToSave}; $scope.currentElement = {id: "eventDate", event: eventToSave.event, saved: true}; $scope.executeRules(); + $scope.getEventPageForEvent($scope.currentEvent); }, function(error){ }); @@ -1099,8 +1161,9 @@ $scope.currentEvent.statusColor = EventUtils.getEventStatusColor($scope.currentEvent); $scope.schedulingEnabled = !$scope.schedulingEnabled; sortEventsByStage('UPDATE'); - }); - + $scope.getEventPageForEvent($scope.currentEvent); + }); + }; $scope.saveCoordinate = function (type) { @@ -1556,6 +1619,24 @@ } var programStageID = $scope.currentEvent.programStage; + + $scope.eventsByStage[programStageID].splice(index, 1); + $scope.currentStageEvents = $scope.eventsByStage[programStageID]; + + //if event is last event in allEventsSorted and only element on page, show previous page + var GetPreviousEventPage = false; + if($scope.allEventsSorted[$scope.allEventsSorted.length-1].event === $scope.currentEvent.event){ + var index = $scope.allEventsSorted.length - 1; + if(index !== 0){ + if(index % $scope.eventPageSize === 0){ + GetPreviousEventPage = true; + } + } + } + sortEventsByStage('REMOVE'); + if(GetPreviousEventPage){ + $scope.getEventPage("BACKWARD"); + } if($scope.displayCustomForm === "TABLE"){ $scope.currentEvent = {}; @@ -1563,10 +1644,7 @@ else { $scope.currentEvent = null; } - - $scope.eventsByStage[programStageID].splice(index, 1); - $scope.currentStageEvents = $scope.eventsByStage[programStageID]; - sortEventsByStage('REMOVE'); + }, function(error){ return $q.reject(error); }); @@ -1745,7 +1823,23 @@ } $scope.showDataEntry($scope.allEventsSorted[$scope.eventPagingStart], false); - }; + }; + + $scope.getEventPageForEvent = function(event){ + var index = -1; + for(i = 0; i < $scope.allEventsSorted.length; i++){ + if(event.event === $scope.allEventsSorted[i].event){ + index = i; + break; + } + } + + if(index !== -1){ + var page = Math.floor(index / $scope.eventPageSize); + $scope.eventPagingStart = page * $scope.eventPageSize; + $scope.eventPagingEnd = $scope.eventPagingStart + $scope.eventPageSize; + } + } $scope.deselectCurrent = function(id){ === modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry.html' --- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry.html 2015-12-30 02:55:18 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry.html 2016-01-07 21:16:02 +0000 @@ -3,9 +3,9 @@
{{dataentryWidget.title| translate}} - + === modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/default-form.html' --- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/default-form.html 2016-01-05 20:54:16 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/default-form.html 2016-01-07 21:16:02 +0000 @@ -1,4 +1,4 @@ -
+ @@ -10,7 +10,7 @@ - +
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/event-layout.html' --- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/event-layout.html 2015-12-28 20:44:17 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/event-layout.html 2016-01-07 21:16:02 +0000 @@ -1,23 +1,93 @@ -
-
-
-
+
+
+
+
 
{{'previous'| translate}}
-
+
{{dhis2Event.sortingDate}}
{{dhis2Event.orgUnitName.length > 15 ? dhis2Event.orgUnitName.substring(0,15).concat('...') : dhis2Event.orgUnitName}}
- {{dhis2Event.name.length > 15 ? dhis2Event.name.substring(0,15).concat('...') : dhis2Event.name}} + {{dhis2Event.name.length > 15 ? dhis2Event.name.substring(0,15).concat('...') : dhis2Event.name}}
-
+
-
+
 
{{'next'| translate}}
-
+
+
+
+
+
{{'new_event' | translate}} + + + + + +
+
+
+
+
{{stage.name}}
+ +
+
+
{{'no_stages_available'| translate}}
+
+
+
+ + + + +
{{'no_events_exist'| translate}}
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/new-event-controller.js' --- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/new-event-controller.js 2015-12-21 13:28:07 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/new-event-controller.js 2016-01-07 21:16:02 +0000 @@ -13,20 +13,26 @@ eventsByStage, stage, stages, + allStages, tei, program, orgUnit, enrollment, eventCreationAction, autoCreate, - EventUtils) { + EventUtils, + events) { $scope.stages = stages; + $scope.allStages = allStages; + $scope.events = events; $scope.eventCreationAction = eventCreationAction; $scope.eventCreationActions = EventCreationService.eventCreationActions; $scope.isNewEvent = (eventCreationAction === $scope.eventCreationActions.add); $scope.isScheduleEvent = (eventCreationAction === $scope.eventCreationActions.schedule || eventCreationAction === $scope.eventCreationActions.referral); $scope.isReferralEvent = (eventCreationAction === $scope.eventCreationActions.referral); $scope.model = {selectedStage: stage, dueDateInvalid: false, eventDateInvalid: false}; + $scope.stageSpecifiedOnModalOpen = angular.isObject(stage) ? true : false; + var orgPath = []; var dummyEvent = {}; @@ -35,33 +41,101 @@ dummyEvent = EventUtils.createDummyEvent(eventsByStage[stage.id], tei, program, stage, orgUnit, enrollment); $scope.newEvent = {programStage: stage}; - $scope.dhis2Event = {eventDate: $scope.isScheduleEvent ? '' : DateUtils.getToday(), dueDate: dummyEvent.dueDate, excecutionDateLabel : dummyEvent.excecutionDateLabel, name: dummyEvent.name, invalid: true}; - - //custom code for folkehelsa. Set empty eventDate if selectedStage is previous pregnancies - if($scope.model.selectedStage.id === 'PUZaKR0Jh2k'){ - $scope.dhis2Event.eventDate = ''; - } + $scope.dhis2Event = {eventDate: $scope.isScheduleEvent ? '' : DateUtils.getToday(), dueDate: dummyEvent.dueDate, excecutionDateLabel : dummyEvent.excecutionDateLabel, name: dummyEvent.name, invalid: true}; if ($scope.model.selectedStage.periodType) { $scope.dhis2Event.eventDate = dummyEvent.dueDate; $scope.dhis2Event.periodName = dummyEvent.periodName; $scope.dhis2Event.periods = dummyEvent.periods; $scope.dhis2Event.selectedPeriod = dummyEvent.periods[0]; - } - - orgPath.push(dummyEvent.orgUnit); - }; - - if($scope.model.selectedStage){ - prepareEvent(); + } + }; + + function suggestStage(){ + var suggestedStage; + var events = $scope.events; + var allStages = $scope.allStages; + + var availableStagesOrdered = $scope.stages.slice(); + availableStagesOrdered.sort(function (a,b){ + return a.sortOrder - b.sortOrder; + }); + + var stagesById = []; + + if(angular.isUndefined(events) || events.length === 0){ + suggestedStage = availableStagesOrdered[0]; + } + else{ + angular.forEach(allStages, function(stage){ + stagesById[stage.id] = stage; + }); + + var lastStageForEvents; + for(i = 0; i < events.length; i++){ + var event = events[i]; + var eventStage = stagesById[event.programStage]; + if(i > 0){ + if(eventStage.sortOrder > lastStageForEvents.sortOrder){ + lastStageForEvents = eventStage; + } + else if(eventStage.sortOrder === lastStageForEvents.sortOrder){ + if(eventStage.id !== lastStageForEvents.id){ + if(eventStage.name.localeCompare(lastStageForEvents.name) > 0){ + lastStageForEvents = eventStage; + } + } + } + } + else { + lastStageForEvents = eventStage; + } + } + + for(j = 0; j < availableStagesOrdered.length; j++){ + var availableStage = availableStagesOrdered[j]; + + if(availableStage.id === lastStageForEvents.id){ + suggestedStage = availableStage; + break; + } + else if(availableStage.sortOrder === lastStageForEvents.sortOrder){ + if(availableStage.name.localeCompare(lastStageForEvents.name) > 0){ + suggestedStage = availableStage; + break; + } + } + else if(availableStage.sortOrder > lastStageForEvents.sortOrder){ + suggestedStage = availableStage; + break; + } + } + + if(angular.isUndefined(suggestedStage)){ + suggestedStage = availableStagesOrdered[availableStagesOrdered.length - 1]; + } + } + + $scope.model.selectedStage = suggestedStage; + stage = $scope.model.selectedStage; + }; + + if(!$scope.stageSpecifiedOnModalOpen){ + //suggest stage + suggestStage(); } + + if(angular.isDefined(orgUnit) && angular.isDefined(orgUnit.id)){ + orgPath.push(orgUnit.id); + } + $scope.$watch('model.selectedStage', function(){ if(angular.isObject($scope.model.selectedStage)){ stage = $scope.model.selectedStage; prepareEvent(); } - }); + }); //watch for changes in due/event-date $scope.$watchCollection('[dhis2Event.dueDate, dhis2Event.eventDate]', function () { @@ -93,7 +167,8 @@ if($scope.isReferralEvent && !$scope.selectedSearchingOrgUnit){ $scope.orgUnitError = true; return false; - } + } + $scope.orgUnitError = false; if ($scope.model.selectedStage.periodType) { @@ -123,7 +198,7 @@ DHIS2EventFactory.create(newEvents).then(function (response) { if (response.response && response.response.importSummaries[0].status === 'SUCCESS') { newEvent.event = response.response.importSummaries[0].reference; - $modalInstance.close(newEvent); + $modalInstance.close({dummyEvent: dummyEvent, ev: newEvent}); } else { var dialogOptions = { @@ -216,7 +291,7 @@ $scope.orgUnitsLoading = false; } }; - + if($scope.isReferralEvent){ initOrgUnits(orgPath[0]); } === modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/new-event.html' --- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/new-event.html 2015-12-21 13:28:07 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/new-event.html 2016-01-07 21:16:02 +0000 @@ -3,50 +3,56 @@

{{'schedule'| translate}} - {{model.selectedStage.name}}

{{'referral' | translate}} - {{model.selectedStage.name}}

-