http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/911cab85/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignDomainServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignDomainServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignDomainServiceImpl.java
new file mode 100644
index 0000000..00926c4
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignDomainServiceImpl.java
@@ -0,0 +1,537 @@
+/**
+ * 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.service;
+
+import java.io.IOException;
+import java.security.InvalidParameterException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.PostConstruct;
+
+import 
org.apache.fineract.infrastructure.campaigns.sms.constants.SmsCampaignTriggerType;
+import org.apache.fineract.infrastructure.campaigns.sms.domain.SmsCampaign;
+import 
org.apache.fineract.infrastructure.campaigns.sms.domain.SmsCampaignRepository;
+import org.apache.fineract.infrastructure.sms.domain.SmsMessage;
+import org.apache.fineract.infrastructure.sms.domain.SmsMessageRepository;
+import 
org.apache.fineract.infrastructure.sms.scheduler.SmsMessageScheduledJobService;
+import org.apache.fineract.organisation.office.domain.Office;
+import org.apache.fineract.organisation.office.domain.OfficeRepository;
+import org.apache.fineract.portfolio.client.domain.Client;
+import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants;
+import 
org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.BUSINESS_ENTITY;
+import 
org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.BUSINESS_EVENTS;
+import org.apache.fineract.portfolio.common.service.BusinessEventListner;
+import 
org.apache.fineract.portfolio.common.service.BusinessEventNotifierService;
+import org.apache.fineract.portfolio.group.domain.Group;
+import org.apache.fineract.portfolio.group.domain.GroupRepository;
+import org.apache.fineract.portfolio.loanaccount.domain.Loan;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
+import 
org.apache.fineract.portfolio.loanaccount.exception.InvalidLoanTypeException;
+import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
+import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransaction;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.type.TypeReference;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class SmsCampaignDomainServiceImpl implements SmsCampaignDomainService {
+
+       private static final Logger logger = 
LoggerFactory.getLogger(SmsCampaignDomainServiceImpl.class);
+       
+    private final SmsCampaignRepository smsCampaignRepository;
+    private final SmsMessageRepository smsMessageRepository;
+    private final OfficeRepository officeRepository;
+    private final BusinessEventNotifierService businessEventNotifierService;
+    private final SmsCampaignWritePlatformService 
smsCampaignWritePlatformCommandHandler;
+    private final GroupRepository groupRepository;
+
+    private final SmsMessageScheduledJobService smsMessageScheduledJobService; 
+    
+    @Autowired
+    public SmsCampaignDomainServiceImpl(final SmsCampaignRepository 
smsCampaignRepository, final SmsMessageRepository smsMessageRepository,
+                                        final BusinessEventNotifierService 
businessEventNotifierService, final OfficeRepository officeRepository,
+                                        final SmsCampaignWritePlatformService 
smsCampaignWritePlatformCommandHandler,
+                                        final GroupRepository groupRepository,
+                                        final SmsMessageScheduledJobService 
smsMessageScheduledJobService){
+        this.smsCampaignRepository = smsCampaignRepository;
+        this.smsMessageRepository = smsMessageRepository;
+        this.businessEventNotifierService = businessEventNotifierService;
+        this.officeRepository = officeRepository;
+        this.smsCampaignWritePlatformCommandHandler = 
smsCampaignWritePlatformCommandHandler;
+        this.groupRepository = groupRepository;
+        this.smsMessageScheduledJobService = smsMessageScheduledJobService ;
+    }
+
+    @PostConstruct
+    public void addListners() {
+        
this.businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.LOAN_APPROVED,
 new SendSmsOnLoanApproved());
+        
this.businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.LOAN_REJECTED,
 new SendSmsOnLoanRejected());
+        
this.businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.LOAN_MAKE_REPAYMENT,
 new SendSmsOnLoanRepayment());
+        
this.businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.CLIENTS_ACTIVATE,
 new ClientActivatedListener());
+        
this.businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.CLIENTS_REJECT,
 new ClientRejectedListener());
+        
this.businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.SAVINGS_ACTIVATE,
 new SavingsAccountActivatedListener());
+        
this.businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.SAVINGS_REJECT,
 new SavingsAccountRejectedListener());
+        
this.businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.SAVINGS_DEPOSIT,
 new SavingsAccountTransactionListener(true));
+        
this.businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.SAVINGS_WITHDRAWAL,
 new SavingsAccountTransactionListener(false));
+        
+        
+    }
+
+    private void notifyRejectedLoanOwner(Loan loan) {
+        ArrayList<SmsCampaign> smsCampaigns = retrieveSmsCampaigns("loan 
rejected");
+        if(smsCampaigns.size()>0){
+            for (SmsCampaign campaign:smsCampaigns){
+                if(campaign.isActive()) {
+                    
this.smsCampaignWritePlatformCommandHandler.insertDirectCampaignIntoSmsOutboundTable(loan,
 campaign);
+                }
+            }
+        }
+    }
+
+    private void notifyAcceptedLoanOwner(Loan loan) {
+        ArrayList<SmsCampaign> smsCampaigns = retrieveSmsCampaigns("loan 
approved");
+
+        if(smsCampaigns.size()>0){
+            for (SmsCampaign campaign:smsCampaigns){
+                if(campaign.isActive()) {
+                    
this.smsCampaignWritePlatformCommandHandler.insertDirectCampaignIntoSmsOutboundTable(loan,
 campaign);
+                }
+            }
+        }
+    }
+
+    private void notifyClientActivated(final Client client) {
+        ArrayList<SmsCampaign> smsCampaigns = retrieveSmsCampaigns("client 
activated");
+        if(smsCampaigns.size()>0){
+             for (SmsCampaign campaign:smsCampaigns){
+                 if(campaign.isActive()) {
+                     
this.smsCampaignWritePlatformCommandHandler.insertDirectCampaignIntoSmsOutboundTable(client,
 campaign);
+                 }
+             }
+         }
+        
+    }
+    
+    private void notifyClientRejected(final Client client) {
+        ArrayList<SmsCampaign> smsCampaigns = retrieveSmsCampaigns("client 
rejected");
+        if(smsCampaigns.size()>0){
+            for (SmsCampaign campaign:smsCampaigns){
+                if(campaign.isActive()) {
+                    
this.smsCampaignWritePlatformCommandHandler.insertDirectCampaignIntoSmsOutboundTable(client,
 campaign);
+                }
+            }
+        }
+        
+   }
+    
+       private void notifySavingsAccountActivated(final SavingsAccount 
savingsAccount) {
+               ArrayList<SmsCampaign> smsCampaigns = 
retrieveSmsCampaigns("savings activated");
+               if (smsCampaigns.size() > 0) {
+                       for (SmsCampaign campaign : smsCampaigns) {
+                               if (campaign.isActive()) {
+                                       
this.smsCampaignWritePlatformCommandHandler.insertDirectCampaignIntoSmsOutboundTable(savingsAccount,
+                                                       campaign);
+                               }
+                       }
+               }
+
+       }
+
+       private void notifySavingsAccountRejected(final SavingsAccount 
savingsAccount) {
+               ArrayList<SmsCampaign> smsCampaigns = 
retrieveSmsCampaigns("savings rejected");
+               if (smsCampaigns.size() > 0) {
+                       for (SmsCampaign campaign : smsCampaigns) {
+                               if (campaign.isActive()) {
+                                       
this.smsCampaignWritePlatformCommandHandler.insertDirectCampaignIntoSmsOutboundTable(savingsAccount,
+                                                       campaign);
+                               }
+                       }
+               }
+
+       }
+       
+       private void sendSmsForLoanRepayment(LoanTransaction loanTransaction) {
+               ArrayList<SmsCampaign> smsCampaigns = 
retrieveSmsCampaigns("loan repayment");
+               if (smsCampaigns.size() > 0) {
+                       for (SmsCampaign smsCampaign : smsCampaigns) {
+                               if (smsCampaign.isActive()) {
+                                       try {
+                                               Loan loan = 
loanTransaction.getLoan();
+                                               final Set<Client> groupClients 
= new HashSet<>();
+                                               if (loan.hasInvalidLoanType()) {
+                                                       throw new 
InvalidLoanTypeException("Loan Type cannot be Invalid for the Triggered Sms 
Campaign");
+                                               }
+                                               if (loan.isGroupLoan()) {
+                                                       Group group = 
this.groupRepository.findOne(loan.getGroupId());
+                                                       
groupClients.addAll(group.getClientMembers());
+                                               } else {
+                                                       
groupClients.add(loan.client());
+                                               }
+                                               HashMap<String, String> 
campaignParams = new ObjectMapper()
+                                                               
.readValue(smsCampaign.getParamValue(), new TypeReference<HashMap<String, 
String>>() {
+                                                               });
+
+                                               if (groupClients.size() > 0) {
+                                                       for (Client client : 
groupClients) {
+                                                               HashMap<String, 
Object> smsParams = processRepaymentDataForSms(loanTransaction, client);
+                                                               for (String key 
: campaignParams.keySet()) {
+                                                                       String 
value = campaignParams.get(key);
+                                                                       String 
spvalue = null;
+                                                                       boolean 
spkeycheck = smsParams.containsKey(key);
+                                                                       if 
(spkeycheck) {
+                                                                               
spvalue = smsParams.get(key).toString();
+                                                                       }
+                                                                       if 
(spkeycheck && !(value.equals("-1") || spvalue.equals(value))) {
+                                                                               
if (key.equals("officeId")) {
+                                                                               
        Office campaignOffice = 
this.officeRepository.findOne(Long.valueOf(value));
+                                                                               
        if (campaignOffice
+                                                                               
                        
.doesNotHaveAnOfficeInHierarchyWithId(client.getOffice().getId())) {
+                                                                               
                throw new RuntimeException();
+                                                                               
        }
+                                                                               
} else {
+                                                                               
        throw new RuntimeException();
+                                                                               
}
+                                                                       }
+                                                               }
+                                                               String message 
= this.smsCampaignWritePlatformCommandHandler.compileSmsTemplate(
+                                                                               
smsCampaign.getMessage(), smsCampaign.getCampaignName(), smsParams);
+                                                               Object mobileNo 
= smsParams.get("mobileNo");
+                                                               if (mobileNo != 
null) {
+                                                                       
SmsMessage smsMessage = SmsMessage.pendingSms(null, null, client, null, message,
+                                                                               
        mobileNo.toString(), smsCampaign);
+                                                                       
this.smsMessageRepository.save(smsMessage);
+                                                                       
Collection<SmsMessage> messages = new ArrayList<>();
+                                                                       
messages.add(smsMessage);
+                                                                       
Map<SmsCampaign, Collection<SmsMessage>> smsDataMap = new HashMap<>();
+                                                                       
smsDataMap.put(smsCampaign, messages);
+                                                                       
this.smsMessageScheduledJobService.sendTriggeredMessages(smsDataMap);
+                                                               }
+                                                       }
+                                               }
+                                       } catch (final IOException e) {
+                                               logger.error("smsParams does 
not contain the key: " + e.getMessage());
+                                       } catch (final RuntimeException e) {
+                                               logger.debug("Client Office Id 
and SMS Campaign Office id doesn't match");
+                                       }
+                               }
+                       }
+               }
+       }
+
+       private void sendSmsForSavingsTransaction(final 
SavingsAccountTransaction savingsTransaction, boolean isDeposit) {
+               String campaignName = isDeposit ? "savings deposit" : "savings 
withdrawal";
+               ArrayList<SmsCampaign> smsCampaigns = 
retrieveSmsCampaigns(campaignName);
+               if (smsCampaigns.size() > 0) {
+                       for (SmsCampaign smsCampaign : smsCampaigns) {
+                               if (smsCampaign.isActive()) {
+                                       try {
+                                               final SavingsAccount 
savingsAccount = savingsTransaction.getSavingsAccount();
+                                               final Client client = 
savingsAccount.getClient();
+                                               HashMap<String, String> 
campaignParams = new ObjectMapper()
+                                                               
.readValue(smsCampaign.getParamValue(), new TypeReference<HashMap<String, 
String>>() {
+                                                               });
+                                               HashMap<String, Object> 
smsParams = processSavingsTransactionDataForSms(savingsTransaction,
+                                                               client);
+                                               for (String key : 
campaignParams.keySet()) {
+                                                       String value = 
campaignParams.get(key);
+                                                       String spvalue = null;
+                                                       boolean spkeycheck = 
smsParams.containsKey(key);
+                                                       if (spkeycheck) {
+                                                               spvalue = 
smsParams.get(key).toString();
+                                                       }
+                                                       if (spkeycheck && 
!(value.equals("-1") || spvalue.equals(value))) {
+                                                               if 
(key.equals("officeId")) {
+                                                                       Office 
campaignOffice = this.officeRepository.findOne(Long.valueOf(value));
+                                                                       if 
(campaignOffice
+                                                                               
        .doesNotHaveAnOfficeInHierarchyWithId(client.getOffice().getId())) {
+                                                                               
throw new RuntimeException();
+                                                                       }
+                                                               } else {
+                                                                       throw 
new RuntimeException();
+                                                               }
+                                                       }
+                                               }
+                                               String message = 
this.smsCampaignWritePlatformCommandHandler
+                                                               
.compileSmsTemplate(smsCampaign.getMessage(), smsCampaign.getCampaignName(), 
smsParams);
+                                               Object mobileNo = 
smsParams.get("mobileNo");
+                                               if (mobileNo != null) {
+                                                       SmsMessage smsMessage = 
SmsMessage.pendingSms(null, null, client, null, message,
+                                                                       
mobileNo.toString(), smsCampaign);
+                                                       
this.smsMessageRepository.save(smsMessage);
+                                                       Collection<SmsMessage> 
messages = new ArrayList<>();
+                                                       
messages.add(smsMessage);
+                                                       Map<SmsCampaign, 
Collection<SmsMessage>> smsDataMap = new HashMap<>();
+                                                       
smsDataMap.put(smsCampaign, messages);
+                                                       
this.smsMessageScheduledJobService.sendTriggeredMessages(smsDataMap);
+                                               }
+                                       } catch (final IOException e) {
+                                               logger.error("smsParams does 
not contain the key: " + e.getMessage());
+                                       } catch (final RuntimeException e) {
+                                               logger.debug("Client Office Id 
and SMS Campaign Office id doesn't match");
+                                       }
+                               }
+                       }
+               }
+       }
+    
+    private ArrayList<SmsCampaign> retrieveSmsCampaigns(String paramValue){
+        Collection<SmsCampaign> initialSmsCampaignList = 
smsCampaignRepository.findByTriggerType(SmsCampaignTriggerType.TRIGGERED.getValue());
+        ArrayList<SmsCampaign> smsCampaigns = new ArrayList<>();
+
+        for(SmsCampaign campaign : initialSmsCampaignList){
+            if(campaign.getParamValue().toLowerCase().contains(paramValue)){
+                smsCampaigns.add(campaign);
+            }
+        }
+        return smsCampaigns;
+    }
+
+    private HashMap<String, Object> processRepaymentDataForSms(final 
LoanTransaction loanTransaction, Client groupClient){
+
+        HashMap<String, Object> smsParams = new HashMap<String, Object>();
+        Loan loan = loanTransaction.getLoan();
+        final Client client;
+        if(loan.isGroupLoan() && groupClient != null){
+            client = groupClient;
+        }else if(loan.isIndividualLoan()){
+            client = loan.getClient();
+        }else{
+            throw new InvalidParameterException("");
+        }
+
+        DateTimeFormatter timeFormatter = DateTimeFormat.forPattern("HH:mm");
+        DateTimeFormatter dateFormatter = 
DateTimeFormat.forPattern("MMM:d:yyyy");
+
+        smsParams.put("id",loanTransaction.getLoan().getClientId());
+        smsParams.put("firstname",client.getFirstname());
+        smsParams.put("middlename",client.getMiddlename());
+        smsParams.put("lastname",client.getLastname());
+        smsParams.put("FullName",client.getDisplayName());
+        smsParams.put("mobileNo",client.mobileNo());
+        smsParams.put("LoanAmount",loan.getPrincpal());
+        
smsParams.put("LoanOutstanding",loanTransaction.getOutstandingLoanBalance());
+        smsParams.put("loanId",loan.getId());
+        smsParams.put("LoanAccountId", loan.getAccountNumber());
+        smsParams.put("officeId", client.getOffice().getId());
+        
+        if(client.getStaff() != null) {
+               smsParams.put("loanOfficerId", client.getStaff().getId());
+        }else {
+                 smsParams.put("loanOfficerId", -1);
+        }
+        
+        smsParams.put("repaymentAmount", 
loanTransaction.getAmount(loan.getCurrency()));
+        smsParams.put("RepaymentDate", 
loanTransaction.getCreatedDateTime().toLocalDate().toString(dateFormatter));
+        smsParams.put("RepaymentTime", 
loanTransaction.getCreatedDateTime().toLocalTime().toString(timeFormatter));
+        
+        if(loanTransaction.getPaymentDetail() != null) {
+               smsParams.put("receiptNumber", 
loanTransaction.getPaymentDetail().getReceiptNumber());
+        }else {
+               smsParams.put("receiptNumber", -1);     
+        }
+        return smsParams;
+    }
+
+    private HashMap<String, Object> processSavingsTransactionDataForSms(final 
SavingsAccountTransaction savingsAccountTransaction, Client client){
+
+       // {{savingsId}} {{id}} {{firstname}} {{middlename}} {{lastname}} 
{{FullName}} {{mobileNo}} {{savingsAccountId}} {{depositAmount}} {{balance}}
+       
+       //transactionDate
+        HashMap<String, Object> smsParams = new HashMap<String, Object>();
+        SavingsAccount savingsAccount = 
savingsAccountTransaction.getSavingsAccount() ;
+        DateTimeFormatter dateFormatter = 
DateTimeFormat.forPattern("MMM:d:yyyy");
+        smsParams.put("clientId",client.getId());
+        smsParams.put("firstname",client.getFirstname());
+        smsParams.put("middlename",client.getMiddlename());
+        smsParams.put("lastname",client.getLastname());
+        smsParams.put("FullName",client.getDisplayName());
+        smsParams.put("mobileNo",client.mobileNo());
+        smsParams.put("savingsId", savingsAccount.getId()) ;
+        smsParams.put("savingsAccountNo",savingsAccount.getAccountNumber());
+        
smsParams.put("withdrawAmount",savingsAccountTransaction.getAmount(savingsAccount.getCurrency()));
+        
smsParams.put("depositAmount",savingsAccountTransaction.getAmount(savingsAccount.getCurrency()));
+        smsParams.put("balance",savingsAccount.getWithdrawableBalance());
+        smsParams.put("officeId", client.getOffice().getId());
+        smsParams.put("transactionDate", 
savingsAccountTransaction.getTransactionLocalDate().toString(dateFormatter)) ;
+        smsParams.put("savingsTransactionId", 
savingsAccountTransaction.getId()) ;
+        
+        if(client.getStaff() != null) {
+               smsParams.put("loanOfficerId", client.getStaff().getId());
+        }else {
+                 smsParams.put("loanOfficerId", -1);
+        }
+        
+        if(savingsAccountTransaction.getPaymentDetail() != null) {
+               smsParams.put("receiptNumber", 
savingsAccountTransaction.getPaymentDetail().getReceiptNumber());
+        }else {
+               smsParams.put("receiptNumber", -1);     
+        }
+        return smsParams;
+    }
+    
+    private class SendSmsOnLoanApproved implements BusinessEventListner{
+
+        @Override
+        public void 
businessEventToBeExecuted(Map<BusinessEventNotificationConstants.BUSINESS_ENTITY,
 Object> businessEventEntity) {
+
+        }
+
+        @Override
+        public void 
businessEventWasExecuted(Map<BusinessEventNotificationConstants.BUSINESS_ENTITY,
 Object> businessEventEntity) {
+            Object entity = 
businessEventEntity.get(BusinessEventNotificationConstants.BUSINESS_ENTITY.LOAN);
+            if (entity instanceof Loan) {
+                Loan loan = (Loan) entity;
+                notifyAcceptedLoanOwner(loan);
+            }
+        }
+    }
+
+    private class SendSmsOnLoanRejected implements BusinessEventListner{
+
+        @Override
+        public void 
businessEventToBeExecuted(Map<BusinessEventNotificationConstants.BUSINESS_ENTITY,
 Object> businessEventEntity) {
+
+        }
+
+        @Override
+        public void 
businessEventWasExecuted(Map<BusinessEventNotificationConstants.BUSINESS_ENTITY,
 Object> businessEventEntity) {
+            Object entity = 
businessEventEntity.get(BusinessEventNotificationConstants.BUSINESS_ENTITY.LOAN);
+            if (entity instanceof Loan) {
+                Loan loan = (Loan) entity;
+                notifyRejectedLoanOwner(loan);
+            }
+        }
+    }
+
+    private class SendSmsOnLoanRepayment implements BusinessEventListner{
+
+        @Override
+        public void 
businessEventToBeExecuted(Map<BusinessEventNotificationConstants.BUSINESS_ENTITY,
 Object> businessEventEntity) {
+
+        }
+
+        @Override
+        public void 
businessEventWasExecuted(Map<BusinessEventNotificationConstants.BUSINESS_ENTITY,
 Object> businessEventEntity) {
+            Object entity = 
businessEventEntity.get(BusinessEventNotificationConstants.BUSINESS_ENTITY.LOAN_TRANSACTION);
+            if (entity instanceof LoanTransaction) {
+                LoanTransaction loanTransaction = (LoanTransaction) entity;
+                sendSmsForLoanRepayment(loanTransaction);
+            }
+        }
+    }
+    
+    private class ClientActivatedListener implements BusinessEventListner {
+
+               @Override
+               public void businessEventToBeExecuted(Map<BUSINESS_ENTITY, 
Object> businessEventEntity) {
+                       
+               }
+
+               @Override
+               public void businessEventWasExecuted(Map<BUSINESS_ENTITY, 
Object> businessEventEntity) {
+                       Object entity = 
businessEventEntity.get(BusinessEventNotificationConstants.BUSINESS_ENTITY.CLIENT);
+                       if(entity instanceof Client) {
+                               notifyClientActivated((Client)entity);  
+                       }
+               }
+    }
+    
+    private class ClientRejectedListener implements BusinessEventListner {
+
+               @Override
+               public void businessEventToBeExecuted(Map<BUSINESS_ENTITY, 
Object> businessEventEntity) {
+                       
+               }
+
+               @Override
+               public void businessEventWasExecuted(Map<BUSINESS_ENTITY, 
Object> businessEventEntity) {
+                       Object entity = 
businessEventEntity.get(BusinessEventNotificationConstants.BUSINESS_ENTITY.CLIENT);
+                       if(entity instanceof Client) {
+                               notifyClientRejected((Client)entity);
+                       }
+                       
+               }
+    }
+    
+    private class SavingsAccountActivatedListener implements 
BusinessEventListner {
+
+               @Override
+               public void businessEventToBeExecuted(Map<BUSINESS_ENTITY, 
Object> businessEventEntity) {
+                       
+               }
+
+               @Override
+               public void businessEventWasExecuted(Map<BUSINESS_ENTITY, 
Object> businessEventEntity) {
+                       Object entity = 
businessEventEntity.get(BusinessEventNotificationConstants.BUSINESS_ENTITY.SAVING);
+                       if(entity instanceof SavingsAccount) {
+                               
notifySavingsAccountActivated((SavingsAccount)entity);
+                       }
+                       
+               }
+    }
+    
+    private class SavingsAccountRejectedListener implements 
BusinessEventListner {
+
+               @Override
+               public void businessEventToBeExecuted(Map<BUSINESS_ENTITY, 
Object> businessEventEntity) {
+                       
+               }
+
+               @Override
+               public void businessEventWasExecuted(Map<BUSINESS_ENTITY, 
Object> businessEventEntity) {
+                       Object entity = 
businessEventEntity.get(BusinessEventNotificationConstants.BUSINESS_ENTITY.SAVING);
+                       if(entity instanceof SavingsAccount) {
+                               
notifySavingsAccountRejected((SavingsAccount)entity);
+                       }
+               }
+    }
+    
+    private class SavingsAccountTransactionListener implements 
BusinessEventListner {
+
+       final boolean isDeposit ;
+       
+       public SavingsAccountTransactionListener(final boolean isDeposit) {
+                       this.isDeposit = isDeposit ;
+               }
+               @Override
+               public void businessEventToBeExecuted(Map<BUSINESS_ENTITY, 
Object> businessEventEntity) {
+                       // TODO Auto-generated method stub
+                       
+               }
+
+               @Override
+               public void businessEventWasExecuted(Map<BUSINESS_ENTITY, 
Object> businessEventEntity) {
+                       Object entity = 
businessEventEntity.get(BusinessEventNotificationConstants.BUSINESS_ENTITY.SAVINGS_TRANSACTION);
+                       if(entity instanceof SavingsAccountTransaction) {
+                               
sendSmsForSavingsTransaction((SavingsAccountTransaction)entity, this.isDeposit);
+                       }
+               }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/911cab85/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignDropdownReadPlatformService.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignDropdownReadPlatformService.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignDropdownReadPlatformService.java
new file mode 100644
index 0000000..bb9814c
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignDropdownReadPlatformService.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.service;
+
+import java.util.Collection;
+
+import org.apache.fineract.infrastructure.campaigns.sms.data.SmsProviderData;
+import 
org.apache.fineract.infrastructure.campaigns.sms.data.TriggerTypeWithSubTypesData;
+import org.apache.fineract.infrastructure.core.data.EnumOptionData;
+
+public interface SmsCampaignDropdownReadPlatformService {
+
+    Collection<EnumOptionData> retrieveCampaignTriggerTypes();
+
+    Collection<SmsProviderData> retrieveSmsProviders();
+
+    Collection<EnumOptionData> retrieveCampaignTypes();
+
+    Collection<EnumOptionData> retrieveWeeks();
+
+    Collection<EnumOptionData> retrieveMonths();
+
+    Collection<EnumOptionData> retrivePeriodFrequencyTypes();
+
+    Collection<TriggerTypeWithSubTypesData> getTriggerTypeAndSubTypes();
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/911cab85/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignDropdownReadPlatformServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignDropdownReadPlatformServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignDropdownReadPlatformServiceImpl.java
new file mode 100644
index 0000000..44c92b9
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignDropdownReadPlatformServiceImpl.java
@@ -0,0 +1,125 @@
+/**
+ * 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.service;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.fineract.infrastructure.campaigns.constants.CampaignType;
+import org.apache.fineract.infrastructure.campaigns.helper.SmsConfigUtils;
+import 
org.apache.fineract.infrastructure.campaigns.sms.constants.SmsCampaignConstants;
+import 
org.apache.fineract.infrastructure.campaigns.sms.constants.SmsCampaignEnumerations;
+import 
org.apache.fineract.infrastructure.campaigns.sms.constants.SmsCampaignTriggerType;
+import 
org.apache.fineract.infrastructure.campaigns.sms.data.CampaignTriggerWithSubTypes;
+import org.apache.fineract.infrastructure.campaigns.sms.data.SmsProviderData;
+import 
org.apache.fineract.infrastructure.campaigns.sms.data.TriggerTypeWithSubTypesData;
+import 
org.apache.fineract.infrastructure.campaigns.sms.exception.ConnectionFailureException;
+import org.apache.fineract.infrastructure.core.data.EnumOptionData;
+import org.apache.fineract.portfolio.calendar.domain.CalendarWeekDaysType;
+import org.apache.fineract.portfolio.calendar.service.CalendarEnumerations;
+import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+@Service
+public class SmsCampaignDropdownReadPlatformServiceImpl implements 
SmsCampaignDropdownReadPlatformService {
+
+    private final RestTemplate restTemplate;
+
+    private final SmsConfigUtils smsConfigUtils ;
+    
+    @Autowired
+    public SmsCampaignDropdownReadPlatformServiceImpl(final SmsConfigUtils 
smsConfigUtils) {
+        this.restTemplate = new RestTemplate();
+        this.smsConfigUtils = smsConfigUtils ;
+    }
+
+    @Override
+    public Collection<EnumOptionData> retrieveCampaignTriggerTypes() {
+        final List<EnumOptionData> triggerTypeCodeValues = Arrays.asList( //
+                
SmsCampaignEnumerations.smscampaignTriggerType(SmsCampaignTriggerType.DIRECT), 
//
+                
SmsCampaignEnumerations.smscampaignTriggerType(SmsCampaignTriggerType.SCHEDULE),
 //
+                
SmsCampaignEnumerations.smscampaignTriggerType(SmsCampaignTriggerType.TRIGGERED)
 //
+                );
+
+        return triggerTypeCodeValues;
+    }
+
+    @Override
+    public Collection<SmsProviderData> retrieveSmsProviders() {
+        Collection<SmsProviderData> smsProviderOptions = new ArrayList<>();
+        try {
+            Map<String, Object> hostConfig = 
this.smsConfigUtils.getMessageGateWayRequestURI("smsbridges", null);
+            URI uri = (URI) hostConfig.get("uri");
+            HttpEntity<?> entity = (HttpEntity<?>) hostConfig.get("entity");
+            ResponseEntity<Collection<SmsProviderData>> responseOne = 
restTemplate.exchange(uri, HttpMethod.GET, entity,
+                    new 
ParameterizedTypeReference<Collection<SmsProviderData>>() {});
+            smsProviderOptions = responseOne.getBody();
+            if (!responseOne.getStatusCode().equals(HttpStatus.OK)) {
+                System.out.println(responseOne.getStatusCode().name());
+                throw new 
ConnectionFailureException(SmsCampaignConstants.SMS_BRIDGE);
+            }
+        } catch (Exception e) {
+            e.getStackTrace();
+        }
+        return smsProviderOptions;
+    }
+
+    @Override
+    public Collection<EnumOptionData> retrieveCampaignTypes() {
+        final List<EnumOptionData> campaignTypeCodeValues = Arrays.asList( //
+                SmsCampaignEnumerations.smscampaignType(CampaignType.SMS)//
+                );
+        return campaignTypeCodeValues;
+    }
+
+    @Override
+    public Collection<EnumOptionData> retrieveMonths() {
+        Collection<EnumOptionData> monthsList = 
SmsCampaignEnumerations.calendarMonthType();
+        return monthsList;
+    }
+
+    @Override
+    public Collection<EnumOptionData> retrieveWeeks() {
+        Collection<EnumOptionData> weeksList = 
CalendarEnumerations.calendarWeekDaysType(CalendarWeekDaysType.values());
+        return weeksList;
+    }
+
+    @Override
+    public Collection<EnumOptionData> retrivePeriodFrequencyTypes() {
+        Collection<EnumOptionData> periodFrequencyTypes = 
SmsCampaignEnumerations
+                .calendarPeriodFrequencyTypes(PeriodFrequencyType.values());
+        return periodFrequencyTypes;
+    }
+
+    @Override
+    public Collection<TriggerTypeWithSubTypesData> getTriggerTypeAndSubTypes() 
{
+        return CampaignTriggerWithSubTypes.getTriggerTypeAndSubTypes();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/911cab85/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignReadPlatformService.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignReadPlatformService.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignReadPlatformService.java
new file mode 100644
index 0000000..8f478bc
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignReadPlatformService.java
@@ -0,0 +1,36 @@
+/**
+ * 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.service;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.fineract.infrastructure.campaigns.sms.data.SmsCampaignData;
+
+public interface SmsCampaignReadPlatformService {
+
+    public SmsCampaignData retrieveOne(final Long campaignId);
+
+    public List<SmsCampaignData> retrieveAll();
+
+    public SmsCampaignData retrieveTemplate(final String reportType);
+
+    Collection<SmsCampaignData> retrieveAllScheduleActiveCampaign();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/911cab85/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignReadPlatformServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignReadPlatformServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignReadPlatformServiceImpl.java
new file mode 100644
index 0000000..ba7be61
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignReadPlatformServiceImpl.java
@@ -0,0 +1,260 @@
+/**
+ * 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.service;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.fineract.infrastructure.campaigns.constants.CampaignType;
+import 
org.apache.fineract.infrastructure.campaigns.sms.constants.SmsCampaignTriggerType;
+import 
org.apache.fineract.infrastructure.campaigns.sms.data.SmsBusinessRulesData;
+import org.apache.fineract.infrastructure.campaigns.sms.data.SmsCampaignData;
+import 
org.apache.fineract.infrastructure.campaigns.sms.data.SmsCampaignTimeLine;
+import org.apache.fineract.infrastructure.campaigns.sms.data.SmsProviderData;
+import 
org.apache.fineract.infrastructure.campaigns.sms.domain.SmsCampaignStatusEnumerations;
+import 
org.apache.fineract.infrastructure.campaigns.sms.exception.SmsCampaignNotFound;
+import org.apache.fineract.infrastructure.core.data.EnumOptionData;
+import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import 
org.apache.fineract.portfolio.calendar.service.CalendarDropdownReadPlatformService;
+import org.joda.time.DateTime;
+import org.joda.time.LocalDate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataAccessException;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.ResultSetExtractor;
+import org.springframework.jdbc.core.RowMapper;
+import org.springframework.stereotype.Service;
+
+@Service
+public class SmsCampaignReadPlatformServiceImpl implements 
SmsCampaignReadPlatformService {
+
+    private final BusinessRuleMapper businessRuleMapper;
+    private final JdbcTemplate jdbcTemplate;
+    private final SmsCampaignDropdownReadPlatformService 
smsCampaignDropdownReadPlatformService;
+    private final SmsCampaignMapper smsCampaignMapper;
+    private final CalendarDropdownReadPlatformService 
calendarDropdownReadPlatformService;
+
+    @Autowired
+    public SmsCampaignReadPlatformServiceImpl(final RoutingDataSource 
dataSource,
+            SmsCampaignDropdownReadPlatformService 
smsCampaignDropdownReadPlatformService, 
+            final CalendarDropdownReadPlatformService 
calendarDropdownReadPlatformService) {
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        businessRuleMapper = new BusinessRuleMapper();
+        this.smsCampaignDropdownReadPlatformService = 
smsCampaignDropdownReadPlatformService;
+        smsCampaignMapper = new SmsCampaignMapper();
+        this.calendarDropdownReadPlatformService = 
calendarDropdownReadPlatformService;
+    }
+
+    @Override
+    public SmsCampaignData retrieveOne(Long campaignId) {
+        final Integer isVisible = 1;
+        try {
+            final String sql = "select " + this.smsCampaignMapper.schema + " 
where sc.id = ? and sc.is_visible = ?";
+            return this.jdbcTemplate.queryForObject(sql, 
this.smsCampaignMapper, new Object[] { campaignId, isVisible });
+        } catch (final EmptyResultDataAccessException e) {
+            throw new SmsCampaignNotFound(campaignId);
+        }
+    }
+
+    @Override
+    public List<SmsCampaignData> retrieveAll() {
+        final Integer visible = 1;
+        final String sql = "select " + this.smsCampaignMapper.schema() + " 
where sc.is_visible = ?";
+        return this.jdbcTemplate.query(sql, this.smsCampaignMapper, new 
Object[] {visible});
+    }
+
+    @Override
+    public SmsCampaignData retrieveTemplate(final String reportType) {
+        String sql = "select " + this.businessRuleMapper.schema();
+        if (!StringUtils.isEmpty(reportType)) {
+            sql = sql + " where sr.report_type = ?";
+        }
+        final Collection<SmsBusinessRulesData> businessRulesOptions = 
this.jdbcTemplate.query(sql, this.businessRuleMapper,
+                new Object[] { reportType });
+        final Collection<SmsProviderData> smsProviderOptions = 
this.smsCampaignDropdownReadPlatformService.retrieveSmsProviders();
+        final Collection<EnumOptionData> campaignTypeOptions = 
this.smsCampaignDropdownReadPlatformService.retrieveCampaignTypes();
+        final Collection<EnumOptionData> campaignTriggerTypeOptions = 
this.smsCampaignDropdownReadPlatformService
+                .retrieveCampaignTriggerTypes();
+        final Collection<EnumOptionData> months = 
this.smsCampaignDropdownReadPlatformService.retrieveMonths();
+        final Collection<EnumOptionData> weekDays = 
this.smsCampaignDropdownReadPlatformService.retrieveWeeks();
+        final Collection<EnumOptionData> frequencyTypeOptions = 
this.calendarDropdownReadPlatformService
+                .retrieveCalendarFrequencyTypeOptions();
+        final Collection<EnumOptionData> periodFrequencyOptions = 
this.smsCampaignDropdownReadPlatformService.retrivePeriodFrequencyTypes();
+        //final Collection<TriggerTypeWithSubTypesData> 
triggerTypeSubTypeOptions = 
this.smsCampaignDropdownReadPlatformService.getTriggerTypeAndSubTypes();
+        return SmsCampaignData.template(smsProviderOptions, 
campaignTypeOptions, businessRulesOptions, campaignTriggerTypeOptions, months,
+                weekDays, frequencyTypeOptions, periodFrequencyOptions);
+    }
+
+    @Override
+    public Collection<SmsCampaignData> retrieveAllScheduleActiveCampaign() {
+        return null;
+    }
+
+    private static final class BusinessRuleMapper implements 
ResultSetExtractor<List<SmsBusinessRulesData>> {
+
+        final String schema;
+
+        private BusinessRuleMapper() {
+            final StringBuilder sql = new StringBuilder(300);
+            sql.append("sr.id as id, ");
+            sql.append("sr.report_name as reportName, ");
+            sql.append("sr.report_type as reportType, ");
+            sql.append("sr.report_subtype as reportSubType, ");
+            sql.append("sr.description as description, ");
+            sql.append("sp.parameter_variable as params, ");
+            sql.append("sp.parameter_FormatType as paramType, ");
+            sql.append("sp.parameter_label as paramLabel, ");
+            sql.append("sp.parameter_name as paramName ");
+            sql.append("from stretchy_report sr ");
+            sql.append("left join stretchy_report_parameter as srp on 
srp.report_id = sr.id ");
+            sql.append("left join stretchy_parameter as sp on sp.id = 
srp.parameter_id ");
+
+            this.schema = sql.toString();
+        }
+
+        public String schema() {
+            return this.schema;
+        }
+
+        @Override
+        public List<SmsBusinessRulesData> extractData(ResultSet rs) throws 
SQLException, DataAccessException {
+            List<SmsBusinessRulesData> smsBusinessRulesDataList = new 
ArrayList<SmsBusinessRulesData>();
+
+            SmsBusinessRulesData smsBusinessRulesData = null;
+
+            Map<Long, SmsBusinessRulesData> mapOfSameObjects = new 
HashMap<Long, SmsBusinessRulesData>();
+
+            while (rs.next()) {
+                final Long id = rs.getLong("id");
+                smsBusinessRulesData = mapOfSameObjects.get(id);
+                if (smsBusinessRulesData == null) {
+                    final String reportName = rs.getString("reportName");
+                    final String reportType = rs.getString("reportType");
+                    final String reportSubType = rs.getString("reportSubType");
+                    final String paramName = rs.getString("paramName");
+                    final String paramLabel = rs.getString("paramLabel");
+                    final String description = rs.getString("description");
+
+                    Map<String, Object> hashMap = new HashMap<String, 
Object>();
+                    hashMap.put(paramLabel, paramName);
+                    smsBusinessRulesData = SmsBusinessRulesData.instance(id, 
reportName, reportType, reportSubType, hashMap, description);
+                    mapOfSameObjects.put(id, smsBusinessRulesData);
+                    // add to the list
+                    smsBusinessRulesDataList.add(smsBusinessRulesData);
+                }
+                // add new paramType to the existing object
+                Map<String, Object> hashMap = new HashMap<String, Object>();
+                final String paramName = rs.getString("paramName");
+                final String paramLabel = rs.getString("paramLabel");
+                hashMap.put(paramLabel, paramName);
+
+                // get existing map and add new items to it
+                smsBusinessRulesData.getReportParamName().putAll(hashMap);
+            }
+
+            return smsBusinessRulesDataList;
+        }
+    }
+    
+    private static final class SmsCampaignMapper implements 
RowMapper<SmsCampaignData> {
+
+        final String schema;
+
+        private SmsCampaignMapper() {
+            final StringBuilder sql = new StringBuilder(400);
+            sql.append("sc.id as id, ");
+            sql.append("sc.campaign_name as campaignName, ");
+            sql.append("sc.campaign_type as campaignType, ");
+            sql.append("sc.campaign_trigger_type as triggerType, ");
+            sql.append("sc.report_id as runReportId, ");
+            sql.append("sc.message as message, ");
+            sql.append("sc.param_value as paramValue, ");
+            sql.append("sc.status_enum as status, ");
+            sql.append("sc.recurrence as recurrence, ");
+            sql.append("sc.recurrence_start_date as recurrenceStartDate, ");
+            sql.append("sc.next_trigger_date as nextTriggerDate, ");
+            sql.append("sc.last_trigger_date as lastTriggerDate, ");
+            sql.append("sc.submittedon_date as submittedOnDate, ");
+            sql.append("sbu.username as submittedByUsername, ");
+            sql.append("sc.closedon_date as closedOnDate, ");
+            sql.append("clu.username as closedByUsername, ");
+            sql.append("acu.username as activatedByUsername, ");
+            sql.append("sc.approvedon_date as activatedOnDate, ");
+            sql.append("sr.report_name as reportName, ");
+            sql.append("provider_id as providerId ");
+            sql.append("from sms_campaign sc ");
+            sql.append("left join m_appuser sbu on sbu.id = 
sc.submittedon_userid ");
+            sql.append("left join m_appuser acu on acu.id = 
sc.approvedon_userid ");
+            sql.append("left join m_appuser clu on clu.id = sc.closedon_userid 
");
+            sql.append("left join stretchy_report sr on sr.id = sc.report_id 
");
+
+            this.schema = sql.toString();
+        }
+
+        public String schema() {
+            return this.schema;
+        }
+
+        @Override
+        public SmsCampaignData mapRow(ResultSet rs, int rowNum) throws 
SQLException {
+            final Long id = JdbcSupport.getLong(rs, "id");
+            final String campaignName = rs.getString("campaignName");
+            final Integer campaignType = JdbcSupport.getInteger(rs, 
"campaignType");
+            final EnumOptionData campaignTypeEnum = 
CampaignType.campaignType(campaignType);
+            final Long runReportId = JdbcSupport.getLong(rs, "runReportId");
+            final String paramValue = rs.getString("paramValue");
+            final String message = rs.getString("message");
+
+            final Integer statusId = JdbcSupport.getInteger(rs, "status");
+            final EnumOptionData status = 
SmsCampaignStatusEnumerations.status(statusId);
+            final Integer triggerType = JdbcSupport.getInteger(rs, 
"triggerType");
+            final EnumOptionData triggerTypeEnum = 
SmsCampaignTriggerType.triggerType(triggerType);
+
+            final DateTime nextTriggerDate = JdbcSupport.getDateTime(rs, 
"nextTriggerDate");
+            final LocalDate lastTriggerDate = JdbcSupport.getLocalDate(rs, 
"lastTriggerDate");
+
+            final LocalDate closedOnDate = JdbcSupport.getLocalDate(rs, 
"closedOnDate");
+            final String closedByUsername = rs.getString("closedByUsername");
+
+            final LocalDate submittedOnDate = JdbcSupport.getLocalDate(rs, 
"submittedOnDate");
+            final String submittedByUsername = 
rs.getString("submittedByUsername");
+
+            final LocalDate activatedOnDate = JdbcSupport.getLocalDate(rs, 
"activatedOnDate");
+            final String activatedByUsername = 
rs.getString("activatedByUsername");
+            final String recurrence = rs.getString("recurrence");
+            final DateTime recurrenceStartDate = JdbcSupport.getDateTime(rs, 
"recurrenceStartDate");
+            final SmsCampaignTimeLine smsCampaignTimeLine = new 
SmsCampaignTimeLine(submittedOnDate, submittedByUsername, activatedOnDate,
+                    activatedByUsername, closedOnDate, closedByUsername);
+            final String reportName = rs.getString("reportName");
+            final Long providerId = rs.getLong("providerId");
+
+            return SmsCampaignData.instance(id, campaignName, 
campaignTypeEnum, triggerTypeEnum, runReportId, reportName, paramValue, status, 
message, nextTriggerDate, lastTriggerDate,
+                    smsCampaignTimeLine, recurrenceStartDate, recurrence, 
providerId);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/911cab85/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignWritePlatformService.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignWritePlatformService.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignWritePlatformService.java
new file mode 100644
index 0000000..b045a93
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignWritePlatformService.java
@@ -0,0 +1,59 @@
+/**
+ * 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.service;
+
+import java.util.Map;
+
+import 
org.apache.fineract.infrastructure.campaigns.sms.data.CampaignPreviewData;
+import org.apache.fineract.infrastructure.campaigns.sms.domain.SmsCampaign;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.api.JsonQuery;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.jobs.exception.JobExecutionException;
+import org.apache.fineract.portfolio.client.domain.Client;
+import org.apache.fineract.portfolio.loanaccount.domain.Loan;
+import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
+
+public interface SmsCampaignWritePlatformService {
+
+    CommandProcessingResult create(JsonCommand command);
+
+    CommandProcessingResult update(Long resourceId, JsonCommand command);
+
+    CommandProcessingResult delete(Long resourceId);
+
+    CommandProcessingResult activateSmsCampaign(Long campaignId, JsonCommand 
command);
+
+    CommandProcessingResult closeSmsCampaign(Long campaignId, JsonCommand 
command);
+
+    CommandProcessingResult reactivateSmsCampaign(Long campaignId, JsonCommand 
command);
+
+    void insertDirectCampaignIntoSmsOutboundTable(Loan loan, SmsCampaign 
smsCampaign);
+
+    String compileSmsTemplate(String textMessageTemplate, String campaignName, 
Map<String, Object> smsParams);
+
+    CampaignPreviewData previewMessage(JsonQuery query);
+
+    public void storeTemplateMessageIntoSmsOutBoundTable() throws 
JobExecutionException;
+
+    public void insertDirectCampaignIntoSmsOutboundTable(final Client client, 
final SmsCampaign smsCampaign) ;
+    
+    public void insertDirectCampaignIntoSmsOutboundTable(final SavingsAccount 
savingsAccount, final SmsCampaign smsCampaign) ;
+
+}

Reply via email to