fineract-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From raj...@apache.org
Subject [08/14] incubator-fineract git commit: SMS Campaign feature implementation
Date Mon, 14 Nov 2016 14:06:10 GMT
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) ;
+
+}


Mime
View raw message