← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 15821: port from 2.15: R15144, 15145, 15146, 15153

 

------------------------------------------------------------
revno: 15821
committer: Long <long.hispvietnam@xxxxxxxxx>
branch nick: trunk
timestamp: Tue 2014-06-24 11:33:13 +0700
message:
  port from 2.15: R15144, 15145, 15146, 15153
modified:
  dhis-2/dhis-services/dhis-service-mobile/src/main/java/org/hisp/dhis/api/mobile/ActivityReportingService.java
  dhis-2/dhis-services/dhis-service-mobile/src/main/java/org/hisp/dhis/api/mobile/model/LWUITmodel/ProgramStage.java
  dhis-2/dhis-services/dhis-service-mobile/src/main/java/org/hisp/dhis/api/mobile/model/MobileOrgUnitLinks.java
  dhis-2/dhis-services/dhis-service-mobile/src/main/java/org/hisp/dhis/mobile/service/ActivityReportingServiceImpl.java
  dhis-2/dhis-services/dhis-service-mobile/src/main/java/org/hisp/dhis/mobile/service/DefaultProgramService.java
  dhis-2/dhis-services/dhis-service-mobile/src/main/resources/META-INF/dhis/beans.xml
  dhis-2/dhis-services/dhis-service-mobile/src/test/java/org/hisp/dhis/mobile/api/model/OrgUnitTest.java
  dhis-2/dhis-services/dhis-service-mobile/src/test/java/org/hisp/dhis/mobile/api/model/OrgUnitsTest.java
  dhis-2/dhis-web/dhis-web-api-mobile/src/main/java/org/hisp/dhis/api/mobile/controller/MobileClientController.java
  dhis-2/dhis-web/dhis-web-api-mobile/src/main/java/org/hisp/dhis/api/mobile/controller/MobileOrganisationUnitController.java


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-services/dhis-service-mobile/src/main/java/org/hisp/dhis/api/mobile/ActivityReportingService.java'
--- dhis-2/dhis-services/dhis-service-mobile/src/main/java/org/hisp/dhis/api/mobile/ActivityReportingService.java	2014-05-28 16:31:17 +0000
+++ dhis-2/dhis-services/dhis-service-mobile/src/main/java/org/hisp/dhis/api/mobile/ActivityReportingService.java	2014-06-24 04:33:13 +0000
@@ -58,7 +58,7 @@
 
     Patient findPatient( int patientId )
         throws NotAllowedException;
-    
+
     PatientList findPatients( String patientIds )
         throws NotAllowedException;
 
@@ -72,6 +72,9 @@
         List<org.hisp.dhis.api.mobile.model.LWUITmodel.ProgramStage> mobileProgramStageList, Date incidentDate )
         throws NotAllowedException;
 
+    public String completeProgramInstance( int programId )
+        throws NotAllowedException;
+
     Collection<org.hisp.dhis.trackedentity.TrackedEntityAttribute> getPatientAtts( String programId );
 
     Collection<PatientAttribute> getAttsForMobile();

=== modified file 'dhis-2/dhis-services/dhis-service-mobile/src/main/java/org/hisp/dhis/api/mobile/model/LWUITmodel/ProgramStage.java'
--- dhis-2/dhis-services/dhis-service-mobile/src/main/java/org/hisp/dhis/api/mobile/model/LWUITmodel/ProgramStage.java	2014-03-18 08:10:10 +0000
+++ dhis-2/dhis-services/dhis-service-mobile/src/main/java/org/hisp/dhis/api/mobile/model/LWUITmodel/ProgramStage.java	2014-06-24 04:33:13 +0000
@@ -46,6 +46,8 @@
 
     private String reportDate;
 
+    private String dueDate;
+
     private String reportDateDescription;
 
     private boolean isRepeatable;
@@ -53,8 +55,8 @@
     private boolean isCompleted;
 
     private boolean isSingleEvent;
-    
-    private Integer standardInterval; 
+
+    private Integer standardInterval;
 
     private List<Section> sections;
 
@@ -150,6 +152,16 @@
         this.standardInterval = standardInterval;
     }
 
+    public String getDueDate()
+    {
+        return dueDate;
+    }
+
+    public void setDueDate( String dueDate )
+    {
+        this.dueDate = dueDate;
+    }
+
     @Override
     public void serialize( DataOutputStream dout )
         throws IOException
@@ -159,8 +171,15 @@
         {
             reportDate = "";
         }
+
+        if ( dueDate == null )
+        {
+            dueDate = "";
+        }
+
         dout.writeUTF( reportDate );
         dout.writeUTF( reportDateDescription );
+        dout.writeUTF( dueDate );
         dout.writeBoolean( isRepeatable );
         dout.writeInt( standardInterval );
         dout.writeBoolean( isCompleted() );
@@ -186,6 +205,7 @@
         super.deSerialize( dint );
         setReportDate( dint.readUTF() );
         setReportDateDescription( dint.readUTF() );
+        setDueDate( dint.readUTF() );
         setRepeatable( dint.readBoolean() );
         setStandardInterval( dint.readInt() );
         setCompleted( dint.readBoolean() );

=== modified file 'dhis-2/dhis-services/dhis-service-mobile/src/main/java/org/hisp/dhis/api/mobile/model/MobileOrgUnitLinks.java'
--- dhis-2/dhis-services/dhis-service-mobile/src/main/java/org/hisp/dhis/api/mobile/model/MobileOrgUnitLinks.java	2014-05-28 11:12:00 +0000
+++ dhis-2/dhis-services/dhis-service-mobile/src/main/java/org/hisp/dhis/api/mobile/model/MobileOrgUnitLinks.java	2014-06-24 04:33:13 +0000
@@ -80,7 +80,7 @@
     private String updateContactUrl;
 
     private String findPatientUrl;
-    
+
     private String findPatientsUrl;
 
     private String uploadProgramStageUrl;
@@ -109,6 +109,8 @@
 
     private String uploadSingleEventWithoutRegistration;
 
+    private String completeProgramInstanceUrl;
+
     @XmlAttribute
     public int getId()
     {
@@ -315,12 +317,12 @@
     {
         return findPatientsUrl;
     }
-    
+
     public void setFindPatientsUrl( String findPatientsUrl )
     {
         this.findPatientsUrl = findPatientsUrl;
     }
-    
+
     public String getUploadProgramStageUrl()
     {
         return uploadProgramStageUrl;
@@ -451,6 +453,16 @@
         this.uploadSingleEventWithoutRegistration = uploadSingleEventWithoutRegistration;
     }
 
+    public String getCompleteProgramInstanceUrl()
+    {
+        return completeProgramInstanceUrl;
+    }
+
+    public void setCompleteProgramInstanceUrl( String completeProgramInstanceUrl )
+    {
+        this.completeProgramInstanceUrl = completeProgramInstanceUrl;
+    }
+
     public void serialize( DataOutputStream dataOutputStream )
         throws IOException
     {
@@ -487,6 +499,7 @@
         dataOutputStream.writeUTF( handleLostToFollowUpUrl );
         dataOutputStream.writeUTF( generateRepeatableEventUrl );
         dataOutputStream.writeUTF( uploadSingleEventWithoutRegistration );
+        dataOutputStream.writeUTF( completeProgramInstanceUrl );
 
     }
 
@@ -526,6 +539,7 @@
         handleLostToFollowUpUrl = dataInputStream.readUTF();
         generateRepeatableEventUrl = dataInputStream.readUTF();
         uploadSingleEventWithoutRegistration = dataInputStream.readUTF();
+        completeProgramInstanceUrl = dataInputStream.readUTF();
 
     }
 
@@ -606,6 +620,6 @@
         dataOutputStream.writeUTF( handleLostToFollowUpUrl );
         dataOutputStream.writeUTF( generateRepeatableEventUrl );
         dataOutputStream.writeUTF( uploadSingleEventWithoutRegistration );
-
+        dataOutputStream.writeUTF( completeProgramInstanceUrl );
     }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-mobile/src/main/java/org/hisp/dhis/mobile/service/ActivityReportingServiceImpl.java'
--- dhis-2/dhis-services/dhis-service-mobile/src/main/java/org/hisp/dhis/mobile/service/ActivityReportingServiceImpl.java	2014-06-20 12:32:01 +0000
+++ dhis-2/dhis-services/dhis-service-mobile/src/main/java/org/hisp/dhis/mobile/service/ActivityReportingServiceImpl.java	2014-06-24 04:33:13 +0000
@@ -41,6 +41,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+
 import org.hisp.dhis.api.mobile.ActivityReportingService;
 import org.hisp.dhis.api.mobile.NotAllowedException;
 import org.hisp.dhis.api.mobile.model.Activity;
@@ -62,6 +63,8 @@
 import org.hisp.dhis.dataelement.DataElement;
 import org.hisp.dhis.dataelement.DataElementService;
 import org.hisp.dhis.event.EventStatus;
+import org.hisp.dhis.i18n.I18nFormat;
+import org.hisp.dhis.i18n.I18nManager;
 import org.hisp.dhis.message.Message;
 import org.hisp.dhis.message.MessageConversation;
 import org.hisp.dhis.message.MessageService;
@@ -84,13 +87,18 @@
 import org.hisp.dhis.relationship.RelationshipType;
 import org.hisp.dhis.relationship.RelationshipTypeService;
 import org.hisp.dhis.sms.SmsSender;
+import org.hisp.dhis.sms.SmsServiceException;
+import org.hisp.dhis.sms.outbound.OutboundSms;
 import org.hisp.dhis.system.util.DateUtils;
 import org.hisp.dhis.trackedentity.TrackedEntity;
 import org.hisp.dhis.trackedentity.TrackedEntityAttribute;
 import org.hisp.dhis.trackedentity.TrackedEntityAttributeService;
 import org.hisp.dhis.trackedentity.TrackedEntityInstance;
 import org.hisp.dhis.trackedentity.TrackedEntityInstanceQueryParams;
+import org.hisp.dhis.trackedentity.TrackedEntityInstanceReminder;
+import org.hisp.dhis.trackedentity.TrackedEntityInstanceReminderService;
 import org.hisp.dhis.trackedentity.TrackedEntityInstanceService;
+import org.hisp.dhis.trackedentity.TrackedEntityService;
 import org.hisp.dhis.trackedentityattributevalue.TrackedEntityAttributeValue;
 import org.hisp.dhis.trackedentityattributevalue.TrackedEntityAttributeValueService;
 import org.hisp.dhis.trackedentitydatavalue.TrackedEntityDataValue;
@@ -112,6 +120,8 @@
 
     private static final String SINGLE_EVENT_WITHOUT_REGISTRATION_UPLOADED = "single_event_without_registration_uploaded";
 
+    private static final String PROGRAM_COMPLETED = "program_completed";
+
     private static final String FEEDBACK_SENT = "feedback_sent";
 
     private static final String MESSAGE_SENT = "message_sent";
@@ -152,6 +162,12 @@
 
     private TrackedEntityAttributeService attributeService;
 
+    private TrackedEntityService trackedEntityService;
+
+    private I18nManager i18nManager;
+
+    private TrackedEntityInstanceReminderService reminderService;
+
     private UserService userService;
 
     private Integer patientId;
@@ -534,12 +550,12 @@
             }
             else
             {
-//                programStageInstance.setCompleted( mobileProgramStage.isCompleted() );
+                // programStageInstance.setCompleted(
+                // mobileProgramStage.isCompleted() );
                 programStageInstanceService.updateProgramStageInstance( programStageInstance );
 
                 // check if all belonged program stage are completed
-
-                if ( isAllProgramStageFinished( programStageInstance ) == true )
+                if ( !mobileProgramStage.isRepeatable() && isAllProgramStageFinished( programStageInstance ) == true )
                 {
 
                     ProgramInstance programInstance = programStageInstance.getProgramInstance();
@@ -652,8 +668,8 @@
         programInstanceService.updateProgramInstance( programInstance );
         patient.getProgramInstances().add( programInstance );
         entityInstanceService.updateTrackedEntityInstance( patient );
-
         patient = entityInstanceService.getTrackedEntityInstance( patientId );
+        this.sendMessages( programInstance, TrackedEntityInstanceReminder.SEND_WHEN_TO_EMROLLEMENT );
         return getPatientModel( patient );
     }
 
@@ -867,6 +883,16 @@
                     mobileProgramStage.setReportDateDescription( programStage.getReportDateDescription() );
                 }
 
+                // get due date
+                if ( eachProgramStageInstance.getDueDate() != null )
+                {
+                    mobileProgramStage.setDueDate( PeriodUtil.dateToString( eachProgramStageInstance.getDueDate() ) );
+                }
+                else
+                {
+                    mobileProgramStage.setDueDate( "" );
+                }
+
                 // is repeatable
                 mobileProgramStage.setRepeatable( programStage.getIrregular() );
 
@@ -1417,6 +1443,7 @@
             }
         }
 
+        patientWeb.setTrackedEntity( trackedEntityService.getTrackedEntityByName( "Person" ) );
         patientId = entityInstanceService.createTrackedEntityInstance( patientWeb, null, null, patientAttributeValues );
         TrackedEntityInstance newTrackedEntityInstance = entityInstanceService
             .getTrackedEntityInstance( this.patientId );
@@ -1447,12 +1474,12 @@
         org.hisp.dhis.api.mobile.model.LWUITmodel.Patient patientMobile = getPatientModel( patient );
         return patientMobile;
     }
-    
+
     public org.hisp.dhis.api.mobile.model.LWUITmodel.PatientList findPatients( String patientIds )
         throws NotAllowedException
     {
         PatientList patientlist = new PatientList();
-        
+
         while ( patientIds.length() > 0 )
         {
             int patientId = Integer.parseInt( patientIds.substring( 0, patientIds.indexOf( "$" ) ) );
@@ -1460,7 +1487,7 @@
             patientlist.getPatientList().add( getPatientModel( patient ) );
             patientIds = patientIds.substring( patientIds.indexOf( "$" ) + 1, patientIds.length() );
         }
-        
+
         return patientlist;
     }
 
@@ -1647,7 +1674,7 @@
             ProgramStageInstance programStageInstance = programStageInstanceService.getProgramStageInstance( lostEvent
                 .getId() );
             programStageInstance.setDueDate( PeriodUtil.stringToDate( lostEvent.getDueDate() ) );
-            programStageInstance.setStatus(EventStatus.fromInt( lostEvent.getStatus() ) );
+            programStageInstance.setStatus( EventStatus.fromInt( lostEvent.getStatus() ) );
 
             if ( lostEvent.getComment() != null )
             {
@@ -2054,4 +2081,101 @@
 
         return MESSAGE_SENT;
     }
+
+    @Override
+    public String completeProgramInstance( int programId )
+        throws NotAllowedException
+    {
+        ProgramInstance programInstance = programInstanceService.getProgramInstance( programId );
+        programInstance.setStatus( ProgramInstance.STATUS_COMPLETED );
+        programInstanceService.updateProgramInstance( programInstance );
+
+        return PROGRAM_COMPLETED;
+    }
+
+    private Collection<OutboundSms> sendMessages( ProgramInstance programInstance, int status )
+    {
+        TrackedEntityInstance entityInstance = programInstance.getEntityInstance();
+        Collection<OutboundSms> outboundSmsList = new HashSet<OutboundSms>();
+
+        Collection<TrackedEntityInstanceReminder> reminders = programInstance.getProgram().getInstanceReminders();
+
+        for ( TrackedEntityInstanceReminder rm : reminders )
+        {
+            if ( rm != null
+                && rm.getWhenToSend() != null
+                && rm.getWhenToSend() == status
+                && (rm.getMessageType() == TrackedEntityInstanceReminder.MESSAGE_TYPE_DIRECT_SMS || rm.getMessageType() == TrackedEntityInstanceReminder.MESSAGE_TYPE_BOTH) )
+            {
+                OutboundSms outboundSms = sendProgramMessage( rm, programInstance, entityInstance );
+
+                if ( outboundSms != null )
+                {
+                    outboundSmsList.add( outboundSms );
+                }
+            }
+        }
+
+        return outboundSmsList;
+    }
+
+    private OutboundSms sendProgramMessage( TrackedEntityInstanceReminder reminder, ProgramInstance programInstance,
+        TrackedEntityInstance entityInstance )
+    {
+        I18nFormat format = i18nManager.getI18nFormat();
+
+        Set<String> phoneNumbers = reminderService.getPhonenumbers( reminder, entityInstance );
+        OutboundSms outboundSms = null;
+
+        if ( phoneNumbers.size() > 0 )
+        {
+            String msg = reminderService.getMessageFromTemplate( reminder, programInstance, format );
+
+            try
+            {
+                outboundSms = new OutboundSms();
+                outboundSms.setMessage( msg );
+                outboundSms.setRecipients( phoneNumbers );
+                outboundSms.setSender( currentUserService.getCurrentUsername() );
+                smsSender.sendMessage( outboundSms, null );
+            }
+            catch ( SmsServiceException e )
+            {
+                e.printStackTrace();
+            }
+        }
+
+        return outboundSms;
+    }
+
+    public I18nManager getI18nManager()
+    {
+        return i18nManager;
+    }
+
+    public void setI18nManager( I18nManager i18nManager )
+    {
+        this.i18nManager = i18nManager;
+    }
+
+    public TrackedEntityInstanceReminderService getReminderService()
+    {
+        return reminderService;
+    }
+
+    public void setReminderService( TrackedEntityInstanceReminderService reminderService )
+    {
+        this.reminderService = reminderService;
+    }
+
+    public TrackedEntityService getTrackedEntityService()
+    {
+        return trackedEntityService;
+    }
+
+    public void setTrackedEntityService( TrackedEntityService trackedEntityService )
+    {
+        this.trackedEntityService = trackedEntityService;
+    }
+
 }
\ No newline at end of file

=== modified file 'dhis-2/dhis-services/dhis-service-mobile/src/main/java/org/hisp/dhis/mobile/service/DefaultProgramService.java'
--- dhis-2/dhis-services/dhis-service-mobile/src/main/java/org/hisp/dhis/mobile/service/DefaultProgramService.java	2014-05-20 15:35:16 +0000
+++ dhis-2/dhis-services/dhis-service-mobile/src/main/java/org/hisp/dhis/mobile/service/DefaultProgramService.java	2014-06-24 04:33:13 +0000
@@ -212,6 +212,8 @@
             prStg.setReportDate( "" );
 
             prStg.setReportDateDescription( programStage.getReportDateDescription() );
+            
+            prStg.setDueDate( "" );
 
             prStg.setId( programStage.getId() );
 

=== modified file 'dhis-2/dhis-services/dhis-service-mobile/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-services/dhis-service-mobile/src/main/resources/META-INF/dhis/beans.xml	2014-05-21 09:48:18 +0000
+++ dhis-2/dhis-services/dhis-service-mobile/src/main/resources/META-INF/dhis/beans.xml	2014-06-24 04:33:13 +0000
@@ -46,6 +46,9 @@
 		<property name="messageService" ref="org.hisp.dhis.message.MessageService" />
 		<property name="smsSender" ref="org.hisp.dhis.sms.SmsSender" />
 		<property name="userService" ref="org.hisp.dhis.user.UserService" />
+		<property name="trackedEntityService" ref="org.hisp.dhis.trackedentity.TrackedEntityService" />
+		<property name="i18nManager" ref="org.hisp.dhis.i18n.I18nManager" />
+		<property name="reminderService" ref="org.hisp.dhis.trackedentity.TrackedEntityInstanceReminderService" />
 	</bean>
 
 	<bean id="org.hisp.dhis.mobile.api.IProgramService" class="org.hisp.dhis.mobile.service.DefaultProgramService">

=== modified file 'dhis-2/dhis-services/dhis-service-mobile/src/test/java/org/hisp/dhis/mobile/api/model/OrgUnitTest.java'
--- dhis-2/dhis-services/dhis-service-mobile/src/test/java/org/hisp/dhis/mobile/api/model/OrgUnitTest.java	2014-05-28 11:12:00 +0000
+++ dhis-2/dhis-services/dhis-service-mobile/src/test/java/org/hisp/dhis/mobile/api/model/OrgUnitTest.java	2014-06-24 04:33:13 +0000
@@ -81,6 +81,7 @@
         unit.setHandleLostToFollowUpUrl( "handleLostToFollowUpUrl" );
         unit.setGenerateRepeatableEventUrl( "generateRepeatableEventUrl" );
         unit.setUploadSingleEventWithoutRegistration( "uploadSingleEventWithoutRegistration" );
+        unit.setCompleteProgramInstanceUrl( "completeProgramInstance" );
 
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         DataOutputStream dos = new DataOutputStream( baos );

=== modified file 'dhis-2/dhis-services/dhis-service-mobile/src/test/java/org/hisp/dhis/mobile/api/model/OrgUnitsTest.java'
--- dhis-2/dhis-services/dhis-service-mobile/src/test/java/org/hisp/dhis/mobile/api/model/OrgUnitsTest.java	2014-05-28 11:12:00 +0000
+++ dhis-2/dhis-services/dhis-service-mobile/src/test/java/org/hisp/dhis/mobile/api/model/OrgUnitsTest.java	2014-06-24 04:33:13 +0000
@@ -107,6 +107,7 @@
         orgUnit.setHandleLostToFollowUpUrl( "handleLostToFollowUp" );
         orgUnit.setGenerateRepeatableEventUrl( "generateRepeatableEvent" );
         orgUnit.setUploadSingleEventWithoutRegistration( "uploadSingleEventWithoutRegistration" );
+        orgUnit.setCompleteProgramInstanceUrl( "completeProgramInstance" );
 
         return orgUnit;
     }

=== modified file 'dhis-2/dhis-web/dhis-web-api-mobile/src/main/java/org/hisp/dhis/api/mobile/controller/MobileClientController.java'
--- dhis-2/dhis-web/dhis-web-api-mobile/src/main/java/org/hisp/dhis/api/mobile/controller/MobileClientController.java	2014-05-28 11:12:00 +0000
+++ dhis-2/dhis-web/dhis-web-api-mobile/src/main/java/org/hisp/dhis/api/mobile/controller/MobileClientController.java	2014-06-24 04:33:13 +0000
@@ -170,6 +170,7 @@
         orgUnit.setGenerateRepeatableEventUrl( getUrl( request, unit.getId(), "generateRepeatableEvent" ) );
         orgUnit.setUploadSingleEventWithoutRegistration( getUrl( request, unit.getId(),
             "uploadSingleEventWithoutRegistration" ) );
+        orgUnit.setCompleteProgramInstanceUrl(getUrl( request, unit.getId(), "completeProgramInstance" ) );
 
         // generate URL for download new version
         String full = UrlUtils.buildFullRequestUrl( request );

=== modified file 'dhis-2/dhis-web/dhis-web-api-mobile/src/main/java/org/hisp/dhis/api/mobile/controller/MobileOrganisationUnitController.java'
--- dhis-2/dhis-web/dhis-web-api-mobile/src/main/java/org/hisp/dhis/api/mobile/controller/MobileOrganisationUnitController.java	2014-06-05 07:16:25 +0000
+++ dhis-2/dhis-web/dhis-web-api-mobile/src/main/java/org/hisp/dhis/api/mobile/controller/MobileOrganisationUnitController.java	2014-06-24 04:33:13 +0000
@@ -57,6 +57,7 @@
 import org.hisp.dhis.api.mobile.model.LWUITmodel.PatientList;
 import org.hisp.dhis.api.mobile.model.LWUITmodel.PatientIdentifierAndAttribute;
 import org.hisp.dhis.api.mobile.model.LWUITmodel.Program;
+import org.hisp.dhis.api.mobile.model.LWUITmodel.ProgramInstance;
 import org.hisp.dhis.api.mobile.model.LWUITmodel.ProgramStage;
 import org.hisp.dhis.api.mobile.model.LWUITmodel.Relationship;
 import org.hisp.dhis.i18n.I18nService;
@@ -398,6 +399,16 @@
         return activityReportingService.saveProgramStage( programStage, patientId, id );
     }
 
+    @RequestMapping( method = RequestMethod.POST, value = "{clientVersion}/LWUIT/orgUnits/{id}/completeProgramInstance" )
+    @ResponseBody
+    public String completeProgramInstance( @PathVariable
+    int id, @RequestBody
+    ProgramInstance programInstance )
+        throws NotAllowedException
+    {
+        return activityReportingService.completeProgramInstance( programInstance.getId() );
+    }
+
     @RequestMapping( method = RequestMethod.POST, value = "{clientVersion}/LWUIT/orgUnits/{id}/uploadSingleEventWithoutRegistration" )
     @ResponseBody
     public String saveSingleEventWithoutRegistration( @PathVariable