← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 7665: Prototype for sending SMS using BulkSMS. Also including code cleanup and bug fixes regarding SMS...

 

------------------------------------------------------------
revno: 7665
committer: Magnus Korvald <korvald@xxxxxxxxxxx>
branch nick: trunk
timestamp: Sun 2012-07-22 14:04:11 +0200
message:
  Prototype for sending SMS using BulkSMS.  Also including code cleanup and bug fixes regarding SMSInput and category option combos.
added:
  dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/output/
  dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/output/BulkSMSOutput.java
  dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/output/SMSOutput.java
modified:
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/smscommand/EditSMSCommandForm.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/smscommand/edit-sms-command.vm
  dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/input/SMSInput.java
  dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/input/SMSParserKeyValue.java
  dhis-2/dhis-web/dhis-web-sms/src/main/resources/META-INF/dhis/beans.xml


--
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-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/smscommand/EditSMSCommandForm.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/smscommand/EditSMSCommandForm.java	2012-06-13 08:44:07 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/smscommand/EditSMSCommandForm.java	2012-07-22 12:04:11 +0000
@@ -18,18 +18,25 @@
 
 import com.opensymphony.xwork2.Action;
 
-public class EditSMSCommandForm implements Action {
+public class EditSMSCommandForm
+    implements Action
+{
 
     // services
     private SMSCommandService smsCommandService;
+
     private DataSetService dataSetService;
+
     private DataElementService dataElementService;
 
-    // input fields
-    private String name; // for lista
-    private int selectedDataSetID; //
+    private String name; 
+
+    private int selectedDataSetID; 
+
     private String codeDataelementOption;
+
     private String seperator;
+
     private String codeSeperator;
 
     private int selectedCommandID = -1;
@@ -38,124 +45,150 @@
     // Action implementation
     // -------------------------------------------------------------------------
 
-    public String execute() throws Exception {
-        
+    public String execute()
+        throws Exception
+    {
+
         Set<SMSCode> codeSet = new HashSet<SMSCode>();
-        
-        @SuppressWarnings("unchecked")
-        List<JSONObject> jsonCodes = (List<JSONObject>) JSONObject.fromObject(codeDataelementOption).get("codes");
-        for(JSONObject x : jsonCodes){
-            System.out.println(x.get("dataElementId") + " " + x.get("optionId") + " " + x.get("code"));
+
+        @SuppressWarnings( "unchecked" )
+        List<JSONObject> jsonCodes = (List<JSONObject>) JSONObject.fromObject( codeDataelementOption ).get( "codes" );
+        for ( JSONObject x : jsonCodes )
+        {
             SMSCode c = new SMSCode();
-            c.setCode(x.getString("code"));
-            c.setDataElement(dataElementService.getDataElement(x.getInt("dataElementId")));
-            c.setOptionId(x.getInt("optionId"));
-            codeSet.add(c);
-        }
-        
-        if(codeSet.size() > 0){
-            smsCommandService.save(codeSet);
-        }
-        
+            c.setCode( x.getString( "code" ) );
+            c.setDataElement( dataElementService.getDataElement( x.getInt( "dataElementId" ) ) );
+            c.setOptionId( x.getInt( "optionId" ) );
+            codeSet.add( c );
+        }
+
+        if ( codeSet.size() > 0 )
+        {
+            smsCommandService.save( codeSet );
+        }
+
         SMSCommand c = getSMSCommand();
-        if (selectedDataSetID > -1 && c != null) {
-            c.setDataset(getDataSetService().getDataSet(getSelectedDataSetID()));
-            c.setName(name);
-            c.setSeperator(seperator);
-            c.setCodes(codeSet);
-            c.setCodeSeperator(codeSeperator);
-            smsCommandService.save(c);
+        if ( selectedDataSetID > -1 && c != null )
+        {
+            c.setDataset( getDataSetService().getDataSet( getSelectedDataSetID() ) );
+            c.setName( name );
+            c.setSeperator( seperator );
+            c.setCodes( codeSet );
+            c.setCodeSeperator( codeSeperator );
+            smsCommandService.save( c );
         }
-        
+
         return SUCCESS;
     }
 
-    public Collection<DataSet> getDataSets() {
+    public Collection<DataSet> getDataSets()
+    {
         return getDataSetService().getAllDataSets();
     }
 
-    public Set<DataElement> getDataSetElements() {
-        DataSet d = dataSetService.getDataSet(selectedDataSetID);
-        if (d != null) {
+    public Set<DataElement> getDataSetElements()
+    {
+        DataSet d = dataSetService.getDataSet( selectedDataSetID );
+        if ( d != null )
+        {
             return d.getDataElements();
         }
         return null;
     }
 
-    public SMSCommand getSMSCommand() {
-        return smsCommandService.getSMSCommand(selectedCommandID);
+    public SMSCommand getSMSCommand()
+    {
+        return smsCommandService.getSMSCommand( selectedCommandID );
 
     }
 
-    public DataSetService getDataSetService() {
+    public DataSetService getDataSetService()
+    {
         return dataSetService;
     }
 
-    public void setDataSetService(DataSetService dataSetService) {
+    public void setDataSetService( DataSetService dataSetService )
+    {
         this.dataSetService = dataSetService;
     }
 
-    public int getSelectedDataSetID() {
+    public int getSelectedDataSetID()
+    {
         return selectedDataSetID;
     }
 
-    public void setSelectedDataSetID(int selectedDataSetID) {
+    public void setSelectedDataSetID( int selectedDataSetID )
+    {
         this.selectedDataSetID = selectedDataSetID;
     }
 
-    public String getCodeDataelementOption() {
+    public String getCodeDataelementOption()
+    {
         return codeDataelementOption;
     }
 
-    public void setCodeDataelementOption(String codeDataelementOption) {
+    public void setCodeDataelementOption( String codeDataelementOption )
+    {
         this.codeDataelementOption = codeDataelementOption;
     }
 
-    public String getName() {
+    public String getName()
+    {
         return name;
     }
 
-    public void setName(String name) {
+    public void setName( String name )
+    {
         this.name = name;
     }
 
-    public SMSCommandService getSmsCommandService() {
+    public SMSCommandService getSmsCommandService()
+    {
         return smsCommandService;
     }
 
-    public void setSmsCommandService(SMSCommandService smsCommandService) {
+    public void setSmsCommandService( SMSCommandService smsCommandService )
+    {
         this.smsCommandService = smsCommandService;
     }
 
-    public int getSelectedCommandID() {
+    public int getSelectedCommandID()
+    {
         return selectedCommandID;
     }
 
-    public void setSelectedCommandID(int selectedCommandID) {
+    public void setSelectedCommandID( int selectedCommandID )
+    {
         this.selectedCommandID = selectedCommandID;
     }
 
-    public String getSeperator() {
+    public String getSeperator()
+    {
         return seperator;
     }
 
-    public void setSeperator(String seperator) {
+    public void setSeperator( String seperator )
+    {
         this.seperator = seperator;
     }
 
-    public DataElementService getDataElementService() {
+    public DataElementService getDataElementService()
+    {
         return dataElementService;
     }
 
-    public void setDataElementService(DataElementService dataElementService) {
+    public void setDataElementService( DataElementService dataElementService )
+    {
         this.dataElementService = dataElementService;
     }
 
-    public String getCodeSeperator() {
+    public String getCodeSeperator()
+    {
         return codeSeperator;
     }
 
-    public void setCodeSeperator(String codeSeperator) {
+    public void setCodeSeperator( String codeSeperator )
+    {
         this.codeSeperator = codeSeperator;
     }
 }
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/smscommand/edit-sms-command.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/smscommand/edit-sms-command.vm	2012-06-27 07:25:34 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/smscommand/edit-sms-command.vm	2012-07-22 12:04:11 +0000
@@ -82,18 +82,19 @@
 		<th>Code</th>
       </tr>
     </thead>
-		
          #foreach( $dataElement in $dataSetElements)
-            #if ($dataElement.categoryCombo && $dataElement.categoryCombo.categories) 
-                #foreach($category in $dataElement.categoryCombo.categories)
-                    #foreach($option in $category.categoryOptions)
-                    <tr>
-                        <td>$dataElement.name $option.name</td>
-                        #set ($str = ""+$dataElement.id+""+$option.id)
-                        <td><input type="text" name="$dataElement.id.$option.id" value='$!codes[$str]'></td>
-                    </tr>         
-                    #end
-                #end
+            #if ($dataElement.categoryCombo && $dataElement.categoryCombo.sortedOptionCombos) 
+                   #foreach($x in $dataElement.categoryCombo.sortedOptionCombos)    
+                       #set ($str = ""+$dataElement.id+""+$x.id)
+                       <tr>
+                           <td>
+                               $dataElement.name $x.name
+                           </td>
+                           <td>
+                               <input type="text" name="$dataElement.id.$x.id" value='$!codes[$str]'>
+                           </td>
+                       </tr>
+                   #end
             #else
             <tr>
                <td>$dataElement.name</td>

=== modified file 'dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/input/SMSInput.java'
--- dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/input/SMSInput.java	2012-07-10 15:16:49 +0000
+++ dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/input/SMSInput.java	2012-07-22 12:04:11 +0000
@@ -1,10 +1,8 @@
 package org.hisp.dhis.sms.input;
 
-import com.opensymphony.xwork2.Action;
 import java.text.ParseException;
-import java.util.Collection;
-import java.util.Iterator;
 import java.util.Map;
+
 import org.apache.commons.lang.StringUtils;
 import org.exolab.castor.types.Date;
 import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
@@ -12,14 +10,13 @@
 import org.hisp.dhis.datavalue.DataValue;
 import org.hisp.dhis.datavalue.DataValueService;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
-import org.hisp.dhis.organisationunit.OrganisationUnitService;
 import org.hisp.dhis.period.CalendarPeriodType;
 import org.hisp.dhis.period.Period;
-
 import org.hisp.dhis.sms.incoming.IncomingSms;
 import org.hisp.dhis.sms.incoming.IncomingSmsStore;
 import org.hisp.dhis.sms.incoming.SmsMessageEncoding;
 import org.hisp.dhis.sms.incoming.SmsMessageStatus;
+import org.hisp.dhis.sms.output.SMSOutput;
 import org.hisp.dhis.smscommand.SMSCode;
 import org.hisp.dhis.smscommand.SMSCommand;
 import org.hisp.dhis.smscommand.SMSCommandService;
@@ -28,282 +25,342 @@
 import org.hisp.dhis.user.UserService;
 import org.springframework.beans.factory.annotation.Autowired;
 
+import com.opensymphony.xwork2.Action;
+
 /**
- *
- * @author Christian
+ * 
+ * @author Christian and Magnus
  */
-public class SMSInput implements Action {
-
-    private String msisdn, sender, message, dca, reffering_batch, network_id, concat_reference, concat_num_segments, concat_seq_num, received_time;
+public class SMSInput
+    implements Action
+{
+
+    private String msisdn, sender, message, dca, reffering_batch, network_id, concat_reference, concat_num_segments,
+        concat_seq_num, received_time;
+
     private String source_id; // Probably like message id and should be an int
+
     private int msg_id; // unique for each sms
+
     private IncomingSms sms;
+
     private IncomingSmsStore smsStore;
-    
+
     // Services
     private CurrentUserService currentUserService;
+
     private DataValueService dataValueService;
+
     private UserService userService;
-    private OrganisationUnitService organisationUnitService;
+
     private SMSCommandService smsCommandService;
+    
     @Autowired
     private DataElementCategoryService dataElementCategoryService;
     
-    public SMSInput() {
+    private SMSOutput smsOutput;
+
+    public SMSInput()
+    {
     }
 
     @Override
-    public String execute() throws Exception {
-        System.out.println("Sender: " + sender + ", Message: " + message);
+    public String execute()
+        throws Exception
+    {
+        System.out.println( "Sender: " + sender + ", Message: " + message );
         IncomingSms sms = new IncomingSms();
-        sms.setText(message);
-        sms.setOriginator(sender);
+        sms.setText( message );
+        sms.setOriginator( sender );
 
         java.util.Date rec = null;
-        try {
-            Date received = Date.parseDate(received_time);
+        try
+        {
+            Date received = Date.parseDate( received_time );
             rec = received.toDate();
-        } catch (ParseException pe) {
-            System.out.println("ERROR: No received_time input");
+        }
+        catch ( ParseException pe )
+        {
+            System.out.println( "ERROR: No received_time input" );
             return ERROR;
         }
-        sms.setReceivedDate(rec);
-        sms.setSentDate(rec); // This should probably be removed from incoming SMS entirely. Though other gateways may use it?
-        sms.setEncoding(SmsMessageEncoding.ENC7BIT);
-        sms.setStatus(SmsMessageStatus.INCOMING);
-        sms.setId(msg_id);
-        sms.setGatewayId("HARDCODEDTESTGATEWAY");
-
-        int result = smsStore.save(sms);
-        System.out.println("The result of SMS save is *trommevirvel* " + result);
-
-        Collection<User> users = userService.getUsersByPhoneNumber(sender);
+        sms.setReceivedDate( rec );
+        sms.setSentDate( rec ); // This should probably be removed from incoming
+                                // SMS entirely. Though other gateways may use
+                                // it?
+        sms.setEncoding( SmsMessageEncoding.ENC7BIT );
+        sms.setStatus( SmsMessageStatus.INCOMING );
+        sms.setId( msg_id );
+        sms.setGatewayId( "HARDCODEDTESTGATEWAY" );
+
+        int result = smsStore.save( sms );
+        System.out.println( "The result of SMS save is *trommevirvel* " + result );
 
         OrganisationUnit orgunit = null;
-        for (Iterator<User> it = users.iterator(); it.hasNext();) {
-            User user = it.next();
-            OrganisationUnit ou = user.getOrganisationUnit(); // Might be undefined if the user has more than one org.units "attached"
-            if (orgunit == null) {
+        for ( User user : userService.getUsersByPhoneNumber( sender ) )
+        {
+            OrganisationUnit ou = user.getOrganisationUnit();
+
+            // Might be undefined if the user has more than one org.units
+            // "attached"
+
+            if ( orgunit == null )
+            {
                 orgunit = ou;
-            } else if (orgunit.getId() == ou.getId()) {
+            }
+            else if ( orgunit.getId() == ou.getId() )
+            {
                 // same orgunit, no problem...
-            } else {
-                // orgunit and ou are different, ie. the phone number is registered to users at multiple facilities.
+            }
+            else
+            {
+                // orgunit and ou are different, ie. the phone number is
+                // registered to users at multiple facilities.
                 // Now what should we do?
-                System.out.println("user is registered to more than one orgunit, what orgunit should we pick?");
+                System.out.println( "user is registered to more than one orgunit, what orgunit should we pick?" );
                 return ERROR;
             }
         }
-        System.out.println("Orgunit: " + orgunit);
 
-        String[] marr = message.trim().split(" ");
-        if (marr.length < 1) {
+        String[] marr = message.trim().split( " " );
+        if ( marr.length < 1 )
+        {
             return ERROR;
         }
         String commandString = marr[0];
-        Collection<SMSCommand> commands = smsCommandService.getSMSCommands();
-        for (Iterator<SMSCommand> it = commands.iterator(); it.hasNext();) {
-            SMSCommand command = it.next();
-            if (command.getName().equalsIgnoreCase(commandString)) {
-                System.out.println("We got a hit on command name: " + commandString);
-                //DataSet ds = command.getDataset();
-
-                IParser p = new SMSParserKeyValue(command.getSeperator(), " ", " ", true, false); // hack, to be changed into message type handler of some sort
-                Map<String, String> parsedMessage = p.parse(message);
-
-                Collection<SMSCode> codes = command.getCodes();
-                for (Iterator<SMSCode> it1 = codes.iterator(); it1.hasNext();) {
-                    SMSCode code = it1.next();
-
-                    if (parsedMessage.containsKey(code.getCode())) { // If SMS Code is in the SMS (parsed sms)
+
+        for ( SMSCommand command : smsCommandService.getSMSCommands() )
+        {
+            if ( command.getName().equalsIgnoreCase( commandString ) )
+            {
+                // Insert message type handler later :)
+                IParser p = new SMSParserKeyValue( command.getSeperator(), " ", " ", true, false );
+                Map<String, String> parsedMessage = p.parse( message );
+
+                for ( SMSCode code : command.getCodes() )
+                {
+
+                    String upperCaseCode = code.getCode().toUpperCase();
+                    if ( parsedMessage.containsKey( upperCaseCode ) )  // Or fail hard??? 
+                    {
 
                         String storedBy = currentUserService.getCurrentUsername();
 
-                        if (StringUtils.isBlank(storedBy)) {
-                            storedBy = "[unknown] from [" + sender+"]";
+                        if ( StringUtils.isBlank( storedBy ) )
+                        {
+                            storedBy = "[unknown] from [" + sender + "]";
                         }
-                        System.out.println("Code.getOptionId() == " + code.getOptionId());
-                        DataElementCategoryOptionCombo optionCombo = dataElementCategoryService.getDataElementCategoryOptionCombo(code.getDataElement().getCategoryCombo().getCategoryOptions());
-                        
-                        System.out.println("optionCombo == " + optionCombo);
+
+                        DataElementCategoryOptionCombo optionCombo = null;
+                        optionCombo = dataElementCategoryService.getDataElementCategoryOptionCombo( code.getOptionId() );
+
                         Period period = code.getDataElement().getPeriodType().createPeriod();
                         CalendarPeriodType cpt = (CalendarPeriodType) period.getPeriodType();
-                        period = cpt.getPreviousPeriod(period);
-
-                        System.out.println("Found Code (" + code.getCode() + ") in message. " + code.getOptionId() + " & " + code.getDataElement());
-                        DataValue dv = dataValueService.getDataValue(orgunit, code.getDataElement(), period, optionCombo);
-                        if (dv != null) {
-                            System.out.println("Updating dataValue, Code: " + code.getCode() +". Value: " + parsedMessage.get(code.getCode()) + " Period: " + period.getDisplayName() + ". " + period.getStartDateString() + " til " + period.getEndDate().toString());
-                            dv.setValue(parsedMessage.get(code.getCode()));
-                            dataValueService.updateDataValue(dv);
-                        } else {
+                        period = cpt.getPreviousPeriod( period );
+
+                        DataValue dv = dataValueService.getDataValue( orgunit, code.getDataElement(), period,
+                            optionCombo );
+
+                        if ( dv == null )
+                        {
+                            // New data element
                             DataValue dataVal = new DataValue();
-                            
-                            if(optionCombo != null) {
-                                dataVal.setOptionCombo(optionCombo);
-                            }
-                            if(orgunit != null) {
-                                dataVal.setSource(orgunit);
-                            }
-                            if(code.getDataElement() != null) {
-                                dataVal.setDataElement(code.getDataElement());
-                            }
-                            
-                            dataVal.setPeriod(period);
-                            dataVal.setComment("");
-                            dataVal.setTimestamp(new java.util.Date());
-                            dataVal.setStoredBy(storedBy);
-                            dataVal.setValue(parsedMessage.get(code.getCode()));
-                            dataValueService.addDataValue(dataVal);
-                            /*
-                            dataValueService.addDataValue(new DataValue(code.getDataElement(), period, orgunit, parsedMessage.get(code.getCode()),
-                                    storedBy, new java.util.Date(), "", optionCombo));*/
-                        }
-
-
-
+
+                            dataVal.setOptionCombo( optionCombo );
+
+                            dataVal.setSource( orgunit );
+                            dataVal.setDataElement( code.getDataElement() );
+
+                            dataVal.setPeriod( period );
+                            dataVal.setComment( "" );
+                            dataVal.setTimestamp( new java.util.Date() );
+                            dataVal.setStoredBy( storedBy );
+                            dataVal.setValue( parsedMessage.get( upperCaseCode ) );
+                            dataValueService.addDataValue( dataVal );
+                        }
+                        else
+                        {
+                            // Update data element
+                            dv.setValue( parsedMessage.get( upperCaseCode ) );
+                            dv.setOptionCombo( optionCombo );
+                            dataValueService.updateDataValue( dv );
+                        }
                     }
-
                 }
             }
         }
 
+
+        smsOutput.sendSMS( "Your sms has been received", sender );
+
         // TODO DataEntry stuff
-
         return SUCCESS;
     }
 
-    public void setDataElementCategoryService(DataElementCategoryService dataElementCategoryService) {
+    public void setDataElementCategoryService( DataElementCategoryService dataElementCategoryService )
+    {
         this.dataElementCategoryService = dataElementCategoryService;
     }
 
-    public void setSmsCommandService(SMSCommandService smsCommandService) {
+    public void setSmsCommandService( SMSCommandService smsCommandService )
+    {
         this.smsCommandService = smsCommandService;
     }
 
-    public void setCurrentUserService(CurrentUserService currentUserService) {
+    public void setCurrentUserService( CurrentUserService currentUserService )
+    {
         this.currentUserService = currentUserService;
     }
 
-    public void setDataValueService(DataValueService dataValueService) {
+    public void setDataValueService( DataValueService dataValueService )
+    {
         this.dataValueService = dataValueService;
     }
 
-    public void setSmsStore(IncomingSmsStore smsStore) {
-        System.out.println("Setting SMSStore: " + smsStore);
+    public void setSmsStore( IncomingSmsStore smsStore )
+    {
+        System.out.println( "Setting SMSStore: " + smsStore );
         this.smsStore = smsStore;
     }
 
-    public void setUserService(UserService userService) {
+    public void setUserService( UserService userService )
+    {
         this.userService = userService;
     }
 
-    public void setOrganisationUnitService(OrganisationUnitService organisationUnitService) {
-        this.organisationUnitService = organisationUnitService;
-    }
-
-    public String getConcat_num_segments() {
+    public String getConcat_num_segments()
+    {
         return concat_num_segments;
     }
 
-    public void setConcat_num_segments(String concat_num_segments) {
+    public void setConcat_num_segments( String concat_num_segments )
+    {
         this.concat_num_segments = concat_num_segments;
     }
 
-    public String getConcat_reference() {
+    public String getConcat_reference()
+    {
         return concat_reference;
     }
 
-    public void setConcat_reference(String concat_reference) {
+    public void setConcat_reference( String concat_reference )
+    {
         this.concat_reference = concat_reference;
     }
 
-    public String getConcat_seq_num() {
+    public String getConcat_seq_num()
+    {
         return concat_seq_num;
     }
 
-    public void setConcat_seq_num(String concat_seq_num) {
+    public void setConcat_seq_num( String concat_seq_num )
+    {
         this.concat_seq_num = concat_seq_num;
     }
 
-    public String getDca() {
+    public String getDca()
+    {
         return dca;
     }
 
-    public void setDca(String dca) {
+    public void setDca( String dca )
+    {
         this.dca = dca;
     }
 
-    public String getMessage() {
+    public String getMessage()
+    {
         return message;
     }
 
-    public void setMessage(String message) {
+    public void setMessage( String message )
+    {
         this.message = message;
     }
 
-    public int getMsg_id() {
+    public int getMsg_id()
+    {
         return msg_id;
     }
 
-    public void setMsg_id(int msg_id) {
+    public void setMsg_id( int msg_id )
+    {
         this.msg_id = msg_id;
     }
 
-    public String getMsisdn() {
+    public String getMsisdn()
+    {
         return msisdn;
     }
 
-    public void setMsisdn(String msisdn) {
+    public void setMsisdn( String msisdn )
+    {
         this.msisdn = msisdn;
     }
 
-    public String getNetwork_id() {
+    public String getNetwork_id()
+    {
         return network_id;
     }
 
-    public void setNetwork_id(String network_id) {
+    public void setNetwork_id( String network_id )
+    {
         this.network_id = network_id;
     }
 
-    public String getReceived_time() {
+    public String getReceived_time()
+    {
         return received_time;
     }
 
-    public void setReceived_time(String received_time) {
+    public void setReceived_time( String received_time )
+    {
         this.received_time = received_time;
     }
 
-    public String getReffering_batch() {
+    public String getReffering_batch()
+    {
         return reffering_batch;
     }
 
-    public void setReffering_batch(String reffering_batch) {
+    public void setReffering_batch( String reffering_batch )
+    {
         this.reffering_batch = reffering_batch;
     }
 
-    public String getSender() {
+    public String getSender()
+    {
         return sender;
     }
 
-    public void setSender(String sender) {
+    public void setSender( String sender )
+    {
         this.sender = sender;
     }
 
-    public IncomingSms getSms() {
+    public IncomingSms getSms()
+    {
         return sms;
     }
 
-    public void setSms(IncomingSms sms) {
+    public void setSms( IncomingSms sms )
+    {
         this.sms = sms;
     }
 
-    public String getSource_id() {
+    public String getSource_id()
+    {
         return source_id;
     }
 
-    public void setSource_id(String source_id) {
+    public void setSource_id( String source_id )
+    {
         this.source_id = source_id;
     }
 
+    public void setSmsOutput( SMSOutput smsOutput )
+    {
+        this.smsOutput = smsOutput;
+    }
+
 }

=== modified file 'dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/input/SMSParserKeyValue.java'
--- dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/input/SMSParserKeyValue.java	2012-06-18 06:14:19 +0000
+++ dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/input/SMSParserKeyValue.java	2012-07-22 12:04:11 +0000
@@ -8,65 +8,90 @@
 import java.util.Map;
 
 /**
- *
+ * 
  * @author Christian
  */
-public class SMSParserKeyValue implements IParser {
-
-    private String separatorBetweenKeyValuePairs = " "; // The separator between two different keys, ie. 'ANC10 BCG15' separator being ' '
+public class SMSParserKeyValue
+    implements IParser
+{
+
+    private String separatorBetweenKeyValuePairs = " "; // The separator between
+                                                        // two different keys,
+                                                        // ie. 'ANC10 BCG15'
+                                                        // separator being ' '
+
     private String separatorBetweenKeyAndValue = "";
+
     private boolean canUseNumbersInKey = false;
+
     private boolean firstWordIsKeyWord = true;
+
     private String separatorForDataEntryKeyword = " ";
 
     @Override
-    public Map<String, String> parse(String sms) {
-        System.out.println("SMS Input is: '"+sms+"'");
-        sms = sms.replaceAll("\r\n"," ");
-        sms = sms.replaceAll("\r", "");
-        sms = sms.replaceAll("\n", " ");
+    public Map<String, String> parse( String sms )
+    {
+        System.out.println( "SMS Input is: '" + sms + "'" );
+        sms = sms.replaceAll( "\r\n", " " );
+        sms = sms.replaceAll( "\r", "" );
+        sms = sms.replaceAll( "\n", " " );
 
         HashMap<String, String> output = new HashMap<String, String>();
-        
-        if (firstWordIsKeyWord) {
-            int reportKeyWordLength = sms.indexOf(separatorForDataEntryKeyword);
-            String dataEntryKeyword = sms.substring(0, reportKeyWordLength);
-            System.out.println("Report keyword is: " + dataEntryKeyword);
-            output.put(DATA_ENTRY_KEYWORD, dataEntryKeyword);
-            sms = sms.substring(reportKeyWordLength); // Remove the keyword
-            
-            if( sms.startsWith(separatorForDataEntryKeyword) ) {
-                sms = sms.replaceFirst(separatorForDataEntryKeyword, ""); // remove the keyword separator at the beginning
+
+        if ( firstWordIsKeyWord )
+        {
+            int reportKeyWordLength = sms.indexOf( separatorForDataEntryKeyword );
+            String dataEntryKeyword = sms.substring( 0, reportKeyWordLength );
+            System.out.println( "Report keyword is: " + dataEntryKeyword );
+            output.put( DATA_ENTRY_KEYWORD, dataEntryKeyword.toUpperCase() );
+            sms = sms.substring( reportKeyWordLength ); // Remove the keyword
+
+            if ( sms.startsWith( separatorForDataEntryKeyword ) )
+            {
+                sms = sms.replaceFirst( separatorForDataEntryKeyword, "" ); // remove
+                                                                            // the
+                                                                            // keyword
+                                                                            // separator
+                                                                            // at
+                                                                            // the
+                                                                            // beginning
             }
-            System.out.println("SMS is now: '"+sms+"'");
+            System.out.println( "SMS is now: '" + sms + "'" );
         }
         // Now move onto the message/data entry part
         sms = sms.trim();
-        String[] smsArr = sms.split(separatorBetweenKeyValuePairs);
+        String[] smsArr = sms.split( separatorBetweenKeyValuePairs );
 
-        for (int i = 0; i < smsArr.length; i++) {
+        for ( int i = 0; i < smsArr.length; i++ )
+        {
             String s = smsArr[i];
             s = s.trim();
-            
-            if (!canUseNumbersInKey && separatorBetweenKeyAndValue.isEmpty()) { // Can't use numbers in key and no sep between key and value
-                for (int j = 0; j < s.length(); j++) {
-                    if (Character.isDigit(s.charAt(j))) { // If char is a digit and we can't use numbers in key
-                        String key = s.substring(0, j);
-                        String value = s.substring(j);
-                        
-                        output.put(key.trim(), value.trim());
-                        System.out.println("Found Key: " + key + " Value: " + value);
-                        System.out.println("");
+
+            if ( !canUseNumbersInKey && separatorBetweenKeyAndValue.isEmpty() )
+            { // Can't use numbers in key and no sep between key and value
+                for ( int j = 0; j < s.length(); j++ )
+                {
+                    if ( Character.isDigit( s.charAt( j ) ) )
+                    { // If char is a digit and we can't use numbers in key
+                        String key = s.substring( 0, j ).trim().toUpperCase();
+                        String value = s.substring( j );
+
+                        output.put( key, value.trim() );
+                        System.out.println( "Found Key: " + key + " Value: " + value );
+                        System.out.println( "" );
                         break;
                     }
                 }
-            } else if( !separatorBetweenKeyAndValue.isEmpty()) { // When there is a separator between key and value you can implisitly use numbers in key.
-                String[] split = s.split(separatorBetweenKeyAndValue);
-                if(split.length != 2)
+            }
+            else if ( !separatorBetweenKeyAndValue.isEmpty() )
+            { // When there is a separator between key and value you can
+              // implisitly use numbers in key.
+                String[] split = s.split( separatorBetweenKeyAndValue );
+                if ( split.length != 2 )
                     continue;
-                String key = split[0];
+                String key = split[0].trim().toUpperCase();
                 String value = split[1];
-                output.put(key.trim(), value.trim());
+                output.put( key, value.trim() );
             }
 
         }
@@ -74,60 +99,70 @@
         return output;
     }
 
-    
-    private boolean containsIllegalChars(String input) {
-        if( input.indexOf(separatorBetweenKeyAndValue) != -1) {
-            return true;
-        } else if(input.indexOf(separatorBetweenKeyValuePairs) == -1) { // Perhaps just remove it? though we can't be sure if it's correct
-            return true;
-        } else if(input.indexOf(separatorForDataEntryKeyword) == -1) {
-            return true;
-        }
-        
+    private boolean containsIllegalChars( String input )
+    {
+        if ( input.indexOf( separatorBetweenKeyAndValue ) != -1 )
+        {
+            return true;
+        }
+        else if ( input.indexOf( separatorBetweenKeyValuePairs ) == -1 )
+        { // Perhaps just remove it? though we can't be sure if it's correct
+            return true;
+        }
+        else if ( input.indexOf( separatorForDataEntryKeyword ) == -1 )
+        {
+            return true;
+        }
+
         return false;
     }
-    
-    public SMSParserKeyValue() {
+
+    public SMSParserKeyValue()
+    {
     }
 
-    public SMSParserKeyValue(String sepBetwKeyAndValue, String sepBetwKeyValuePairs, String sepForDataEntryKeyword,
-            boolean firstWordIsKeyWord, boolean canUseNumbersInKey) {
+    public SMSParserKeyValue( String sepBetwKeyAndValue, String sepBetwKeyValuePairs, String sepForDataEntryKeyword,
+        boolean firstWordIsKeyWord, boolean canUseNumbersInKey )
+    {
         this.separatorBetweenKeyAndValue = sepBetwKeyAndValue;
         this.separatorBetweenKeyValuePairs = sepBetwKeyValuePairs;
         this.separatorForDataEntryKeyword = sepForDataEntryKeyword;
-        
-        this.canUseNumbersInKey=canUseNumbersInKey;
-        this.firstWordIsKeyWord = firstWordIsKeyWord; 
-        
-        if(!sepBetwKeyAndValue.isEmpty())
+
+        this.canUseNumbersInKey = canUseNumbersInKey;
+        this.firstWordIsKeyWord = firstWordIsKeyWord;
+
+        if ( !sepBetwKeyAndValue.isEmpty() )
             this.canUseNumbersInKey = true;
     }
-        
-    public void setCanUseNumbersInKey(boolean canUseNumbersInKey) {
+
+    public void setCanUseNumbersInKey( boolean canUseNumbersInKey )
+    {
         this.canUseNumbersInKey = canUseNumbersInKey;
     }
 
-    public void setFirstWordIsKeyWord(boolean firstWordIsKeyWord) {
+    public void setFirstWordIsKeyWord( boolean firstWordIsKeyWord )
+    {
         this.firstWordIsKeyWord = firstWordIsKeyWord;
     }
 
-    public void setSeparatorBetweenKeyAndValue(String separatorBetweenKeyAndValue) {
+    public void setSeparatorBetweenKeyAndValue( String separatorBetweenKeyAndValue )
+    {
         this.separatorBetweenKeyAndValue = separatorBetweenKeyAndValue;
-        if( separatorBetweenKeyAndValue != null && !separatorBetweenKeyAndValue.isEmpty()) {
+        if ( separatorBetweenKeyAndValue != null && !separatorBetweenKeyAndValue.isEmpty() )
+        {
             canUseNumbersInKey = true;
         }
-        
+
     }
 
-    public void setSeparatorBetweenKeyValuePairs(String separatorBetweenKeyValuePairs) {
+    public void setSeparatorBetweenKeyValuePairs( String separatorBetweenKeyValuePairs )
+    {
         this.separatorBetweenKeyValuePairs = separatorBetweenKeyValuePairs;
     }
 
-    public void setSeparatorForDataEntryKeyword(String separatorForDataEntryKeyword) {
+    public void setSeparatorForDataEntryKeyword( String separatorForDataEntryKeyword )
+    {
         this.separatorForDataEntryKeyword = separatorForDataEntryKeyword;
     }
-    
-    
-    
-    
+
 }

=== added directory 'dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/output'
=== added file 'dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/output/BulkSMSOutput.java'
--- dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/output/BulkSMSOutput.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/output/BulkSMSOutput.java	2012-07-22 12:04:11 +0000
@@ -0,0 +1,83 @@
+package org.hisp.dhis.sms.output;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+
+import org.hisp.dhis.sms.SmsConfigurationManager;
+import org.hisp.dhis.sms.config.BulkSmsGatewayConfig;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class BulkSMSOutput
+    implements SMSOutput
+{
+
+    @Autowired
+    private SmsConfigurationManager smsConfigurationManager;
+
+    @Override
+    public void sendSMS( String message, String mobileNumber )
+    {
+
+        BulkSmsGatewayConfig gatewayConfig = (BulkSmsGatewayConfig) smsConfigurationManager
+            .checkInstanceOfGateway( BulkSmsGatewayConfig.class );
+
+        try
+        {
+            // Construct data
+            String data = "";
+            /*
+             * Note the suggested encoding for certain parameters, notably the
+             * username, password and especially the message. ISO-8859-1 is
+             * essentially the character set that we use for message bodies,
+             * with a few exceptions for e.g. Greek characters. For a full list,
+             * see:
+             * http://bulksms.vsms.net/docs/eapi/submission/character_encoding/
+             */
+            data += "username=" + URLEncoder.encode( gatewayConfig.getUsername(), "ISO-8859-1" );
+            data += "&password=" + URLEncoder.encode( gatewayConfig.getPassword(), "ISO-8859-1" );
+            data += "&message=" + URLEncoder.encode( message, "ISO-8859-1" );
+            data += "&want_report=1";
+            data += "&msisdn=" + mobileNumber;
+
+            // Send data
+            URL url = new URL( "http://www.bulksms.co.uk:5567/eapi/submission/send_sms/2/2.0"; );
+            /*
+             * If your firewall blocks access to port 5567, you can fall back to
+             * port 80: URL url = new
+             * URL("http://bulksms.vsms.net/eapi/submission/send_sms/2/2.0";);
+             * (See FAQ for more details.)
+             */
+
+            URLConnection conn = url.openConnection();
+            conn.setDoOutput( true );
+            OutputStreamWriter wr = new OutputStreamWriter( conn.getOutputStream() );
+            wr.write( data );
+            wr.flush();
+
+            // Get the response
+            BufferedReader rd = new BufferedReader( new InputStreamReader( conn.getInputStream() ) );
+            String line;
+            while ( (line = rd.readLine()) != null )
+            {
+                // Print the response output...
+                System.out.println( line );
+            }
+            wr.close();
+            rd.close();
+        }
+        catch ( Exception e )
+        {
+            e.printStackTrace();
+        }
+    }
+
+    public void setSmsConfigurationManager( SmsConfigurationManager smsConfigurationManager )
+    {
+        this.smsConfigurationManager = smsConfigurationManager;
+    }
+
+}

=== added file 'dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/output/SMSOutput.java'
--- dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/output/SMSOutput.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/output/SMSOutput.java	2012-07-22 12:04:11 +0000
@@ -0,0 +1,8 @@
+package org.hisp.dhis.sms.output;
+
+public interface SMSOutput
+{
+
+    public void sendSMS( String message, String mobileNumber );
+
+}

=== modified file 'dhis-2/dhis-web/dhis-web-sms/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-web/dhis-web-sms/src/main/resources/META-INF/dhis/beans.xml	2012-07-10 14:57:33 +0000
+++ dhis-2/dhis-web/dhis-web-sms/src/main/resources/META-INF/dhis/beans.xml	2012-07-22 12:04:11 +0000
@@ -18,16 +18,17 @@
 		<property name="periodService" ref="org.hisp.dhis.period.PeriodService"/>
 	</bean>
 	
-        <!-- added by Chris -->
-        <bean id="org.hisp.dhis.sms.input.SMSInput" class="org.hisp.dhis.sms.input.SMSInput">
-            <property name="smsStore" ref="org.hisp.dhis.sms.incoming.IncomingSmsStore"/>
-            <property name="userService" ref="org.hisp.dhis.user.UserService"/>
-            <property name="organisationUnitService" ref="org.hisp.dhis.organisationunit.OrganisationUnitService"/>
-            <property name="smsCommandService" ref="smsCommandService" />
-            <property name="currentUserService" ref="org.hisp.dhis.user.CurrentUserService"/>
-            <property name="dataValueService" ref="org.hisp.dhis.datavalue.DataValueService"/>
-            
-        </bean>
+    <bean id="org.hisp.dhis.sms.input.SMSInput" class="org.hisp.dhis.sms.input.SMSInput">
+        <property name="smsStore" ref="org.hisp.dhis.sms.incoming.IncomingSmsStore"/>
+        <property name="userService" ref="org.hisp.dhis.user.UserService"/>
+        <property name="smsCommandService" ref="smsCommandService" />
+        <property name="currentUserService" ref="org.hisp.dhis.user.CurrentUserService"/>
+        <property name="dataValueService" ref="org.hisp.dhis.datavalue.DataValueService"/>
+        <property name="smsOutput" ref="org.hisp.dhis.sms.output.BulkSMSOutput" /> <!--  replace later -->
+    </bean>
+    
+  <bean id="org.hisp.dhis.sms.output.BulkSMSOutput" class="org.hisp.dhis.sms.output.BulkSMSOutput" />
+  
         
 	<!-- Data entry -->