=== modified file 'dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/parse/DefaultParserManager.java' --- dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/parse/DefaultParserManager.java 2013-03-09 12:23:42 +0000 +++ dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/parse/DefaultParserManager.java 2013-03-13 06:43:01 +0000 @@ -1,5 +1,6 @@ package org.hisp.dhis.sms.parse; +import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; @@ -7,7 +8,6 @@ import java.util.Date; import java.util.Iterator; import java.util.Map; - import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -22,7 +22,13 @@ import org.hisp.dhis.datavalue.DataValueService; import org.hisp.dhis.organisationunit.OrganisationUnit; import org.hisp.dhis.period.CalendarPeriodType; +import org.hisp.dhis.period.DailyPeriodType; +import org.hisp.dhis.period.MonthlyPeriodType; import org.hisp.dhis.period.Period; +import org.hisp.dhis.period.PeriodType; +import org.hisp.dhis.period.QuarterlyPeriodType; +import org.hisp.dhis.period.WeeklyPeriodType; +import org.hisp.dhis.period.YearlyPeriodType; import org.hisp.dhis.sms.incoming.IncomingSms; import org.hisp.dhis.sms.outbound.OutboundSms; import org.hisp.dhis.sms.outbound.OutboundSmsService; @@ -99,7 +105,6 @@ } Collection orgUnits = getOrganisationUnitsByPhoneNumber( sender ); - if ( orgUnits == null || orgUnits.size() == 0 ) { throw new SMSParserException( "No user associated with this phone number. Please contact your supervisor." ); @@ -125,6 +130,11 @@ runKeyValueParser( sender, message, orgUnits, command ); break; } + else + { + runJ2MEParser( sender, message, orgUnits, command ); + break; + } } } if ( !foundCommand ) @@ -137,7 +147,6 @@ { Collection orgUnits = new ArrayList(); Collection users = userService.getUsersByPhoneNumber( sender ); - for ( User u : users ) { if ( u.getOrganisationUnits() != null ) @@ -516,6 +525,267 @@ } return user; } + + //Run the J2ME parser for mobile + + private void runJ2MEParser( String sender, String message, Collection orgUnits, SMSCommand command ) + { + J2MEDataEntryParser j2meParser = new J2MEDataEntryParser(); + j2meParser.setSmsCommand( command ); + message = message.trim(); + + if ( !StringUtils.isBlank( command.getSeparator() ) ) + { + j2meParser.setSeparator( command.getSeparator() ); + } + String token[] = message.split( "!" ); + Period period = getPeriod( token[0].trim(), command.getDataset().getPeriodType() ); + Map parsedMessage = j2meParser.parse( token[1] ); + OrganisationUnit orgUnit = selectOrganisationUnit( orgUnits, parsedMessage ); + + boolean valueStored = false; + for ( SMSCode code : command.getCodes() ) + { + if ( parsedMessage.containsKey( code.getCode().toUpperCase() ) ) + { + storeDataValue( sender, orgUnit, parsedMessage, code, command, period, command.getDataset(), + formIsComplete( command, parsedMessage ) ); + valueStored = true; + } + } + + if ( parsedMessage.isEmpty() || !valueStored ) + { + if ( StringUtils.isEmpty( command.getDefaultMessage() ) ) + { + throw new SMSParserException( "No values reported for command '" + command.getName() + "'" ); + } + else + { + throw new SMSParserException( command.getDefaultMessage() ); + } + } + + registerCompleteDataSet( command.getDataset(), period, orgUnit, "mobile" ); + + sendSuccessFeedback( sender, command, parsedMessage, period, orgUnit ); + + } + + private void sendSuccessFeedback( String sender, SMSCommand command, Map parsedMessage, + Period period, OrganisationUnit orgUnit ) + { + String reportBack = "Thank you! Values entered: "; + String notInReport = "Missing values for: "; + boolean missingElements = false; + + for ( SMSCode code : command.getCodes() ) + { + + DataElementCategoryOptionCombo optionCombo = dataElementCategoryService + .getDataElementCategoryOptionCombo( code.getOptionId() ); + + DataValue dv = dataValueService.getDataValue( orgUnit, code.getDataElement(), period, optionCombo ); + + if ( dv == null && !StringUtils.isEmpty( code.getCode() ) ) + { + notInReport += code.getCode() + ","; + missingElements = true; + } + else if ( dv != null ) + { + String value = dv.getValue(); + if ( StringUtils.equals( dv.getDataElement().getType(), DataElement.VALUE_TYPE_BOOL ) ) + { + if ( "true".equals( value ) ) + { + value = "Yes"; + } + else if ( "false".equals( value ) ) + { + value = "No"; + } + } + reportBack += code.getCode() + "=" + value + " "; + } + } + + notInReport = notInReport.substring( 0, notInReport.length() - 1 ); + + if ( missingElements ) + { + sendSMS( reportBack + notInReport, sender ); + } + else + { + sendSMS( reportBack, sender ); + } + + } + + private void storeDataValue( String sender, OrganisationUnit orgUnit, Map parsedMessage, + SMSCode code, SMSCommand command, Period period, DataSet dataset, boolean formIsComplete ) + { + String upperCaseCode = code.getCode().toUpperCase(); + + String storedBy = getUser( sender ).getUsername(); + + if ( StringUtils.isBlank( storedBy ) ) + { + storedBy = "[unknown] from [" + sender + "]"; + } + + DataElementCategoryOptionCombo optionCombo = dataElementCategoryService.getDataElementCategoryOptionCombo( code + .getOptionId() ); + + DataValue dv = dataValueService.getDataValue( orgUnit, code.getDataElement(), period, optionCombo ); + + String value = parsedMessage.get( upperCaseCode ); + if ( !StringUtils.isEmpty( value ) ) + { + boolean newDataValue = false; + if ( dv == null ) + { + dv = new DataValue(); + dv.setOptionCombo( optionCombo ); + dv.setSource( orgUnit ); + dv.setDataElement( code.getDataElement() ); + dv.setPeriod( period ); + dv.setComment( "" ); + newDataValue = true; + } + + if ( StringUtils.equals( dv.getDataElement().getType(), DataElement.VALUE_TYPE_BOOL ) ) + { + if ( "Y".equals( value.toUpperCase() ) || "YES".equals( value.toUpperCase() ) ) + { + value = "true"; + } + else if ( "N".equals( value.toUpperCase() ) || "NO".equals( value.toUpperCase() ) ) + { + value = "false"; + } + } + + dv.setValue( value ); + dv.setTimestamp( new java.util.Date() ); + dv.setStoredBy( storedBy ); + + if ( newDataValue ) + { + dataValueService.addDataValue( dv ); + } + else + { + dataValueService.updateDataValue( dv ); + } + } + + } + + public static Period getPeriod( String periodName, PeriodType periodType ) + throws IllegalArgumentException + { + + if ( periodType instanceof DailyPeriodType ) + { + String pattern = "yyyy-MM-dd"; + SimpleDateFormat formatter = new SimpleDateFormat( pattern ); + Date date; + try + { + date = formatter.parse( periodName ); + } + catch ( ParseException e ) + { + throw new IllegalArgumentException( "Couldn't make a period of type " + periodType.getName() + + " and name " + periodName, e ); + } + return periodType.createPeriod( date ); + + } + + if ( periodType instanceof WeeklyPeriodType ) + { + String pattern = "yyyy-MM-dd"; + SimpleDateFormat formatter = new SimpleDateFormat( pattern ); + Date date; + try + { + date = formatter.parse( periodName ); + } + catch ( ParseException e ) + { + throw new IllegalArgumentException( "Couldn't make a period of type " + periodType.getName() + + " and name " + periodName, e ); + } + return periodType.createPeriod( date ); + } + + if ( periodType instanceof MonthlyPeriodType ) + { + int dashIndex = periodName.indexOf( '-' ); + + if ( dashIndex < 0 ) + { + return null; + } + + int month = Integer.parseInt( periodName.substring( 0, dashIndex ) ); + int year = Integer.parseInt( periodName.substring( dashIndex + 1, periodName.length() ) ); + + Calendar cal = Calendar.getInstance(); + cal.set( Calendar.YEAR, year ); + cal.set( Calendar.MONTH, month ); + + return periodType.createPeriod( cal.getTime() ); + } + + if ( periodType instanceof YearlyPeriodType ) + { + Calendar cal = Calendar.getInstance(); + cal.set( Calendar.YEAR, Integer.parseInt( periodName ) ); + + return periodType.createPeriod( cal.getTime() ); + } + + if ( periodType instanceof QuarterlyPeriodType ) + { + Calendar cal = Calendar.getInstance(); + + int month = 0; + if ( periodName.substring( 0, periodName.indexOf( " " ) ).equals( "Jan" ) ) + { + month = 1; + } + else if ( periodName.substring( 0, periodName.indexOf( " " ) ).equals( "Apr" ) ) + { + month = 4; + } + else if ( periodName.substring( 0, periodName.indexOf( " " ) ).equals( "Jul" ) ) + { + month = 6; + } + else if ( periodName.substring( 0, periodName.indexOf( " " ) ).equals( "Oct" ) ) + { + month = 10; + } + + int year = Integer.parseInt( periodName.substring( periodName.lastIndexOf( " " ) + 1 ) ); + + cal.set( Calendar.MONTH, month ); + cal.set( Calendar.YEAR, year ); + + if ( month != 0 ) + { + return periodType.createPeriod( cal.getTime() ); + } + + } + + throw new IllegalArgumentException( "Couldn't make a period of type " + periodType.getName() + " and name " + + periodName ); + } public void setDataElementCategoryService( DataElementCategoryService dataElementCategoryService ) { === modified file 'dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/parse/J2MEDataEntryParser.java' --- dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/parse/J2MEDataEntryParser.java 2013-01-22 08:08:14 +0000 +++ dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/parse/J2MEDataEntryParser.java 2013-03-13 06:43:01 +0000 @@ -1,24 +1,53 @@ package org.hisp.dhis.sms.parse; +import java.util.HashMap; import java.util.Map; +import java.util.regex.Pattern; + +import org.hisp.dhis.smscommand.SMSCommand; public class J2MEDataEntryParser implements IParser { + private SMSCommand smsCommand; @Override public Map parse( String sms ) { - String keyValueSection = sms.split( "" )[1]; - - return null; + String[] keyValuePairs = null; + if ( sms.indexOf( "#" ) > -1 ) + { + keyValuePairs = sms.split( "#" ); + } + else + { + keyValuePairs = new String[1]; + keyValuePairs[0] = sms; + } + + Map keyValueMap = new HashMap(); + for ( String keyValuePair : keyValuePairs ) + { + String[] token = keyValuePair.split( Pattern.quote( smsCommand.getSeparator() ) ); + keyValueMap.put( token[0], token[1] ); + } + + return keyValueMap; } @Override public void setSeparator( String separator ) { // TODO Auto-generated method stub - - } - + } + + public SMSCommand getSmsCommand() + { + return smsCommand; + } + + public void setSmsCommand( SMSCommand smsCommand ) + { + this.smsCommand = smsCommand; + } }