fineract-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From raj...@apache.org
Subject [10/14] incubator-fineract git commit: SMS Campaign feature implementation
Date Mon, 14 Nov 2016 14:06:12 GMT
SMS Campaign feature implementation


Project: http://git-wip-us.apache.org/repos/asf/incubator-fineract/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-fineract/commit/911cab85
Tree: http://git-wip-us.apache.org/repos/asf/incubator-fineract/tree/911cab85
Diff: http://git-wip-us.apache.org/repos/asf/incubator-fineract/diff/911cab85

Branch: refs/heads/develop
Commit: 911cab85b02de34f4469324a75da8fb4ad34ece7
Parents: 580840c
Author: Satish <satish.sajjan@confluxtechnologies.com>
Authored: Fri Nov 11 15:49:23 2016 +0530
Committer: Satish <satish.sajjan@confluxtechnologies.com>
Committed: Fri Nov 11 18:56:12 2016 +0530

----------------------------------------------------------------------
 api-docs/apiLive.htm                            | 327 ++++++++-
 .../commands/service/CommandWrapperBuilder.java |  47 ++
 .../campaigns/constants/CampaignType.java       |  76 ++
 .../campaigns/helper/SmsConfigUtils.java        |  76 ++
 .../sms/api/SmsCampaignApiResource.java         | 195 ++++++
 .../sms/constants/SmsCampaignConstants.java     |  43 ++
 .../sms/constants/SmsCampaignEnumerations.java  |  92 +++
 .../sms/constants/SmsCampaignStatus.java        |  72 ++
 .../sms/constants/SmsCampaignTriggerType.java   |  98 +++
 .../campaigns/sms/data/CampaignPreviewData.java |  39 ++
 .../sms/data/CampaignTriggerWithSubTypes.java   | 298 ++++++++
 .../data/MessageGatewayConfigurationData.java   |  81 +++
 .../sms/data/SmsBusinessRulesData.java          |  92 +++
 .../campaigns/sms/data/SmsCampaignData.java     | 206 ++++++
 .../campaigns/sms/data/SmsCampaignTimeLine.java |  44 ++
 .../campaigns/sms/data/SmsProviderData.java     |  72 ++
 .../sms/data/TriggerTypeWithSubTypesData.java   |  43 ++
 .../campaigns/sms/domain/SmsCampaign.java       | 561 +++++++++++++++
 .../sms/domain/SmsCampaignRepository.java       |  35 +
 .../domain/SmsCampaignStatusEnumerations.java   |  55 ++
 .../exception/ConnectionFailureException.java   |  30 +
 .../GatewayConnectionConfigurationNotFound.java |  30 +
 ...ampaignMustBeClosedToBeDeletedException.java |  28 +
 .../SmsCampaignMustBeClosedToEditException.java |  29 +
 .../sms/exception/SmsCampaignNotFound.java      |  28 +
 .../ActivateSmsCampaignCommandHandler.java      |  47 ++
 .../handler/CloseSmsCampaignCommandHandler.java |  43 ++
 .../CreateSmsCampaignCommandHandler.java        |  46 ++
 .../DeleteSmsCampaignCommandHandler.java        |  45 ++
 .../ReactivateSmsCampaignCommandHandler.java    |  45 ++
 .../UpdateSmsCampaignCommandHandler.java        |  46 ++
 .../sms/serialization/SmsCampaignValidator.java | 302 ++++++++
 .../sms/service/SmsCampaignDomainService.java   |  25 +
 .../service/SmsCampaignDomainServiceImpl.java   | 537 +++++++++++++++
 .../SmsCampaignDropdownReadPlatformService.java |  43 ++
 ...CampaignDropdownReadPlatformServiceImpl.java | 125 ++++
 .../service/SmsCampaignReadPlatformService.java |  36 +
 .../SmsCampaignReadPlatformServiceImpl.java     | 260 +++++++
 .../SmsCampaignWritePlatformService.java        |  59 ++
 .../SmsCampaignWritePlatformServiceJpaImpl.java | 687 +++++++++++++++++++
 ...ropertiesCommandFromApiJsonDeserializer.java |   6 +
 .../service/ExternalServicesConstants.java      |  37 +
 ...alServicesPropertiesReadPlatformService.java |   3 +
 ...rvicesPropertiesReadPlatformServiceImpl.java |  39 ++
 ...ExternalServicesReadPlatformServiceImpl.java |   4 +
 .../core/serialization/FromJsonHelper.java      |   4 +
 .../core/serialization/JsonParserHelper.java    |  13 +
 .../core/service/PaginationHelper.java          |  10 +
 .../core/service/SearchParameters.java          |  16 +
 .../service/ReadReportingService.java           |   5 +
 .../service/ReadReportingServiceImpl.java       |  31 +
 .../infrastructure/jobs/service/JobName.java    |   5 +-
 .../infrastructure/sms/SmsApiConstants.java     |   5 +-
 .../infrastructure/sms/api/SmsApiResource.java  |  34 +
 .../infrastructure/sms/data/SmsData.java        |  54 +-
 .../data/SmsMessageApiQueueResourceData.java    | 125 ++++
 .../data/SmsMessageApiReportResourceData.java   |  75 ++
 .../sms/data/SmsMessageApiResponseData.java     |  67 ++
 .../sms/data/SmsMessageDeliveryReportData.java  | 113 +++
 .../infrastructure/sms/domain/SmsMessage.java   | 104 ++-
 .../sms/domain/SmsMessageAssembler.java         |  18 +-
 .../sms/domain/SmsMessageRepository.java        |   5 +-
 .../sms/domain/SmsMessageStatusType.java        |   4 +
 .../SmsCountryCodeNotFoundException.java        |  28 +
 .../SmsMessageScheduledJobService.java          |  47 ++
 .../SmsMessageScheduledJobServiceImpl.java      | 295 ++++++++
 .../sms/service/SmsReadPlatformService.java     |  20 +
 .../sms/service/SmsReadPlatformServiceImpl.java | 145 +++-
 .../portfolio/client/domain/Client.java         |   8 +-
 .../client/domain/ClientTransaction.java        |   4 +
 ...ntWritePlatformServiceJpaRepositoryImpl.java |  70 +-
 .../BusinessEventNotificationConstants.java     |  31 +-
 .../loanaccount/api/LoansApiResource.java       |  12 +-
 .../portfolio/loanaccount/domain/Loan.java      |   6 +-
 .../loanaccount/domain/LoanTransaction.java     |   8 +
 .../exception/InvalidLoanTypeException.java     |  32 +
 ...onWritePlatformServiceJpaRepositoryImpl.java |   2 +-
 .../service/LoanReadPlatformServiceImpl.java    |   1 -
 .../paymentdetail/domain/PaymentDetail.java     |   1 +
 .../domain/SavingsAccountDomainServiceJpa.java  |  28 +-
 .../domain/SavingsAccountTransaction.java       |   8 +-
 ...ntWritePlatformServiceJpaRepositoryImpl.java |  75 +-
 ...ssWritePlatformServiceJpaRepositoryImpl.java |  20 +-
 ...erWritePlatformServiceJpaRepositoryImpl.java |  37 +-
 .../resources/META-INF/spring/appContext.xml    |   1 +
 .../migrations/core_db/V322__sms_campaign.sql   | 277 ++++++++
 86 files changed, 6882 insertions(+), 94 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/911cab85/api-docs/apiLive.htm
----------------------------------------------------------------------
diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm
index abd6867..c2a06be 100644
--- a/api-docs/apiLive.htm
+++ b/api-docs/apiLive.htm
@@ -2064,7 +2064,46 @@
 								<td><a href="#shareproducts_retrieve">Retrieve a Share product</a></td>
 								<td><a href="#shareproducts_update">Update a Share product</a></td>
 							</tr>
-
+							<tr>
+								<td><a href="#smscampaigns">SMS Campaigns</a></td>
+								<td>smscampaigns</td>
+								<td><a href="#smscampaigns_create">Create a SMS Campaign</a></td>
+								<td><a href="#smscampaigns_list">List SMS Campaigns</a></td>
+								<td></td>
+								<td></td>
+							</tr>
+							tr>
+								<td></td>
+								<td>smscampaigns/{campaignId}</td>
+								<td></td>
+								<td><a href="#smscampaigns_retrieve">Retrieve a SMS Campaign</a></td>
+								<td><a href="#smscampaigns_update">Update a SMS Campaign</a></td>
+								<td><a href="#smscampaigns_delete">Delete a SMS Campaign</a></td>
+							</tr>
+							<tr>
+								<td></td>
+								<td>smscampaigns/{campaignId}command=activate</td>
+								<td></td>
+								<td><a href="#smscampaigns_activate">Activate a SMS Campaign</a></td>
+								<td></td>
+								<td></td>
+							</tr>
+							<tr>
+								<td></td>
+								<td>smscampaigns/{campaignId}command=close</td>
+								<td></td>
+								<td><a href="#smscampaigns_close">Close a SMS Campaign</a></td>
+								<td></td>
+								<td></td>
+							</tr>
+							<tr>
+								<td></td>
+								<td>smscampaigns/{campaignId}command=reactivate</td>
+								<td></td>
+								<td><a href="#smscampaigns_reactivate">Reactivate a SMS Campaign</a></td>
+								<td></td>
+								<td></td>
+							</tr>
 							<tr>
 								<td><a href="#configs">Currency</a></td>
 								<td>currencies</td>
@@ -21038,7 +21077,291 @@ Content-Type: application/json
         </div>
     </div>
 
-	<a id="shareproducts_create" name="shareproducts_create" class="old-syle-anchor">&nbsp;</a>
+	<a id="smscampaigns_create" name="smscampaigns_create" class="old-syle-anchor">&nbsp;</a>
+    <div class="method-section">
+        <div class="method-description">
+            <h4>Create a SMS Campaign</h4>
+            <table class=matrixHeading>
+                <tr class="matrixHeadingBG"><td><div class="fineractHeading2">Mandatory Fields</div></td></tr>
+                <tr class=alt>
+                	<td>campaignName, campaignType, triggerType, providerId, runReportId, message</td>
+                </tr>
+            </table>
+            <br/>
+            <table class=matrixHeading>
+                <tr class="matrixHeadingBG"><td><div class="fineractHeading2">Mandatory Fields for Cash based on selected report id</div></td></tr>
+                <tr class=alt>
+                	<td>paramValue in json format</td>
+                </tr>
+            </table>
+          </div>
+        <div class="method-example">
+
+            <code class="method-declaration">POST https://Domain Name/api/v1/smscampaigns</code>
+			<code class="method-request">POST smscampaigns
+Content-Type: application/json
+Request Body:
+{
+"campaignName": "Savings Deposit Campaign",
+"campaignType": "SMS",
+"triggerType": 3,
+"providerId": 2,
+"runReportId": 180,
+"paramValue": "{"officeId":1,"loanOfficerId":-1,"transactionId":1,"reportName":"Savings Deposit"}",
+"message": "Hello {fullName} your account is credited with {depositAmount} on {transactionDate}",
+}
+
+			</code>
+			<code class="method-response">
+{
+  "resourceId": 1
+}
+</code>
+			
+        </div>
+</div>
+
+<a id="smscampaigns_list" name="smscampaigns_list" class="old-syle-anchor">&nbsp;</a>
+    <div class="method-section">
+        <div class="method-description">
+            <h4>List SMS Campaigns</h4>
+			<table class=matrixHeading>
+                <tr class="matrixHeadingBG"><td><div class="fineractHeading2">Mandatory Fields</div></td></tr>
+                <tr class=alt>
+                	<td></td>
+                </tr>
+            </table>
+            <p>Example Requests:</p>
+            <div class=apiClick>smscampaigns</div>
+        </div>
+        <div class="method-example">
+
+            <code class="method-declaration">GET https://Domain Name/api/v1/smscampaigns</code>
+            <code class="method-response">
+
+[{
+		"id": 1,
+		"campaignName": "Savings Deposit Campaign"
+		"campaignType": "SMS",
+		"triggerType": 3,
+		"providerId": 2,
+		"runReportId": 180,
+		"reportName" : "Savings Deposit",
+		"paramValue": "{"officeId":1,"loanOfficerId":-1,"transactionId":1,"reportName":"Savings Deposit"}",
+		"message": "Hello {fullName} your account is credited with {depositAmount} on {transactionDate}",
+		"status" : { "id":"","code":"","value":""}
+		
+}]
+</code>
+       </div>
+</div>
+
+<a id="smscampaigns_retrieve" name="smscampaigns_retrieve" class="old-syle-anchor">&nbsp;</a>
+    <div class="method-section">
+        <div class="method-description">
+            <h4>Retrieve a Share Product</h4>
+            <p>Example Requests: </p>
+            <div class=apiClick>smscampaigns/1</div>
+            <br><br>
+            <div class=apiClick>smscampaigns/1?template=true</div>
+        </div>
+        <div class="method-example">
+			<code class="method-declaration">GET https://Domain Name/api/v1/smscampaigns/1</code>
+			<code class="method-response">
+{
+		"id": 1,
+		"campaignName": "Savings Deposit Campaign"
+		"campaignType": "SMS",
+		"triggerType": 3,
+		"providerId": 2,
+		"runReportId": 180,
+		"reportName" : "Savings Deposit",
+		"paramValue": "{"officeId":1,"loanOfficerId":-1,"transactionId":1,"reportName":"Savings Deposit"}",
+		"message": "Hello {fullName} your account is credited with {depositAmount} on {transactionDate}",
+		"status" : { "id":"","code":"","value":""}				
+}
+<B>In case of Scheduled Campaign</B>
+{
+		"id": 1,
+		"campaignName": "Savings Deposit Campaign"
+		"campaignType": "SMS",
+		"triggerType": 3,
+		"providerId": 2,
+		"runReportId": 180,
+		"reportName" : "Savings Deposit",
+		"paramValue": "{"officeId":1,"loanOfficerId":-1,"transactionId":1,"reportName":"Savings Deposit"}",
+		"message": "Hello {fullName} your account is credited with {depositAmount} on {transactionDate}",
+		"status" : { "id":"","code":"","value":""},
+		"nextTriggerDate": "22 Jan 2017",
+		"lastTriggerDate": "22 Jan 2016",
+		"recurrenceStartDate":"22 Jan 2016",
+		"recurrence": "YEARLY"			
+}
+			</code>
+        </div>
+</div>
+
+<a id="smscampaigns_update" name="smscampaigns_update" class="old-syle-anchor">&nbsp;</a>
+    <div class="method-section">
+        <div class="method-description">
+            <h4>Update a Campaign</h4>
+        </div>
+        <div class="method-example">
+            <code class="method-declaration">PUT https://Domain Name/api/v1/smscampaigns/{campaignId}</code>
+			<code class="method-request">POST smscampaigns/1
+Content-Type: application/json
+Request Body:
+{
+  "message": "Hello your savings account {savingsAccountNo} debited with {withdrawAmount}"
+  
+}
+			</code>
+			<code class="method-response">
+{
+  "resourceId": 1,
+  "changes": {
+    "message": "Hello your savings account {savingsAccountNo} debited with {withdrawAmount}"
+  }
+}
+			</code>
+        </div>
+</div>
+
+<a id="smscampaigns_delete" name="smscampaigns_delete" class="old-syle-anchor">&nbsp;</a>
+            <div class="method-section">
+                <div class="method-description">
+                    <h4>Delete a SMS Campaign</h4>
+                    <p>
+                        <b>Note:</b> Only closed SMS Campaigns can be
+						deleted
+                    </p>
+                </div>
+                <div class="method-example">
+                    <code class="method-declaration">
+DELETE https://DomainName/api/v1/smscampaigns/{campaignId}
+                    </code>
+                    <code class="method-request">
+DELETE smscampaigns/1
+Content-Type: application/json
+No Request Body:
+                    </code>
+                    <code class="method-response">
+{
+    "resourceId": 1,
+    "changes": {}
+}
+        </code>
+    </div>
+</div>
+
+<a id="smscampaigns_activate" name="smscampaigns_activate" class="old-syle-anchor">&nbsp;</a>
+	<div class="method-section">
+	    <div class="method-description">
+	        <h2>Activates SMS Campaign</h2>
+	        
+	    </div>
+	    <div class="method-example">
+	        <code class="method-declaration">POST https://Domain Name/api/v1/smscampaigns/{campaignId}?command=activate</code>
+	        <code class="method-request">POST smscampaigns/1?command=activate
+Content-Type: application/json
+Request Body:
+{
+"activationDate":"01 May 2016",
+"locale":"en",
+"dateFormat":"dd MMMM yyyy"
+}
+</code>
+<code class="method-response">
+{
+
+  "resourceId": 1,
+  "changes": {
+    "status": {
+      "id": 300,
+      "code": "smsCampaignStatus.active",
+      "value": "Activated",
+    },
+    "locale": "en",
+    "dateFormat": "dd MMMM yyyy",
+    "activationDate": "01 May 2016"
+  }
+}
+	        </code>
+	    </div>
+</div>
+
+<a id="smscampaigns_close" name="smscampaigns_close" class="old-syle-anchor">&nbsp;</a>
+	<div class="method-section">
+	    <div class="method-description">
+	        <h2>Deactivates SMS Campaign</h2>
+	        
+	    </div>
+	    <div class="method-example">
+	        <code class="method-declaration">POST https://Domain Name/api/v1/smscampaigns/{campaignId}?command=close</code>
+	        <code class="method-request">POST smscampaigns/1?command=close
+Content-Type: application/json
+Request Body:
+{
+"closureDate":"01 May 2016",
+"locale":"en",
+"dateFormat":"dd MMMM yyyy"
+}
+</code>
+<code class="method-response">
+{
+  "resourceId": 1,
+  "changes": {
+    "status": {
+      "id": 600,
+      "code": "smsCampaignStatus.closed",
+      "value": "Activated",
+    },
+    "locale": "en",
+    "dateFormat": "dd MMMM yyyy",
+    "closureDate": "01 May 2016"
+  }
+}
+	        </code>
+	    </div>
+</div>
+
+<a id="smscampaigns_reactivate" name="smscampaigns_reactivate" class="old-syle-anchor">&nbsp;</a>
+	<div class="method-section">
+	    <div class="method-description">
+	        <h2>Reactivates SMS Campaign</h2>
+	        
+	    </div>
+	    <div class="method-example">
+	        <code class="method-declaration">POST https://Domain Name/api/v1/smscampaigns/{campaignId}?command=reactivate</code>
+	        <code class="method-request">POST smscampaigns/1?command=reactivate
+Content-Type: application/json
+Request Body:
+{
+"activationDate":"01 May 2016",
+"locale":"en",
+"dateFormat":"dd MMMM yyyy"
+}
+</code>
+<code class="method-response">
+{
+
+  "resourceId": 1,
+  "changes": {
+    "status": {
+      "id": 300,
+      "code": "smsCampaignStatus.active",
+      "value": "Activated",
+    },
+    "locale": "en",
+    "dateFormat": "dd MMMM yyyy",
+    "activationDate": "01 May 2016"
+  }
+}
+	        </code>
+	    </div>
+</div>
+
+<a id="shareproducts_create" name="shareproducts_create" class="old-syle-anchor">&nbsp;</a>
     <div class="method-section">
         <div class="method-description">
             <h4>Create a Share Product</h4>

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/911cab85/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java b/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java
index fb497c0..ed92a38 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java
@@ -2803,4 +2803,51 @@ public class CommandWrapperBuilder {
         this.href = "/reportmailingjobs/" + entityId;
         return this;
     }
+    
+    public CommandWrapperBuilder createSmsCampaign() {
+        this.actionName = "CREATE";
+        this.entityName = "SMSCAMPAIGN";
+        this.entityId = null;
+        this.href = "/smscampaign";
+        return this;
+    }
+    
+    public CommandWrapperBuilder updateSmsCampaign(final Long resourceId) {
+        this.actionName = "UPDATE";
+        this.entityName = "SMSCAMPAIGN";
+        this.entityId = resourceId;
+        this.href = "/smscampaign/"+resourceId;
+        return this;
+    }
+    
+    public CommandWrapperBuilder activateSmsCampaign(final Long resourceId) {
+        this.actionName = "ACTIVATE";
+        this.entityName = "SMSCAMPAIGN";
+        this.entityId = resourceId;
+        this.href = "/smscampaign/"+resourceId + "?command=activate";
+        return this;
+    }
+
+    public CommandWrapperBuilder closeSmsCampaign(final Long resourceId) {
+        this.actionName = "CLOSE";
+        this.entityName = "SMSCAMPAIGN";
+        this.entityId = resourceId;
+        this.href = "/smscampaign/"+resourceId + "?command=close";
+        return this;
+    }
+    public CommandWrapperBuilder reactivateSmsCampaign(final Long resourceId) {
+        this.actionName = "REACTIVATE";
+        this.entityName = "SMSCAMPAIGN";
+        this.entityId = resourceId;
+        this.href = "/smscampaign/"+resourceId + "?command=reactivate";
+        return this;
+    }
+    
+    public CommandWrapperBuilder deleteSmsCampaign(final Long resourceId) {
+        this.actionName = "DELETE";
+        this.entityName = "SMSCAMPAIGN";
+        this.entityId = resourceId;
+        this.href = "/smscampaign/"+resourceId;
+        return this;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/911cab85/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/constants/CampaignType.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/constants/CampaignType.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/constants/CampaignType.java
new file mode 100644
index 0000000..b6a0aaf
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/constants/CampaignType.java
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.campaigns.constants;
+
+import org.apache.fineract.infrastructure.core.data.EnumOptionData;
+
+public enum CampaignType {
+    INVALID(0, "campaignType.invalid"), SMS(1, "campaignType.sms");
+
+    private Integer value;
+    private String code;
+
+    private CampaignType(Integer value, String code) {
+        this.value = value;
+        this.code = code;
+    }
+
+    public Integer getValue() {
+        return value;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public static CampaignType fromInt(final Integer typeValue) {
+        CampaignType type = null;
+        switch (typeValue) {
+            case 0:
+                type = INVALID;
+            break;
+            case 1:
+                type = SMS;
+            break;
+        }
+        return type;
+    }
+    
+    public static EnumOptionData campaignType(final Integer campaignTypeId) {
+        return campaignType(CampaignType.fromInt(campaignTypeId));
+    }
+
+    public static EnumOptionData campaignType(final CampaignType campaignType) {
+        EnumOptionData optionData = new EnumOptionData(CampaignType.INVALID.getValue().longValue(), CampaignType.INVALID.getCode(),
+                "Invalid");
+        switch (campaignType) {
+            case INVALID:
+                optionData = new EnumOptionData(CampaignType.INVALID.getValue().longValue(), CampaignType.INVALID.getCode(), "Invalid");
+            break;
+            case SMS:
+                optionData = new EnumOptionData(CampaignType.SMS.getValue().longValue(), CampaignType.SMS.getCode(), "SMS");
+            break;
+        }
+        return optionData;
+    }
+
+    public boolean isSms() {
+        return this.value.equals(CampaignType.SMS.getValue());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/911cab85/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/helper/SmsConfigUtils.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/helper/SmsConfigUtils.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/helper/SmsConfigUtils.java
new file mode 100644
index 0000000..a7fc942
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/helper/SmsConfigUtils.java
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.campaigns.helper;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ws.rs.core.UriBuilder;
+
+import org.apache.fineract.infrastructure.campaigns.sms.constants.SmsCampaignConstants;
+import org.apache.fineract.infrastructure.campaigns.sms.data.MessageGatewayConfigurationData;
+import org.apache.fineract.infrastructure.configuration.service.ExternalServicesPropertiesReadPlatformService;
+import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
+import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Component;
+
+@Component
+public class SmsConfigUtils {
+
+	@Autowired
+	  private ExternalServicesPropertiesReadPlatformService propertiesReadPlatformService;
+	
+	//This method will return uri and HttpEntry objects with keys as uri and entity
+    public Map<String, Object> getMessageGateWayRequestURI(final String apiEndPoint, String apiQueueResourceDatas) {
+        Map<String, Object> httpRequestdetails = new HashMap<>();
+        MessageGatewayConfigurationData messageGatewayConfigurationData = this.propertiesReadPlatformService.getSMSGateway();
+        final FineractPlatformTenant tenant = ThreadLocalContextUtil.getTenant();
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        headers.add(SmsCampaignConstants.FINERACT_PLATFORM_TENANT_ID, tenant.getTenantIdentifier());
+        headers.add(SmsCampaignConstants.FINERACT_TENANT_APP_KEY, messageGatewayConfigurationData.getTenantAppKey());
+        StringBuilder pathBuilder = new StringBuilder();
+        String endPoint = (messageGatewayConfigurationData.getEndPoint() == null || messageGatewayConfigurationData.getEndPoint().equals(
+                "/")) ? "" : messageGatewayConfigurationData.getEndPoint();
+        pathBuilder = (messageGatewayConfigurationData.getEndPoint() == null || messageGatewayConfigurationData.getEndPoint().equals("/")) ? pathBuilder
+                .append("{apiEndPoint}") : pathBuilder.append("{endPoint}/{apiEndPoint}");
+        // pathBuilder.append("{endPoint}/{apiEndPoint}") ;
+        UriBuilder builder = UriBuilder.fromPath(pathBuilder.toString()).host(messageGatewayConfigurationData.getHostName()).scheme("http")
+                .port(messageGatewayConfigurationData.getPortNumber());
+        URI uri = (messageGatewayConfigurationData.getEndPoint() == null || messageGatewayConfigurationData.getEndPoint().equals("/")) ? builder
+                .build(apiEndPoint) : builder.build(endPoint, apiEndPoint);
+        HttpEntity<?> entity = null;
+        if (apiQueueResourceDatas != null) {
+            entity = new HttpEntity<>(apiQueueResourceDatas, headers);
+        } else {
+            entity = new HttpEntity<>(headers);
+        }
+
+        httpRequestdetails.put("uri", uri);
+        httpRequestdetails.put("entity", entity);
+
+        return httpRequestdetails;
+    }
+	
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/911cab85/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/api/SmsCampaignApiResource.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/api/SmsCampaignApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/api/SmsCampaignApiResource.java
new file mode 100644
index 0000000..5c7dd7b
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/api/SmsCampaignApiResource.java
@@ -0,0 +1,195 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.campaigns.sms.api;
+
+import java.util.Collection;
+import java.util.HashSet;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
+import org.apache.fineract.infrastructure.campaigns.constants.CampaignType;
+import org.apache.fineract.infrastructure.campaigns.sms.constants.SmsCampaignConstants;
+import org.apache.fineract.infrastructure.campaigns.sms.data.CampaignPreviewData;
+import org.apache.fineract.infrastructure.campaigns.sms.data.SmsCampaignData;
+import org.apache.fineract.infrastructure.campaigns.sms.service.SmsCampaignReadPlatformService;
+import org.apache.fineract.infrastructure.campaigns.sms.service.SmsCampaignWritePlatformService;
+import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
+import org.apache.fineract.infrastructure.core.api.JsonQuery;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
+import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+
+import com.google.gson.JsonElement;
+
+@Path("/smscampaigns")
+@Component
+@Scope("singleton")
+public class SmsCampaignApiResource {
+
+    private final PlatformSecurityContext platformSecurityContext;
+    private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
+    private final DefaultToApiJsonSerializer<SmsCampaignData> toApiJsonSerializer;
+    private final SmsCampaignReadPlatformService smsCampaignReadPlatformService;
+    private final ApiRequestParameterHelper apiRequestParameterHelper;
+    private final FromJsonHelper fromJsonHelper;
+    private final DefaultToApiJsonSerializer<CampaignPreviewData> previewCampaignMessageDefaultToApiJsonSerializer;
+    private final SmsCampaignWritePlatformService smsCampaignWritePlatformService;
+
+    private final String resourceNameForPermissions = "SMS_CAMPAIGN";
+    private final PlatformSecurityContext context;
+
+    @Autowired
+    public SmsCampaignApiResource(final PlatformSecurityContext platformSecurityContext,
+            final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
+            final DefaultToApiJsonSerializer<SmsCampaignData> toApiJsonSerializer,
+            final SmsCampaignReadPlatformService smsCampaignReadPlatformService, final ApiRequestParameterHelper apiRequestParameterHelper,
+            final FromJsonHelper fromJsonHelper,
+            final DefaultToApiJsonSerializer<CampaignPreviewData> previewCampaignMessageDefaultToApiJsonSerializer,
+            final PlatformSecurityContext context, final SmsCampaignWritePlatformService smsCampaignWritePlatformService) {
+        this.platformSecurityContext = platformSecurityContext;
+        this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
+        this.toApiJsonSerializer = toApiJsonSerializer;
+        this.smsCampaignReadPlatformService = smsCampaignReadPlatformService;
+        this.apiRequestParameterHelper = apiRequestParameterHelper;
+        this.fromJsonHelper = fromJsonHelper;
+        this.previewCampaignMessageDefaultToApiJsonSerializer = previewCampaignMessageDefaultToApiJsonSerializer;
+        this.context = context;
+        this.smsCampaignWritePlatformService = smsCampaignWritePlatformService;
+    }
+
+    @GET
+    @Path("template")
+    public String template(@Context final UriInfo uriInfo) {
+        this.platformSecurityContext.authenticatedUser().validateHasReadPermission(SmsCampaignConstants.RESOURCE_NAME);
+        final SmsCampaignData smsCampaignData = this.smsCampaignReadPlatformService.retrieveTemplate(CampaignType.SMS.name());
+        final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+        return this.toApiJsonSerializer.serialize(settings, smsCampaignData);
+    }
+
+    @POST
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String createCampaign(final String apiRequestBodyAsJson) {
+        this.platformSecurityContext.authenticatedUser();
+        final CommandWrapper commandRequest = new CommandWrapperBuilder().createSmsCampaign().withJson(apiRequestBodyAsJson).build();
+        final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        return this.toApiJsonSerializer.serialize(result);
+    }
+
+    @GET
+    @Path("{resourceId}")
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String retrieveCampaign(@PathParam("resourceId") final Long resourceId, @Context final UriInfo uriInfo) {
+        this.platformSecurityContext.authenticatedUser().validateHasReadPermission(SmsCampaignConstants.RESOURCE_NAME);
+        SmsCampaignData smsCampaignData = this.smsCampaignReadPlatformService.retrieveOne(resourceId);
+        final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+        return this.toApiJsonSerializer.serialize(settings, smsCampaignData);
+
+    }
+
+    @GET
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String retrieveAllCampaigns(@Context final UriInfo uriInfo) {
+        this.platformSecurityContext.authenticatedUser().validateHasReadPermission(SmsCampaignConstants.RESOURCE_NAME);
+        Collection<SmsCampaignData> smsCampaignDataCollection = this.smsCampaignReadPlatformService.retrieveAll();
+        final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+        return this.toApiJsonSerializer.serialize(settings, smsCampaignDataCollection);
+    }
+
+    @PUT
+    @Path("{campaignId}")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String updateCampaign(@PathParam("campaignId") final Long campaignId, final String apiRequestBodyAsJson) {
+        final CommandWrapper commandRequest = new CommandWrapperBuilder().updateSmsCampaign(campaignId).withJson(apiRequestBodyAsJson)
+                .build();
+        final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        return this.toApiJsonSerializer.serialize(result);
+    }
+
+    @POST
+    @Path("{campaignId}")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String handleCommands(@PathParam("campaignId") final Long campaignId, @QueryParam("command") final String commandParam,
+            final String apiRequestBodyAsJson) {
+        final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
+        CommandProcessingResult result = null;
+        CommandWrapper commandRequest = null;
+        if (is(commandParam, "activate")) {
+            commandRequest = builder.activateSmsCampaign(campaignId).build();
+            result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        } else if (is(commandParam, "close")) {
+            commandRequest = builder.closeSmsCampaign(campaignId).build();
+            result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        } else if (is(commandParam, "reactivate")) {
+            commandRequest = builder.reactivateSmsCampaign(campaignId).build();
+            result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        }
+        return this.toApiJsonSerializer.serialize(result);
+    }
+
+    @POST
+    @Path("preview")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String preview(final String apiRequestBodyAsJson, @Context final UriInfo uriInfo) {
+        this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
+
+        CampaignPreviewData campaignMessage = null;
+        final JsonElement parsedQuery = this.fromJsonHelper.parse(apiRequestBodyAsJson);
+        final JsonQuery query = JsonQuery.from(apiRequestBodyAsJson, parsedQuery, this.fromJsonHelper);
+        campaignMessage = this.smsCampaignWritePlatformService.previewMessage(query);
+        final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+        return this.previewCampaignMessageDefaultToApiJsonSerializer.serialize(settings, campaignMessage, new HashSet<String>());
+
+    }
+
+    @DELETE
+    @Path("{campaignId}")
+    public String delete(@PathParam("campaignId") final Long campaignId) {
+        final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteSmsCampaign(campaignId).build();
+        final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        return this.toApiJsonSerializer.serialize(result);
+    }
+
+    private boolean is(final String commandParam, final String commandValue) {
+        return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/911cab85/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/constants/SmsCampaignConstants.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/constants/SmsCampaignConstants.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/constants/SmsCampaignConstants.java
new file mode 100644
index 0000000..104f4c7
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/constants/SmsCampaignConstants.java
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.campaigns.sms.constants;
+
+public interface SmsCampaignConstants {
+
+    String SMS_CAMPAIGN_NAME = "sms";
+
+    String RESOURCE_NAME = "SMSCAMPAIGN";
+
+    String SMS_BRIDGE = "sms_bridge";
+
+    String SMS = "sms";
+
+    String FINERACT_PLATFORM_TENANT_ID = "Fineract-Platform-TenantId";
+
+    String FINERACT_TENANT_APP_KEY = "Fineract-Tenant-App-Key";
+    
+    //Supported Triggered Campaigns
+    
+    String LOAN_REJECT = "Loan Rejected" ;
+    
+    String LOAN_APPROVED = "Loan Approved" ;
+    
+    String LOAN_REPAYMENT = "Loan Repayment" ;
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/911cab85/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/constants/SmsCampaignEnumerations.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/constants/SmsCampaignEnumerations.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/constants/SmsCampaignEnumerations.java
new file mode 100644
index 0000000..16ae3cd
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/constants/SmsCampaignEnumerations.java
@@ -0,0 +1,92 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.campaigns.sms.constants;
+
+import java.time.Month;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.fineract.infrastructure.campaigns.constants.CampaignType;
+import org.apache.fineract.infrastructure.core.data.EnumOptionData;
+import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
+
+
+public class SmsCampaignEnumerations {
+
+    
+    public static EnumOptionData smscampaignTriggerType(final SmsCampaignTriggerType type) {
+        EnumOptionData optionData = new EnumOptionData(SmsCampaignTriggerType.INVALID.getValue().longValue(),
+                SmsCampaignTriggerType.INVALID.getCode(), "Invalid");
+        switch (type) {
+            case INVALID:
+            break;
+            case DIRECT:
+                optionData = new EnumOptionData(SmsCampaignTriggerType.DIRECT.getValue().longValue(),
+                        SmsCampaignTriggerType.DIRECT.getCode(), "Direct");
+            break;
+            case SCHEDULE:
+                optionData = new EnumOptionData(SmsCampaignTriggerType.SCHEDULE.getValue().longValue(),
+                        SmsCampaignTriggerType.SCHEDULE.getCode(), "Scheduled");
+            break;
+            case TRIGGERED:
+                optionData = new EnumOptionData(SmsCampaignTriggerType.TRIGGERED.getValue().longValue(),
+                        SmsCampaignTriggerType.TRIGGERED.getCode(), "Triggered");
+            break;
+        }
+        return optionData;
+    }
+
+    public static EnumOptionData smscampaignType(final CampaignType type) {
+        EnumOptionData optionData = new EnumOptionData(CampaignType.INVALID.getValue().longValue(), CampaignType.INVALID.getCode(),
+                "Invalid");
+        switch (type) {
+            case INVALID:
+            break;
+            case SMS:
+                optionData = new EnumOptionData(CampaignType.SMS.getValue().longValue(), CampaignType.SMS.getCode(), "SMS");
+            break;
+        }
+        return optionData;
+    }
+
+    public static EnumOptionData calendarMonthType(final Month entityType) {
+        final EnumOptionData optionData = new EnumOptionData(new Long(entityType.getValue()), entityType.name(), entityType.name());
+        return optionData;
+    }
+
+    public static List<EnumOptionData> calendarMonthType() {
+        final List<EnumOptionData> optionDatas = new ArrayList<>();
+        for (final Month monthType : Month.values()) {
+            if (Month.DECEMBER.compareTo(monthType) != 0) {
+                optionDatas.add(calendarMonthType(monthType));
+            }
+        }
+        return optionDatas;
+    }
+
+    public static List<EnumOptionData> calendarPeriodFrequencyTypes(final PeriodFrequencyType[] periodFrequencyTypes) {
+        final List<EnumOptionData> optionDatas = new ArrayList<>();
+        for (final PeriodFrequencyType periodFrequencyType : periodFrequencyTypes) {
+            final EnumOptionData optionData = new EnumOptionData(periodFrequencyType.getValue().longValue(), periodFrequencyType.getCode(),
+                    periodFrequencyType.toString());
+            optionDatas.add(optionData);
+        }
+        return optionDatas;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/911cab85/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/constants/SmsCampaignStatus.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/constants/SmsCampaignStatus.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/constants/SmsCampaignStatus.java
new file mode 100644
index 0000000..43d3c27
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/constants/SmsCampaignStatus.java
@@ -0,0 +1,72 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.campaigns.sms.constants;
+
+public enum SmsCampaignStatus {
+
+    INVALID(-1, "smsCampaignStatus.invalid"), //
+    PENDING(100, "smsCampaignStatus.pending"), //
+    ACTIVE(300, "smsCampaignStatus.active"), //
+    CLOSED(600, "smsCampaignStatus.closed");
+
+    private final Integer value;
+    private final String code;
+
+    private SmsCampaignStatus(Integer value, String code) {
+        this.value = value;
+        this.code = code;
+    }
+
+    public static SmsCampaignStatus fromInt(final Integer statusValue) {
+
+        SmsCampaignStatus enumeration = SmsCampaignStatus.INVALID;
+        switch (statusValue) {
+            case 100:
+                enumeration = SmsCampaignStatus.PENDING;
+            break;
+            case 300:
+                enumeration = SmsCampaignStatus.ACTIVE;
+            break;
+            case 600:
+                enumeration = SmsCampaignStatus.CLOSED;
+            break;
+        }
+        return enumeration;
+    }
+
+    public Integer getValue() {
+        return value;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public boolean isActive() {
+        return this.value.equals(SmsCampaignStatus.ACTIVE.getValue());
+    }
+
+    public boolean isPending() {
+        return this.value.equals(SmsCampaignStatus.PENDING.getValue());
+    }
+
+    public boolean isClosed() {
+        return this.value.equals(SmsCampaignStatus.CLOSED.getValue());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/911cab85/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/constants/SmsCampaignTriggerType.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/constants/SmsCampaignTriggerType.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/constants/SmsCampaignTriggerType.java
new file mode 100644
index 0000000..a133e6f
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/constants/SmsCampaignTriggerType.java
@@ -0,0 +1,98 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.campaigns.sms.constants;
+
+import org.apache.fineract.infrastructure.core.data.EnumOptionData;
+
+public enum SmsCampaignTriggerType {
+    INVALID(-1, "triggerType.invalid"), DIRECT(1, "triggerType.direct"), SCHEDULE(2, "triggerType.schedule"), TRIGGERED(3,
+            "triggerType.triggered");
+
+    private Integer value;
+    private String code;
+
+    private SmsCampaignTriggerType(Integer value, String code) {
+        this.value = value;
+        this.code = code;
+    }
+
+    public Integer getValue() {
+        return value;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public static SmsCampaignTriggerType fromInt(final Integer typeValue) {
+        SmsCampaignTriggerType type = null;
+        switch (typeValue) {
+            case 1:
+                type = DIRECT;
+            break;
+            case 2:
+                type = SCHEDULE;
+            break;
+            case 3:
+                type = TRIGGERED;
+            break;
+        }
+        return type;
+    }
+
+    public static EnumOptionData triggerType(final Integer triggerTypeId) {
+        return triggerType(SmsCampaignTriggerType.fromInt(triggerTypeId));
+    }
+
+    public static EnumOptionData triggerType(final SmsCampaignTriggerType triggerType) {
+        EnumOptionData optionData = new EnumOptionData(SmsCampaignTriggerType.INVALID.getValue().longValue(),
+                SmsCampaignTriggerType.INVALID.getCode(), "Invalid");
+        switch (triggerType) {
+            case INVALID:
+                optionData = new EnumOptionData(SmsCampaignTriggerType.INVALID.getValue().longValue(),
+                        SmsCampaignTriggerType.INVALID.getCode(), "Invalid");
+            break;
+            case DIRECT:
+                optionData = new EnumOptionData(SmsCampaignTriggerType.DIRECT.getValue().longValue(),
+                        SmsCampaignTriggerType.DIRECT.getCode(), "Direct");
+            break;
+            case SCHEDULE:
+                optionData = new EnumOptionData(SmsCampaignTriggerType.SCHEDULE.getValue().longValue(),
+                        SmsCampaignTriggerType.SCHEDULE.getCode(), "Schedule");
+            break;
+            case TRIGGERED:
+                optionData = new EnumOptionData(SmsCampaignTriggerType.TRIGGERED.getValue().longValue(),
+                        SmsCampaignTriggerType.TRIGGERED.getCode(), "Triggered");
+            break;
+        }
+        return optionData;
+    }
+
+    public boolean isDirect() {
+        return this.value.equals(SmsCampaignTriggerType.DIRECT.getValue());
+    }
+
+    public boolean isSchedule() {
+        return this.value.equals(SmsCampaignTriggerType.SCHEDULE.getValue());
+    }
+
+    public boolean isTriggered() {
+        return this.value.equals(SmsCampaignTriggerType.TRIGGERED.getValue());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/911cab85/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/data/CampaignPreviewData.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/data/CampaignPreviewData.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/data/CampaignPreviewData.java
new file mode 100644
index 0000000..73ca41f
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/data/CampaignPreviewData.java
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.campaigns.sms.data;
+
+public class CampaignPreviewData {
+
+    private final String campaignMessage;
+
+    private final Integer totalNumberOfMessages;
+
+    public CampaignPreviewData(String campaignMessage, Integer totalNumberOfMessages) {
+        this.campaignMessage = campaignMessage;
+        this.totalNumberOfMessages = totalNumberOfMessages;
+    }
+
+    public String getCampaignMessage() {
+        return campaignMessage;
+    }
+
+    public Integer getTotalNumberOfMessages() {
+        return totalNumberOfMessages;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/911cab85/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/data/CampaignTriggerWithSubTypes.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/data/CampaignTriggerWithSubTypes.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/data/CampaignTriggerWithSubTypes.java
new file mode 100644
index 0000000..c23771f
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/data/CampaignTriggerWithSubTypes.java
@@ -0,0 +1,298 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.campaigns.sms.data;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.fineract.infrastructure.core.data.EnumOptionData;
+
+public final class CampaignTriggerWithSubTypes {
+
+    public enum ActualCampaignTriggerType {
+        INVALID(0, "campaignTriggerType.invalid"), //
+        LOAN(1, "campaignTriggerType.loan"), //
+        SAVING(2, "campaignTriggerType.saving"), //
+        CLIENT(3, "campaignTriggerType.client");
+
+        private Integer value;
+        private String code;
+
+        private ActualCampaignTriggerType(Integer value, String code) {
+            this.value = value;
+            this.code = code;
+        }
+
+        public static ActualCampaignTriggerType fromInt(final Integer typeValue) {
+            ActualCampaignTriggerType type = ActualCampaignTriggerType.INVALID;
+            switch (typeValue) {
+                case 1:
+                    type = LOAN;
+                break;
+                case 2:
+                    type = SAVING;
+                break;
+                case 3:
+                    type = CLIENT;
+                break;
+            }
+            return type;
+        }
+
+        public Integer getValue() {
+            return this.value;
+        }
+
+        public String getCode() {
+            return this.code;
+        }
+
+        public static EnumOptionData toEnumOptionData(final ActualCampaignTriggerType triggerType) {
+            final EnumOptionData optionData = new EnumOptionData(new Long(triggerType.getValue()), triggerType.getCode(), triggerType.name());
+            return optionData;
+        }
+
+        public static EnumOptionData toEnumOptionData(final Integer triggerTypeValue) {
+            ActualCampaignTriggerType actualCampaignTriggerType = ActualCampaignTriggerType.fromInt(triggerTypeValue);
+            final EnumOptionData optionData = new EnumOptionData(new Long(actualCampaignTriggerType.getValue()),
+                    actualCampaignTriggerType.getCode(), actualCampaignTriggerType.name());
+            return optionData;
+        }
+
+        public boolean isInvalid() {
+            return this.value.equals(ActualCampaignTriggerType.INVALID.getValue());
+        }
+    }
+
+    public enum CampaignTriggerSubType {
+        INVALID(0, ActualCampaignTriggerType.INVALID, "campaignTriggerSubType.invalid"), //
+
+        DISBURSE(101, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.disburse"), //
+        REPAYMENT(102, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.repayment"), //
+        UNDO_DISBURSAL(103, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.undodisbursal"), //
+        WRITE_OFF(104, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.writeoff"), //
+        ADJUST(105, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.adjust"), //
+        UNDO_WRITE_OFF(106, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.undowriteoff"), //
+        FORECLOSURE(107, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.foreclosure"), //
+        APPROVED(108, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.approved"), //
+        WAIVE_INTEREST(109, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.waive.interest"), //
+        CLOSE(110, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.close"), //
+        CLOSE_AS_RESCHEDULE(111, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.close.as.rescheduled"), //
+        ADD_CHARGE(112, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.add.charge"), //
+        UPDATE_CHARGE(113, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.update.charge"), //
+        WAIVE_CHARGE(114, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.waive.charge"), //
+        DELETE_CHARGE(115, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.delete.charge"), //
+        CHARGE_PAYMENT(116, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.charge.payment"), //
+        INITIATE_TRANSFER(117, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.initiate.transfer"), //
+        ACCEPT_TRANSFER(118, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.accept.transfer"), //
+        WITHDRAW_TRANSFER(119, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.withdraw.transfer"), //
+        REJECT_TRANSFER(120, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.reject.transfer"), //
+        REASSIGN_OFFICER(121, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.reassign.officer"), //
+        REMOVE_OFFICER(122, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.reassign.officer"), //
+        APPLY_OVERDUE_CHARGE(123, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.reassign.officer"), //
+        INTEREST_RECALCULATION(124, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.reassign.officer"), //
+        REFUND(125, ActualCampaignTriggerType.LOAN, "campaignTriggerSubType.reassign.officer"), //
+
+        SAVINGS_DEPOSIT(201, ActualCampaignTriggerType.SAVING, "campaignTriggerSubType.deposit"), //
+        SAVINGS_WITHDRAWAL(202, ActualCampaignTriggerType.SAVING, "campaignTriggerSubType.withdrawal"), //
+        SAVINGS_ACTIVATE(203, ActualCampaignTriggerType.SAVING, "campaignTriggerSubType.savings.activate"), //
+        SAVINGS_ADJUST_TRANSACTION(204, ActualCampaignTriggerType.SAVING, "campaignTriggerSubType.savings.adjust"), //
+        SAVINGS_APPLY_ANNUAL_FEE(205, ActualCampaignTriggerType.SAVING, "campaignTriggerSubType.savings.apply.annual.fee"), //
+        SAVINGS_CALCULATE_INTEREST(206, ActualCampaignTriggerType.SAVING, "campaignTriggerSubType.savings.calclulate.interest"), //
+        SAVINGS_CLOSE(207, ActualCampaignTriggerType.SAVING, "campaignTriggerSubType.savings.close"), //
+        SAVINGS_POST_INTEREST(208, ActualCampaignTriggerType.SAVING, "campaignTriggerSubType.savings.post"), //
+        SAVINGS_REJECT(209, ActualCampaignTriggerType.SAVING, "campaignTriggerSubType.savings.reject"), //
+        SAVINGS_UNDO(210, ActualCampaignTriggerType.SAVING, "campaignTriggerSubType.savings.undo"), //
+        SAVINGS_ADD_CHARGE(211, ActualCampaignTriggerType.SAVING, "campaignTriggerSubType.savings.add.charge"), //
+        SAVINGS_WAIVE_CHARGE(212, ActualCampaignTriggerType.SAVING, "campaignTriggerSubType.savings.waive.charge"), //
+        SAVINGS_PAY_CHARGE(213, ActualCampaignTriggerType.SAVING, "campaignTriggerSubType.savings.pay.charge"), //
+
+        CLIENTS_ACTIVATE(301, ActualCampaignTriggerType.CLIENT, "campaignTriggerSubType.activate"), //
+        CLIENTS_CLOSE(302, ActualCampaignTriggerType.CLIENT, "campaignTriggerSubType.close"), //
+        CLIENTS_ACCEPT_TRANSFER(303, ActualCampaignTriggerType.CLIENT, "campaignTriggerSubType.accept.transfer"), //
+        CLIENTS_ASSIGN_STAFF(304, ActualCampaignTriggerType.CLIENT, "campaignTriggerSubType.assign.staff"), //
+        CLIENTS_CREATE(305, ActualCampaignTriggerType.CLIENT, "campaignTriggerSubType.create"), //
+        CLIENTS_DELETE(306, ActualCampaignTriggerType.CLIENT, "campaignTriggerSubType.delete"), //
+        CLIENTS_PROPOSE_TRANSFER(307, ActualCampaignTriggerType.CLIENT, "campaignTriggerSubType.propose.transfer"), //
+        CLIENTS_REACTIVATE(308, ActualCampaignTriggerType.CLIENT, "campaignTriggerSubType.reactivate"), //
+        CLIENTS_REJECT(309, ActualCampaignTriggerType.CLIENT, "campaignTriggerSubType.reject"), //
+        CLIENTS_REJECT_TRANSFER(310, ActualCampaignTriggerType.CLIENT, "campaignTriggerSubType.reject.transfer"), //
+        CLIENTS_WITHDRAW(311, ActualCampaignTriggerType.CLIENT, "campaignTriggerSubType.withdraw"), //
+        CLIENTS_WITHDRAW_TRANSFER(312, ActualCampaignTriggerType.CLIENT, "campaignTriggerSubType.withdraw.transfer");
+
+        private Integer id;
+        private ActualCampaignTriggerType type;
+        private String code;
+
+        private CampaignTriggerSubType(Integer id, ActualCampaignTriggerType type, String code) {
+            this.id = id;
+            this.type = type;
+            this.code = code;
+        }
+
+        public static CampaignTriggerSubType fromInt(final Integer subTypeValue) {
+            CampaignTriggerSubType subType = CampaignTriggerSubType.INVALID;
+            switch (subTypeValue) {
+                case 101:
+                    subType = DISBURSE;
+                break;
+                case 102:
+                    subType = REPAYMENT;
+                break;
+                case 103:
+                    subType = ADJUST;
+                break;
+                case 104:
+                    subType = UNDO_DISBURSAL;
+                break;
+                case 105:
+                    subType = WRITE_OFF;
+                break;
+                case 106:
+                    subType = UNDO_WRITE_OFF;
+                break;
+
+                case 201:
+                    subType = SAVINGS_DEPOSIT;
+                break;
+                case 202:
+                    subType = SAVINGS_WITHDRAWAL;
+                break;
+                case 203:
+                    subType = SAVINGS_ACTIVATE;
+                break;
+                case 204:
+                    subType = SAVINGS_ADJUST_TRANSACTION;
+                break;
+                case 205:
+                    subType = SAVINGS_APPLY_ANNUAL_FEE;
+                break;
+                case 206:
+                    subType = SAVINGS_CALCULATE_INTEREST;
+                break;
+                case 207:
+                    subType = SAVINGS_CLOSE;
+                break;
+                case 208:
+                    subType = SAVINGS_POST_INTEREST;
+                break;
+                case 209:
+                    subType = SAVINGS_REJECT;
+                break;
+                case 210:
+                    subType = SAVINGS_UNDO;
+                break;
+                case 211:
+                    subType = SAVINGS_ADD_CHARGE;
+                break;
+                case 212:
+                    subType = SAVINGS_WAIVE_CHARGE;
+                break;
+                case 213:
+                    subType = SAVINGS_PAY_CHARGE;
+                break;
+
+                case 301:
+                    subType = CLIENTS_ACTIVATE;
+                break;
+                case 302:
+                    subType = CLIENTS_CLOSE;
+                break;
+                case 303:
+                    subType = CLIENTS_ACCEPT_TRANSFER;
+                break;
+                case 304:
+                    subType = CLIENTS_ASSIGN_STAFF;
+                break;
+                case 305:
+                    subType = CLIENTS_CREATE;
+                break;
+                case 306:
+                    subType = CLIENTS_DELETE;
+                break;
+                case 307:
+                    subType = CLIENTS_PROPOSE_TRANSFER;
+                break;
+                case 308:
+                    subType = CLIENTS_REACTIVATE;
+                break;
+                case 309:
+                    subType = CLIENTS_REJECT;
+                break;
+                case 310:
+                    subType = CLIENTS_REJECT_TRANSFER;
+                break;
+                case 311:
+                    subType = CLIENTS_WITHDRAW;
+                break;
+                case 312:
+                    subType = CLIENTS_WITHDRAW_TRANSFER;
+                break;
+            }
+            return subType;
+        }
+
+        public Integer getId() {
+            return this.id;
+        }
+
+        public ActualCampaignTriggerType getType() {
+            return this.type;
+        }
+
+        public String getCode() {
+            return this.code;
+        }
+
+        public static EnumOptionData toEnumOptionData(final Integer triggerSubType) {
+            CampaignTriggerSubType subTypeEnum = CampaignTriggerSubType.fromInt(triggerSubType);
+            final EnumOptionData optionData = new EnumOptionData(new Long(subTypeEnum.getId()), subTypeEnum.getCode(), subTypeEnum.name());
+            return optionData;
+        }
+    }
+
+    public static List<EnumOptionData> addTypeSubTypeMapping(ActualCampaignTriggerType type) {
+        List<EnumOptionData> subTypeList = new ArrayList<>();
+        EnumOptionData optionData = null;
+        for (CampaignTriggerSubType subType : CampaignTriggerSubType.values()) {
+            if (subType.getType().equals(type)) {
+                optionData = new EnumOptionData(subType.getId().longValue(), subType.getCode(), subType.name());
+                subTypeList.add(optionData);
+            }
+        }
+        return subTypeList;
+    }
+
+    public static Collection<TriggerTypeWithSubTypesData> getTriggerTypeAndSubTypes() {
+        final Collection<TriggerTypeWithSubTypesData> typesList = new ArrayList<>();
+        EnumOptionData actualTriggerType = null;
+        for (ActualCampaignTriggerType triggerType : ActualCampaignTriggerType.values()) {
+            if (triggerType.isInvalid()) {
+                continue;
+            }
+            List<EnumOptionData> subTypeList = addTypeSubTypeMapping(triggerType);
+            actualTriggerType = ActualCampaignTriggerType.toEnumOptionData(triggerType);
+            TriggerTypeWithSubTypesData triggerTypeWithSubTypesData = new TriggerTypeWithSubTypesData(actualTriggerType, subTypeList);
+            typesList.add(triggerTypeWithSubTypesData);
+        }
+        return typesList;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/911cab85/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/data/MessageGatewayConfigurationData.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/data/MessageGatewayConfigurationData.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/data/MessageGatewayConfigurationData.java
new file mode 100644
index 0000000..f2222ee
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/data/MessageGatewayConfigurationData.java
@@ -0,0 +1,81 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.campaigns.sms.data;
+
+public class MessageGatewayConfigurationData {
+
+    private final Long id;
+    private final String connectionName;
+    private final String hostName;
+    private final int portNumber;
+    private final String endPoint;
+    private final String userName;
+    private final String password;
+    private final boolean sslEnabled;
+    private final String tenantAppKey;
+
+    public MessageGatewayConfigurationData(final Long id, final String connectionName, final String hostName, final int portNumber,
+            final String endPoint, final String userName, final String password, final boolean sslEnabled, final String tenantAppKey) {
+        this.id = id;
+        this.connectionName = connectionName;
+        this.hostName = hostName;
+        this.portNumber = portNumber;
+        this.endPoint = endPoint;
+        this.userName = userName;
+        this.password = password;
+        this.sslEnabled = sslEnabled;
+        this.tenantAppKey = tenantAppKey;
+    }
+
+    public Long getId() {
+        return this.id;
+    }
+
+    public String getConnectionName() {
+        return this.connectionName;
+    }
+
+    public String getHostName() {
+        return this.hostName;
+    }
+
+    public int getPortNumber() {
+        return this.portNumber;
+    }
+
+    public String getEndPoint() {
+        return this.endPoint;
+    }
+
+    public String getUserName() {
+        return this.userName;
+    }
+
+    public String getPassword() {
+        return this.password;
+    }
+
+    public boolean isSslEnabled() {
+        return this.sslEnabled;
+    }
+
+    public String getTenantAppKey() {
+        return this.tenantAppKey;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/911cab85/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/data/SmsBusinessRulesData.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/data/SmsBusinessRulesData.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/data/SmsBusinessRulesData.java
new file mode 100644
index 0000000..adee094
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/data/SmsBusinessRulesData.java
@@ -0,0 +1,92 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.campaigns.sms.data;
+
+import java.util.Map;
+
+public class SmsBusinessRulesData {
+
+    private final Long reportId;
+
+    private final String reportName;
+
+    private final String reportType;
+
+    private final String reportSubType;
+
+    private final String reportDescription;
+
+    private final Map<String, Object> reportParamName;
+
+    public SmsBusinessRulesData(final Long reportId, final String reportName, final String reportType, final String reportSubType,
+            final Map<String, Object> reportParamName, final String reportDescription) {
+        this.reportId = reportId;
+        this.reportName = reportName;
+        this.reportType = reportType;
+        this.reportSubType = reportSubType;
+        this.reportParamName = reportParamName;
+        this.reportDescription = reportDescription;
+    }
+
+    public static SmsBusinessRulesData instance(final Long reportId, final String reportName, final String reportType,
+            final String reportSubType, final Map<String, Object> reportParamName, final String reportDescription) {
+        return new SmsBusinessRulesData(reportId, reportName, reportType, reportSubType, reportParamName, reportDescription);
+    }
+
+    public Map<String, Object> getReportParamName() {
+        return reportParamName;
+    }
+
+    public String getReportType() {
+        return reportType;
+    }
+
+    public String getReportSubType() {
+        return this.reportSubType;
+    }
+
+    public String getReportName() {
+        return reportName;
+    }
+
+    public Long getReportId() {
+        return reportId;
+    }
+
+    public String getReportDescription() {
+        return reportDescription;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        SmsBusinessRulesData that = (SmsBusinessRulesData) o;
+
+        if (reportId != null ? !reportId.equals(that.reportId) : that.reportId != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return reportId != null ? reportId.hashCode() : 0;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/911cab85/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/data/SmsCampaignData.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/data/SmsCampaignData.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/data/SmsCampaignData.java
new file mode 100644
index 0000000..8a6e6a3
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/data/SmsCampaignData.java
@@ -0,0 +1,206 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.campaigns.sms.data;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.fineract.infrastructure.core.data.EnumOptionData;
+import org.joda.time.DateTime;
+import org.joda.time.LocalDate;
+
+@SuppressWarnings("unused")
+public class SmsCampaignData {
+
+    private Long id;
+    private final String campaignName;
+    private final EnumOptionData campaignType;
+    private final Long runReportId;
+    private final String reportName;
+    private final String paramValue;
+    private final EnumOptionData campaignStatus;
+    private final EnumOptionData triggerType;
+    private final String campaignMessage;
+    private final DateTime nextTriggerDate;
+    private final LocalDate lastTriggerDate;
+    private final SmsCampaignTimeLine smsCampaignTimeLine;
+    private final DateTime recurrenceStartDate;
+    private final String recurrence;
+    private final Long providerId;
+
+    private final Collection<SmsProviderData> smsProviderOptions;
+
+    private final Collection<EnumOptionData> campaignTypeOptions;
+
+    private final Collection<EnumOptionData> triggerTypeOptions;
+
+    private final Collection<SmsBusinessRulesData> businessRulesOptions;
+
+    private final Collection<EnumOptionData> months;
+
+    private final Collection<EnumOptionData> weekDays;
+
+    private final Collection<EnumOptionData> frequencyTypeOptions;
+
+    private final Collection<EnumOptionData> periodFrequencyOptions;
+    
+    private SmsCampaignData(final Long id, final String campaignName, final EnumOptionData campaignType, final EnumOptionData triggerType,
+            final Long runReportId, 
+            final String reportName, final String paramValue, final EnumOptionData campaignStatus,
+            final String message, final DateTime nextTriggerDate, final LocalDate lastTriggerDate,
+            final SmsCampaignTimeLine smsCampaignTimeLine, final DateTime recurrenceStartDate, final String recurrence,
+            final Long providerId, final Collection<SmsBusinessRulesData> businessRulesOptions,
+            final Collection<SmsProviderData> smsProviderOptions, final Collection<EnumOptionData> campaignTypeOptions,
+            final Collection<EnumOptionData> triggerTypeOptions, final Collection<EnumOptionData> months, 
+            final Collection<EnumOptionData> weekDays, final Collection<EnumOptionData> frequencyTypeOptions, 
+            final Collection<EnumOptionData> periodFrequencyOptions) {
+        this.id = id;
+        this.campaignName = campaignName;
+        this.campaignType = campaignType;
+        this.triggerType = triggerType;
+        this.runReportId = runReportId;
+        this.reportName = reportName;
+        this.paramValue = paramValue;
+        this.campaignStatus = campaignStatus;
+        this.campaignMessage = message;
+        if (nextTriggerDate != null) {
+            this.nextTriggerDate = nextTriggerDate;
+        } else {
+            this.nextTriggerDate = null;
+        }
+        if (lastTriggerDate != null) {
+            this.lastTriggerDate = lastTriggerDate;
+        } else {
+            this.lastTriggerDate = null;
+        }
+        this.smsCampaignTimeLine = smsCampaignTimeLine;
+        this.recurrenceStartDate = recurrenceStartDate;
+        this.recurrence = recurrence;
+        this.providerId = providerId;
+        this.businessRulesOptions = businessRulesOptions;
+        this.smsProviderOptions = smsProviderOptions;
+        this.campaignTypeOptions = campaignTypeOptions;
+        this.triggerTypeOptions = triggerTypeOptions;
+        this.months = months;
+        this.weekDays = weekDays;
+        this.frequencyTypeOptions = frequencyTypeOptions;
+        this.periodFrequencyOptions = periodFrequencyOptions;
+    }
+
+    public static SmsCampaignData instance(final Long id, final String campaignName, final EnumOptionData campaignType,
+            final EnumOptionData triggerType, 
+            final Long runReportId, final String reportName, final String paramValue, final EnumOptionData campaignStatus,
+            final String message, final DateTime nextTriggerDate, final LocalDate lastTriggerDate,
+            final SmsCampaignTimeLine smsCampaignTimeLine, final DateTime recurrenceStartDate, final String recurrence,
+            final Long providerId) {
+        final Collection<SmsBusinessRulesData> businessRulesOptions = null;
+        final Collection<SmsProviderData> smsProviderOptions = null;
+        final Collection<EnumOptionData> campaignTypeOptions = null;
+        final Collection<EnumOptionData> triggerTypeOptions = null;
+        final Collection<EnumOptionData> months = null;
+        final Collection<EnumOptionData> weekDays = null;
+        final Collection<EnumOptionData> frequencyTypeOptions = null;
+        final Collection<EnumOptionData> periodFrequencyOptions = null;
+
+        return new SmsCampaignData(id, campaignName, campaignType, triggerType, runReportId,
+                reportName, paramValue, campaignStatus, message, nextTriggerDate, lastTriggerDate, smsCampaignTimeLine,
+                recurrenceStartDate, recurrence, providerId, businessRulesOptions, smsProviderOptions, campaignTypeOptions,
+                triggerTypeOptions, months, weekDays, frequencyTypeOptions, periodFrequencyOptions);
+    }
+
+    public static SmsCampaignData template(final Collection<SmsProviderData> smsProviderOptions,
+            final Collection<EnumOptionData> campaignTypeOptions, final Collection<SmsBusinessRulesData> businessRulesOptions,
+            final Collection<EnumOptionData> triggerTypeOptions, final Collection<EnumOptionData> months,
+            final Collection<EnumOptionData> weekDays, final Collection<EnumOptionData> frequencyTypeOptions,
+            final Collection<EnumOptionData> periodFrequencyOptions) {
+        final Long id = null;
+        final String campaignName = null;
+        final EnumOptionData campaignType = null;
+        final Long runReportId = null;
+        final String paramValue = null;
+        final EnumOptionData campaignStatus = null;
+        final String message = null;
+        final DateTime nextTriggerDate = null;
+        final LocalDate lastTriggerDate = null;
+        final SmsCampaignTimeLine smsCampaignTimeLine = null;
+        final DateTime recurrenceStartDate = null;
+        final String recurrence = null;
+        final EnumOptionData triggerType = null;
+        final String reportName = null;
+        final Long providerId = null;
+        return new SmsCampaignData(id, campaignName, campaignType, triggerType, runReportId,
+                reportName, paramValue, campaignStatus, message, nextTriggerDate, lastTriggerDate, smsCampaignTimeLine,
+                recurrenceStartDate, recurrence, providerId, businessRulesOptions, smsProviderOptions, campaignTypeOptions,
+                triggerTypeOptions, months, weekDays, frequencyTypeOptions, periodFrequencyOptions);
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getCampaignName() {
+        return this.campaignName;
+    }
+
+    public EnumOptionData getCampaignType() {
+        return this.campaignType;
+    }
+
+    public Long getRunReportId() {
+        return this.runReportId;
+    }
+
+    public String getParamValue() {
+        return this.paramValue;
+    }
+
+    public EnumOptionData getCampaignStatus() {
+        return this.campaignStatus;
+    }
+
+    public String getMessage() {
+        return this.campaignMessage;
+    }
+
+    public DateTime getNextTriggerDate() {
+        return this.nextTriggerDate;
+    }
+
+    public LocalDate getLastTriggerDate() {
+        return this.lastTriggerDate;
+    }
+
+    public String getRecurrence() {
+        return this.recurrence;
+    }
+
+    public DateTime getRecurrenceStartDate() {
+        return this.recurrenceStartDate;
+    }
+
+    public String getReportName() {
+        return this.reportName;
+    }
+
+    public Long providerId() {
+        return this.providerId;
+    }
+
+}


Mime
View raw message