Email Campaigns PR


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

Branch: refs/heads/develop
Commit: c338c1758e8755c96db14a2d1e4811c576daa5e6
Parents: d6accae
Author: Ippez Robert <ippezrob...@gmail.com>
Authored: Tue Nov 14 15:53:34 2017 +0300
Committer: GitHub <nore...@github.com>
Committed: Tue Nov 14 15:53:34 2017 +0300

----------------------------------------------------------------------
 .../commands/service/CommandWrapperBuilder.java |  78 +-
 .../campaigns/email/EmailApiConstants.java      |  54 ++
 .../email/ScheduledEmailConstants.java          |  82 ++
 .../campaigns/email/api/EmailApiResource.java   | 201 +++++
 .../email/api/EmailCampaignApiResource.java     | 230 ++++++
 .../api/EmailConfigurationApiResource.java      |  94 +++
 .../email/data/EmailBusinessRulesData.java      |  96 +++
 .../campaigns/email/data/EmailCampaignData.java | 144 ++++
 .../email/data/EmailCampaignTimeLine.java       |  40 +
 .../email/data/EmailCampaignValidator.java      | 259 +++++++
 .../email/data/EmailConfigurationData.java      |  63 ++
 .../email/data/EmailConfigurationValidator.java | 111 +++
 .../campaigns/email/data/EmailData.java         | 160 ++++
 .../email/data/EmailDataValidator.java          | 307 ++++++++
 .../data/EmailMessageWithAttachmentData.java    |  53 ++
 .../email/data/PreviewCampaignMessage.java      |  40 +
 .../email/data/ScheduledEmailEnumerations.java  |  56 ++
 .../campaigns/email/domain/EmailCampaign.java   | 538 +++++++++++++
 .../email/domain/EmailCampaignRepository.java   |  25 +
 .../email/domain/EmailCampaignStatus.java       |  71 ++
 .../domain/EmailCampaignStatusEnumerations.java |  53 ++
 .../email/domain/EmailCampaignType.java         |  61 ++
 .../email/domain/EmailConfiguration.java        |  60 ++
 .../domain/EmailConfigurationRepository.java    |  26 +
 .../campaigns/email/domain/EmailMessage.java    | 164 ++++
 .../email/domain/EmailMessageAssembler.java     |  92 +++
 .../email/domain/EmailMessageEnumerations.java  |  58 ++
 .../email/domain/EmailMessageRepository.java    |  29 +
 .../email/domain/EmailMessageStatusType.java    |  72 ++
 .../ScheduledEmailAttachmentFileFormat.java     | 110 +++
 ...duledEmailStretchyReportParamDateOption.java | 117 +++
 .../exception/EmailBusinessRuleNotFound.java    |  28 +
 ...ampaignMustBeClosedToBeDeletedException.java |  28 +
 ...mailCampaignMustBeClosedToEditException.java |  30 +
 .../email/exception/EmailCampaignNotFound.java  |  28 +
 .../EmailConfigurationNotFoundException.java    |  31 +
 .../EmailConfigurationSMTPUsernameNotValid.java |  30 +
 .../email/exception/EmailNotFoundException.java |  31 +
 .../ActivateEmailCampaignCommandHandler.java    |  45 ++
 .../CloseEmailCampaignCommandHandler.java       |  43 +
 .../CreateEmailCampaignCommandHandler.java      |  46 ++
 .../handler/CreateEmailCommandHandler.java      |  47 ++
 .../DeleteEmailCampaignCommandHandler.java      |  45 ++
 .../handler/DeleteEmailCommandHandler.java      |  47 ++
 .../ReactivateEmailCampaignCommandHandler.java  |  45 ++
 .../UpdateEmailCampaignCommandHandler.java      |  44 ++
 .../UpdateEmailConfigurationCommandHandler.java |  48 ++
 .../EmailCampaignReadPlatformService.java       |  38 +
 .../EmailCampaignReadPlatformServiceImpl.java   | 285 +++++++
 ...CampaignWritePlatformCommandHandlerImpl.java | 775 +++++++++++++++++++
 .../EmailCampaignWritePlatformService.java      |  47 ++
 .../EmailConfigurationReadPlatformService.java  |  30 +
 ...ailConfigurationReadPlatformServiceImpl.java |  99 +++
 .../EmailConfigurationWritePlatformService.java |  28 +
 ...ilConfigurationWritePlatformServiceImpl.java |  89 +++
 .../service/EmailMessageJobEmailService.java    |  28 +
 .../EmailMessageJobEmailServiceImpl.java        | 110 +++
 .../email/service/EmailReadPlatformService.java |  45 ++
 .../service/EmailReadPlatformServiceImpl.java   | 199 +++++
 .../service/EmailWritePlatformService.java      |  31 +
 ...ilWritePlatformServiceJpaRepositoryImpl.java | 134 ++++
 .../sms/api/SmsCampaignApiResource.java         |   2 +-
 .../SmsCampaignWritePlatformServiceJpaImpl.java |   2 +-
 .../core/service/SearchParameters.java          |  15 +
 .../dataqueries/domain/Report.java              |   4 +
 .../domain/ReportParameterUsage.java            |   4 +
 .../domain/ReportParameterUsageRepository.java  |   4 +
 .../service/ReadReportingService.java           |  14 +-
 .../service/ReadReportingServiceImpl.java       |  94 ++-
 .../infrastructure/jobs/service/JobName.java    |   6 +-
 ...portMailingJobEmailAttachmentFileFormat.java | 110 +++
 .../reportmailingjob/helper/IPv4Helper.java     | 143 ++++
 .../organisation/staff/domain/Staff.java        |   7 +
 .../client/api/ClientApiConstants.java          |   3 +-
 .../data/ClientApiCollectionConstants.java      |   4 +-
 .../portfolio/client/data/ClientData.java       |  25 +-
 .../portfolio/client/domain/Client.java         |  28 +-
 .../service/ClientReadPlatformServiceImpl.java  |   8 +-
 .../V322_1__scheduled_email_campaign.sql        | 169 ++++
 .../core_db/V322_2__email_business_rules.sql    | 127 +++
 80 files changed, 6840 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/fineract/blob/c338c175/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java
 
b/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java
index 0ad3612..a2ac7f0 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java
@@ -2929,7 +2929,7 @@ public class CommandWrapperBuilder {
         this.href = "/smscampaigns/"+resourceId;
         return this;
     }
-    
+
     public CommandWrapperBuilder holdAmount(final Long accountId) {
         this.actionName = "HOLDAMOUNT";
         this.entityName = "SAVINGSACCOUNT";
@@ -3039,6 +3039,82 @@ public class CommandWrapperBuilder {
         this.entityId = adHocId;
         this.href = "/adhocquery/" + adHocId;
         this.json = "{}";
+
+    public CommandWrapperBuilder createEmail() {
+        this.actionName = "CREATE";
+        this.entityName = "EMAIL";
+        this.entityId = null;
+        this.href = "/emailcampaigns/template";
+        return this;
+    }
+
+    public CommandWrapperBuilder updateEmail(final Long resourceId) {
+        this.actionName = "UPDATE";
+        this.entityName = "EMAIL";
+        this.entityId = resourceId;
+        this.href = "/emailcampaigns/"+resourceId;
+        return this;
+    }
+
+    public CommandWrapperBuilder deleteEmail(final Long resourceId) {
+        this.actionName = "DELETE";
+        this.entityName = "EMAIL";
+        this.entityId = resourceId;
+        this.href = "/emailcampaigns/"+resourceId;
+        return this;
+    }
+
+    public CommandWrapperBuilder createEmailCampaign() {
+        this.actionName = "CREATE";
+        this.entityName = "EMAIL_CAMPAIGN";
+        this.entityId = null;
+        this.href = "/emailcampaigns/campaign";
+        return this;
+    }
+
+    public CommandWrapperBuilder updateEmailCampaign(final Long resourceId) {
+        this.actionName = "UPDATE";
+        this.entityName = "EMAIL_CAMPAIGN";
+        this.entityId = resourceId;
+        this.href = "/emailcampaigns/"+resourceId;
+        return this;
+    }
+
+    public CommandWrapperBuilder deleteEmailCampaign(final Long resourceId) {
+        this.actionName = "DELETE";
+        this.entityName = "EMAIL_CAMPAIGN";
+        this.entityId = resourceId;
+        this.href = "/emailcampaigns/"+resourceId;
+        return this;
+    }
+
+    public CommandWrapperBuilder activateEmailCampaign(final Long resourceId) {
+        this.actionName = "ACTIVATE";
+        this.entityName = "EMAIL_CAMPAIGN";
+        this.entityId = resourceId;
+        this.href = "/emailcampaigns/"+resourceId + "?command=activate";
+        return this;
+    }
+
+    public CommandWrapperBuilder closeEmailCampaign(final Long resourceId) {
+        this.actionName = "CLOSE";
+        this.entityName = "EMAIL_CAMPAIGN";
+        this.entityId = resourceId;
+        this.href = "/emailcampaigns/"+resourceId + "?command=close";
+        return this;
+    }
+    public CommandWrapperBuilder reactivateEmailCampaign(final Long 
resourceId) {
+        this.actionName = "REACTIVATE";
+        this.entityName = "EMAIL_CAMPAIGN";
+        this.entityId = resourceId;
+        this.href = "/emailcampaigns/"+resourceId + "?command=reactivate";
+        return this;
+    }
+
+    public CommandWrapperBuilder updateEmailConfiguration() {
+        this.actionName = "UPDATE";
+        this.entityName = "EMAIL_CONFIGURATION";
+        this.href = "/emailcampaigns/configuration/";
         return this;
     }
 }

http://git-wip-us.apache.org/repos/asf/fineract/blob/c338c175/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/EmailApiConstants.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/EmailApiConstants.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/EmailApiConstants.java
new file mode 100644
index 0000000..1307467
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/EmailApiConstants.java
@@ -0,0 +1,54 @@
+/**
+ * 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.email;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+public class EmailApiConstants {
+
+    public static final String RESOURCE_NAME = "email";
+
+    // general
+    public static final String localeParamName = "locale";
+    public static final String dateFormatParamName = "dateFormat";
+
+    // request parameters
+    public static final String idParamName = "id";
+    public static final String groupIdParamName = "groupId";
+    public static final String clientIdParamName = "clientId";
+    public static final String staffIdParamName = "staffId";
+    public static final String subjectParamName = "emailSubject";
+    public static final String messageParamName = "emailMessage";
+
+    // response parameters
+    public static final String statusParamName = "status";
+
+    public static final Set<String> CREATE_REQUEST_DATA_PARAMETERS = new 
HashSet<>(Arrays.asList(localeParamName,
+            dateFormatParamName, groupIdParamName, clientIdParamName, 
staffIdParamName, messageParamName));
+
+    public static final Set<String> UPDATE_REQUEST_DATA_PARAMETERS = new 
HashSet<>(Arrays.asList(messageParamName));
+
+    public static final String SMTP_SERVER = "SMTP_SERVER";
+    public static final String SMTP_PORT = "SMTP_PORT";
+    public static final String SMTP_USERNAME = "SMTP_USERNAME";
+    public static final String SMTP_PASSWORD = "SMTP_PASSWORD";
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/fineract/blob/c338c175/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/ScheduledEmailConstants.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/ScheduledEmailConstants.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/ScheduledEmailConstants.java
new file mode 100644
index 0000000..950f232
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/ScheduledEmailConstants.java
@@ -0,0 +1,82 @@
+/**
+ * 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.email;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+public class ScheduledEmailConstants {
+
+    // define the API resource entity name
+    public static final String SCHEDULED_EMAIL_ENTITY_NAME = "SCHEDULEDEMAIL";
+    
+    // general API resource request parameter constants
+    public static final String LOCALE_PARAM_NAME = "locale";
+    public static final String DATE_FORMAT_PARAM_NAME = "dateFormat";
+    
+    // parameter constants for create/update entity API request
+    public static final String NAME_PARAM_NAME = "name";
+    public static final String DESCRIPTION_PARAM_NAME = "description";
+    public static final String START_DATE_TIME_PARAM_NAME = "startDateTime";
+    public static final String RECURRENCE_PARAM_NAME = "recurrence";
+    public static final String EMAIL_RECIPIENTS_PARAM_NAME = "emailRecipients";
+    public static final String EMAIL_SUBJECT_PARAM_NAME = "emailSubject";
+    public static final String EMAIL_MESSAGE_PARAM_NAME = "emailMessage";
+    public static final String EMAIL_ATTACHMENT_FILE_FORMAT_ID_PARAM_NAME = 
"emailAttachmentFileFormatId";
+    public static final String STRETCHY_REPORT_ID_PARAM_NAME = 
"stretchyReportId";
+    public static final String STRETCHY_REPORT_PARAM_MAP_PARAM_NAME = 
"stretchyReportParamMap";
+    public static final String IS_ACTIVE_PARAM_NAME = "isActive";
+    
+    // other parameter constants
+    public static final String ID_PARAM_NAME = "id";
+    public static final String EMAIL_ATTACHMENT_FILE_FORMAT_PARAM_NAME = 
"emailAttachmentFileFormat";
+    public static final String PREVIOUS_RUN_DATE_TIME_PARAM_NAME = 
"previousRunDateTime";
+    public static final String NEXT_RUN_DATE_TIME_PARAM_NAME = 
"nextRunDateTime";
+    public static final String PREVIOUS_RUN_STATUS = "previousRunStatus";
+    public static final String PREVIOUS_RUN_ERROR_LOG = "previousRunErrorLog";
+    public static final String PREVIOUS_RUN_ERROR_MESSAGE = 
"previousRunErrorMessage";
+    public static final String NUMBER_OF_RUNS = "numberOfRuns";
+    public static final String STRETCHY_REPORT_PARAM_NAME = "stretchyReport";
+    
+    // list of permitted parameters for the create report mailing job request
+    public static final Set<String> CREATE_REQUEST_PARAMETERS = new 
HashSet<>(Arrays.asList(LOCALE_PARAM_NAME, DATE_FORMAT_PARAM_NAME, 
+            NAME_PARAM_NAME, DESCRIPTION_PARAM_NAME, RECURRENCE_PARAM_NAME, 
EMAIL_RECIPIENTS_PARAM_NAME, EMAIL_SUBJECT_PARAM_NAME, 
+            EMAIL_MESSAGE_PARAM_NAME, 
EMAIL_ATTACHMENT_FILE_FORMAT_ID_PARAM_NAME, STRETCHY_REPORT_ID_PARAM_NAME, 
+            STRETCHY_REPORT_PARAM_MAP_PARAM_NAME, IS_ACTIVE_PARAM_NAME, 
START_DATE_TIME_PARAM_NAME));
+    
+    // list of permitted parameters for the update report mailing job request
+    public static final Set<String> UPDATE_REQUEST_PARAMETERS = new 
HashSet<>(Arrays.asList(LOCALE_PARAM_NAME, DATE_FORMAT_PARAM_NAME, 
+            NAME_PARAM_NAME, DESCRIPTION_PARAM_NAME, RECURRENCE_PARAM_NAME, 
EMAIL_RECIPIENTS_PARAM_NAME, EMAIL_SUBJECT_PARAM_NAME, 
+            EMAIL_MESSAGE_PARAM_NAME, 
EMAIL_ATTACHMENT_FILE_FORMAT_ID_PARAM_NAME, STRETCHY_REPORT_ID_PARAM_NAME, 
+            STRETCHY_REPORT_PARAM_MAP_PARAM_NAME, IS_ACTIVE_PARAM_NAME, 
START_DATE_TIME_PARAM_NAME));
+    
+    // list of parameters that represent the properties of a report mailing job
+    public static final Set<String> REPORT_MAILING_JOB_DATA_PARAMETERS = new 
HashSet<>(Arrays.asList(ID_PARAM_NAME, NAME_PARAM_NAME, 
+            DESCRIPTION_PARAM_NAME, RECURRENCE_PARAM_NAME, 
EMAIL_RECIPIENTS_PARAM_NAME, EMAIL_SUBJECT_PARAM_NAME, 
EMAIL_MESSAGE_PARAM_NAME, 
+            EMAIL_ATTACHMENT_FILE_FORMAT_PARAM_NAME, 
STRETCHY_REPORT_PARAM_NAME, STRETCHY_REPORT_PARAM_MAP_PARAM_NAME, 
IS_ACTIVE_PARAM_NAME, 
+            START_DATE_TIME_PARAM_NAME, PREVIOUS_RUN_DATE_TIME_PARAM_NAME, 
NEXT_RUN_DATE_TIME_PARAM_NAME, PREVIOUS_RUN_STATUS, 
+            PREVIOUS_RUN_ERROR_LOG, PREVIOUS_RUN_ERROR_MESSAGE, 
NUMBER_OF_RUNS));
+    
+    // report mailing job configuration names
+    public static final String GMAIL_SMTP_SERVER = "GMAIL_SMTP_SERVER";
+    public static final String GMAIL_SMTP_PORT = "GMAIL_SMTP_PORT";
+    public static final String GMAIL_SMTP_USERNAME = "GMAIL_SMTP_USERNAME";
+    public static final String GMAIL_SMTP_PASSWORD = "GMAIL_SMTP_PASSWORD";
+}

http://git-wip-us.apache.org/repos/asf/fineract/blob/c338c175/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/api/EmailApiResource.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/api/EmailApiResource.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/api/EmailApiResource.java
new file mode 100644
index 0000000..575ee37
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/api/EmailApiResource.java
@@ -0,0 +1,201 @@
+/**
+ * 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.email.api;
+
+import org.apache.fineract.accounting.journalentry.api.DateParam;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import 
org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
+import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import 
org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
+import 
org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
+import org.apache.fineract.infrastructure.core.service.Page;
+import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import 
org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import 
org.apache.fineract.infrastructure.campaigns.email.data.EmailConfigurationData;
+import org.apache.fineract.infrastructure.campaigns.email.data.EmailData;
+import 
org.apache.fineract.infrastructure.campaigns.email.service.EmailConfigurationReadPlatformService;
+import 
org.apache.fineract.infrastructure.campaigns.email.service.EmailReadPlatformService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+
+import javax.ws.rs.*;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+@Path("/email")
+@Consumes({ MediaType.APPLICATION_JSON })
+@Produces({ MediaType.APPLICATION_JSON })
+@Component
+@Scope("singleton")
+public class EmailApiResource {
+
+    private final String resourceNameForPermissions = "Email";
+    private final PlatformSecurityContext context;
+    private final EmailReadPlatformService readPlatformService;
+    private final DefaultToApiJsonSerializer<EmailData> toApiJsonSerializer;
+    private final ApiRequestParameterHelper apiRequestParameterHelper;
+    private final PortfolioCommandSourceWritePlatformService 
commandsSourceWritePlatformService;
+    private final EmailConfigurationReadPlatformService 
emailConfigurationReadPlatformService;
+
+    @Autowired
+    public EmailApiResource(final PlatformSecurityContext context, final 
EmailReadPlatformService readPlatformService,
+            final DefaultToApiJsonSerializer<EmailData> toApiJsonSerializer, 
final ApiRequestParameterHelper apiRequestParameterHelper,
+            final PortfolioCommandSourceWritePlatformService 
commandsSourceWritePlatformService,
+            EmailConfigurationReadPlatformService 
emailConfigurationReadPlatformService) {
+        this.context = context;
+        this.readPlatformService = readPlatformService;
+        this.toApiJsonSerializer = toApiJsonSerializer;
+        this.apiRequestParameterHelper = apiRequestParameterHelper;
+        this.commandsSourceWritePlatformService = 
commandsSourceWritePlatformService;
+        this.emailConfigurationReadPlatformService = 
emailConfigurationReadPlatformService;
+    }
+
+    @GET
+       public String retrieveAllEmails(@Context final UriInfo uriInfo) {
+
+        
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
+
+        final Collection<EmailData> emailMessages = 
this.readPlatformService.retrieveAll();
+
+        final ApiRequestJsonSerializationSettings settings = 
this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+        return this.toApiJsonSerializer.serialize(settings, emailMessages);
+    }
+
+    @GET
+    @Path("pendingEmail")
+       public String retrievePendingEmail(@QueryParam("sqlSearch") final 
String sqlSearch,
+             @QueryParam("offset") final Integer offset, @QueryParam("limit") 
final Integer limit,
+             @QueryParam("orderBy") final String orderBy, 
@QueryParam("sortOrder") final String sortOrder, @Context final UriInfo 
uriInfo) {
+
+        
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
+
+               final SearchParameters searchParameters = 
SearchParameters.forEmailCampaign(sqlSearch, offset, limit, orderBy, sortOrder);
+         Page<EmailData> emailMessages = 
this.readPlatformService.retrieveAllPending(searchParameters);
+
+        final ApiRequestJsonSerializationSettings settings = 
this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+        return this.toApiJsonSerializer.serialize(settings, emailMessages);
+    }
+    
+    @GET
+    @Path("sentEmail")
+       public String retrieveSentEmail(@QueryParam("sqlSearch") final String 
sqlSearch,
+             @QueryParam("offset") final Integer offset, @QueryParam("limit") 
final Integer limit,
+             @QueryParam("orderBy") final String orderBy, 
@QueryParam("sortOrder") final String sortOrder, @Context final UriInfo 
uriInfo) {
+
+        
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
+
+               final SearchParameters searchParameters = 
SearchParameters.forEmailCampaign(sqlSearch, offset, limit, orderBy, sortOrder);
+         Page<EmailData> emailMessages = 
this.readPlatformService.retrieveAllSent(searchParameters);
+
+        final ApiRequestJsonSerializationSettings settings = 
this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+        return this.toApiJsonSerializer.serialize(settings, emailMessages);
+    }
+
+
+    @GET
+    @Path("messageByStatus")
+       public String retrieveAllEmailByStatus(@QueryParam("sqlSearch") final 
String sqlSearch,
+             @QueryParam("offset") final Integer offset, @QueryParam("limit") 
final Integer limit,
+                        @QueryParam("status") final Long status,
+             @QueryParam("orderBy") final String orderBy, 
@QueryParam("sortOrder") final String sortOrder, 
+                        @QueryParam("fromDate") final DateParam fromDateParam, 
@QueryParam("toDate") final DateParam toDateParam,
+             @QueryParam("locale") final String locale, 
@QueryParam("dateFormat") final String dateFormat,@Context final UriInfo 
uriInfo) {
+
+        
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
+        Date fromDate = null;
+        if (fromDateParam != null) {
+            fromDate = fromDateParam.getDate("fromDate", dateFormat, locale);
+        }
+        Date toDate = null;
+        if (toDateParam != null) {
+            toDate = toDateParam.getDate("toDate", dateFormat, locale);
+        }
+
+               final SearchParameters searchParameters = 
SearchParameters.forEmailCampaign(sqlSearch, offset, limit, status, 
fromDate,toDate, orderBy, sortOrder);
+         Page<EmailData> emailMessages = 
this.readPlatformService.retrieveEmailByStatus(searchParameters);
+
+        final ApiRequestJsonSerializationSettings settings = 
this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+        return this.toApiJsonSerializer.serialize(settings, emailMessages);
+    }
+    
+    @GET
+    @Path("failedEmail")
+       public String retrieveFailedEmail(@QueryParam("sqlSearch") final String 
sqlSearch,
+             @QueryParam("offset") final Integer offset, @QueryParam("limit") 
final Integer limit,
+             @QueryParam("orderBy") final String orderBy, 
@QueryParam("sortOrder") final String sortOrder, @Context final UriInfo 
uriInfo) {
+
+        
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
+
+               final SearchParameters searchParameters = 
SearchParameters.forEmailCampaign(sqlSearch, offset, limit, orderBy, sortOrder);
+         Page<EmailData> emailMessages = 
this.readPlatformService.retrieveAllFailed(searchParameters);
+
+        final ApiRequestJsonSerializationSettings settings = 
this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+        return this.toApiJsonSerializer.serialize(settings, emailMessages);
+    }
+
+    
+    @POST
+    public String create(final String apiRequestBodyAsJson) {
+
+        final CommandWrapper commandRequest = new 
CommandWrapperBuilder().createEmail().withJson(apiRequestBodyAsJson).build();
+
+        final CommandProcessingResult result = 
this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+
+        return this.toApiJsonSerializer.serialize(result);
+    }
+
+    @GET
+    @Path("{resourceId}")
+    public String retrieveOne(@PathParam("resourceId") final Long resourceId, 
@Context final UriInfo uriInfo) {
+
+        final EmailData emailMessage = 
this.readPlatformService.retrieveOne(resourceId);
+
+        final ApiRequestJsonSerializationSettings settings = 
this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+        return this.toApiJsonSerializer.serialize(settings, emailMessage);
+    }
+
+    @PUT
+    @Path("{resourceId}")
+    public String update(@PathParam("resourceId") final Long resourceId, final 
String apiRequestBodyAsJson) {
+
+        final CommandWrapper commandRequest = new 
CommandWrapperBuilder().updateEmail(resourceId).withJson(apiRequestBodyAsJson).build();
+
+        final CommandProcessingResult result = 
this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+
+        return this.toApiJsonSerializer.serialize(result);
+    }
+
+    @DELETE
+    @Path("{resourceId}")
+    public String delete(@PathParam("resourceId") final Long resourceId) {
+
+        final CommandWrapper commandRequest = new 
CommandWrapperBuilder().deleteEmail(resourceId).build();
+
+        final CommandProcessingResult result = 
this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+
+        return this.toApiJsonSerializer.serialize(result);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/fineract/blob/c338c175/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/api/EmailCampaignApiResource.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/api/EmailCampaignApiResource.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/api/EmailCampaignApiResource.java
new file mode 100644
index 0000000..243eefc
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/api/EmailCampaignApiResource.java
@@ -0,0 +1,230 @@
+/**
+ * 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.email.api;
+
+import com.google.gson.JsonElement;
+import org.apache.commons.lang.StringUtils;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import 
org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
+import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
+import org.apache.fineract.infrastructure.core.api.JsonQuery;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import 
org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
+import 
org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.Page;
+import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import 
org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import 
org.apache.fineract.infrastructure.campaigns.email.data.PreviewCampaignMessage;
+import 
org.apache.fineract.infrastructure.campaigns.email.data.EmailBusinessRulesData;
+import 
org.apache.fineract.infrastructure.campaigns.email.data.EmailCampaignData;
+import 
org.apache.fineract.infrastructure.campaigns.email.service.EmailCampaignReadPlatformService;
+import 
org.apache.fineract.infrastructure.campaigns.email.service.EmailCampaignWritePlatformService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+
+import javax.ws.rs.*;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+import java.util.Collection;
+import java.util.HashSet;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: andrew
+ * Date: 19-5-14
+ * Time: 15:17
+ * To change this template use File | Settings | File Templates.
+ */
+@Path("/email/campaign")
+@Consumes({ MediaType.APPLICATION_JSON })
+@Produces({ MediaType.APPLICATION_JSON })
+@Component
+@Scope("singleton")
+public class EmailCampaignApiResource {
+
+
+    //change name to email campaign
+    private final String resourceNameForPermissions = "EMAIL_CAMPAIGN";
+
+    private final PlatformSecurityContext context;
+
+    private final DefaultToApiJsonSerializer<EmailBusinessRulesData> 
toApiJsonSerializer;
+
+    private final ApiRequestParameterHelper apiRequestParameterHelper;
+
+    private final EmailCampaignReadPlatformService 
emailCampaignReadPlatformService;
+    private final FromJsonHelper fromJsonHelper;
+
+
+    private final PortfolioCommandSourceWritePlatformService 
commandsSourceWritePlatformService;
+    private final DefaultToApiJsonSerializer<EmailCampaignData> 
emailCampaignDataDefaultToApiJsonSerializer;
+    private final EmailCampaignWritePlatformService 
emailCampaignWritePlatformService;
+
+    private final DefaultToApiJsonSerializer<PreviewCampaignMessage> 
previewCampaignMessageDefaultToApiJsonSerializer;
+
+
+    @Autowired
+    public EmailCampaignApiResource(final PlatformSecurityContext 
context,final DefaultToApiJsonSerializer<EmailBusinessRulesData> 
toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper,
+                                  final EmailCampaignReadPlatformService 
emailCampaignReadPlatformService, final 
PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
+                                  final 
DefaultToApiJsonSerializer<EmailCampaignData> 
emailCampaignDataDefaultToApiJsonSerializer,
+                                  final FromJsonHelper fromJsonHelper, final 
EmailCampaignWritePlatformService emailCampaignWritePlatformService,
+                                  final 
DefaultToApiJsonSerializer<PreviewCampaignMessage> 
previewCampaignMessageDefaultToApiJsonSerializer) {
+        this.context = context;
+        this.toApiJsonSerializer = toApiJsonSerializer;
+        this.apiRequestParameterHelper = apiRequestParameterHelper;
+        this.emailCampaignReadPlatformService = 
emailCampaignReadPlatformService;
+        this.commandsSourceWritePlatformService = 
commandsSourceWritePlatformService;
+        this.emailCampaignDataDefaultToApiJsonSerializer = 
emailCampaignDataDefaultToApiJsonSerializer;
+        this.fromJsonHelper = fromJsonHelper;
+        this.emailCampaignWritePlatformService = 
emailCampaignWritePlatformService;
+        this.previewCampaignMessageDefaultToApiJsonSerializer = 
previewCampaignMessageDefaultToApiJsonSerializer;
+    }
+
+
+    @GET
+    @Path("{resourceId}")
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String retrieveOneCampaign(@PathParam("resourceId") final Long 
resourceId,@Context final UriInfo uriInfo){
+        
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
+
+        EmailCampaignData emailCampaignData = 
this.emailCampaignReadPlatformService.retrieveOne(resourceId);
+        final ApiRequestJsonSerializationSettings settings = 
this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+        return 
this.emailCampaignDataDefaultToApiJsonSerializer.serialize(settings,emailCampaignData);
+
+    }
+
+    @GET
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String retrieveAllCampaign(@Context final UriInfo uriInfo) {
+
+        
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
+
+        final Collection<EmailCampaignData> emailCampaignDataCollection = 
this.emailCampaignReadPlatformService.retrieveAllCampaign();
+
+        final ApiRequestJsonSerializationSettings settings = 
this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+        return 
this.emailCampaignDataDefaultToApiJsonSerializer.serialize(settings,emailCampaignDataCollection);
+    }
+
+    @POST
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String createCampaign(final String apiRequestBodyAsJson,@Context 
final UriInfo uriInfo){
+
+        final CommandWrapper commandRequest = new 
CommandWrapperBuilder().createEmailCampaign().withJson(apiRequestBodyAsJson).build();
+
+        final CommandProcessingResult result = 
this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+
+        return this.toApiJsonSerializer.serialize(result);
+    }
+
+    @PUT
+    @Path("{resourceId}")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String updateCampaign(@PathParam("resourceId") final Long 
campaignId,final String apiRequestBodyAsJson,@Context final UriInfo uriInfo){
+
+        final CommandWrapper commandRequest = new 
CommandWrapperBuilder().updateEmailCampaign(campaignId).withJson(apiRequestBodyAsJson).build();
+
+        final CommandProcessingResult result = 
this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+
+        return this.toApiJsonSerializer.serialize(result);
+    }
+
+    @POST
+    @Path("{resourceId}")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String activate(@PathParam("resourceId") final Long campaignId, 
@QueryParam("command") final String commandParam,
+                           final String apiRequestBodyAsJson){
+        final CommandWrapperBuilder builder = new 
CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
+
+        CommandProcessingResult result = null;
+        CommandWrapper commandRequest = null;
+        if (is(commandParam, "activate")) {
+            commandRequest = builder.activateEmailCampaign(campaignId).build();
+            result = 
this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        }else if (is(commandParam, "close")){
+            commandRequest = builder.closeEmailCampaign(campaignId).build();
+            result = 
this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        }else if (is(commandParam, "reactivate")){
+            commandRequest = 
builder.reactivateEmailCampaign(campaignId).build();
+            result = 
this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        }
+        return this.toApiJsonSerializer.serialize(result);
+    }
+
+    @POST
+    @Path("preview")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String preview(final String apiRequestBodyAsJson,@Context final 
UriInfo uriInfo){
+        
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
+
+        PreviewCampaignMessage campaignMessage = null;
+        final JsonElement parsedQuery = 
this.fromJsonHelper.parse(apiRequestBodyAsJson);
+        final JsonQuery query = JsonQuery.from(apiRequestBodyAsJson, 
parsedQuery, this.fromJsonHelper);
+        campaignMessage = 
this.emailCampaignWritePlatformService.previewMessage(query);
+        final ApiRequestJsonSerializationSettings settings = 
this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+        return 
this.previewCampaignMessageDefaultToApiJsonSerializer.serialize(settings,campaignMessage,
 new HashSet<String>());
+
+    }
+
+
+    @GET()
+    @Path("template")
+    public String template(@Context final UriInfo uriInfo){
+        
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
+
+        final Collection<EmailBusinessRulesData>  
emailBusinessRulesDataCollection = 
this.emailCampaignReadPlatformService.retrieveAll();
+
+        final ApiRequestJsonSerializationSettings settings = 
this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+        return 
this.toApiJsonSerializer.serialize(settings,emailBusinessRulesDataCollection);
+    }
+
+    @GET
+    @Path("template/{resourceId}")
+    public String retrieveOneTemplate(@PathParam("resourceId") final Long 
resourceId,@Context final UriInfo uriInfo){
+        
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
+
+        final EmailBusinessRulesData emailBusinessRulesData = 
this.emailCampaignReadPlatformService.retrieveOneTemplate(resourceId);
+        final ApiRequestJsonSerializationSettings settings = 
this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+        return 
this.toApiJsonSerializer.serialize(settings,emailBusinessRulesData);
+
+    }
+
+    @DELETE
+    @Path("{resourceId}")
+    public String delete(@PathParam("resourceId") final Long resourceId) {
+
+        final CommandWrapper commandRequest = new 
CommandWrapperBuilder().deleteEmailCampaign(resourceId).build();
+
+        final CommandProcessingResult result = 
this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+
+        return this.toApiJsonSerializer.serialize(result);
+    }
+
+    private boolean is(final String commandParam, final String commandValue) {
+        return StringUtils.isNotBlank(commandParam) && 
commandParam.trim().equalsIgnoreCase(commandValue);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/fineract/blob/c338c175/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/api/EmailConfigurationApiResource.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/api/EmailConfigurationApiResource.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/api/EmailConfigurationApiResource.java
new file mode 100644
index 0000000..e956694
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/api/EmailConfigurationApiResource.java
@@ -0,0 +1,94 @@
+/**
+ * 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.email.api;
+
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import 
org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
+import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import 
org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
+import 
org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
+import 
org.apache.fineract.infrastructure.campaigns.email.data.EmailConfigurationData;
+import org.apache.fineract.infrastructure.campaigns.email.data.EmailData;
+import 
org.apache.fineract.infrastructure.campaigns.email.service.EmailConfigurationReadPlatformService;
+import 
org.apache.fineract.infrastructure.campaigns.email.service.EmailReadPlatformService;
+import 
org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+
+import javax.ws.rs.*;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+import java.util.Collection;
+
+
+@Path("/email/configuration")
+@Consumes({ MediaType.APPLICATION_JSON })
+@Produces({ MediaType.APPLICATION_JSON })
+@Component
+@Scope("singleton")
+public class EmailConfigurationApiResource {
+
+    private final String resourceNameForPermissions = "EMAIL_CONFIGURATION";
+    private final PlatformSecurityContext context;
+    private final EmailReadPlatformService readPlatformService;
+    private final DefaultToApiJsonSerializer<EmailConfigurationData> 
toApiJsonSerializer;
+    private final ApiRequestParameterHelper apiRequestParameterHelper;
+    private final PortfolioCommandSourceWritePlatformService 
commandsSourceWritePlatformService;
+    private final EmailConfigurationReadPlatformService 
emailConfigurationReadPlatformService;
+
+    @Autowired
+    public EmailConfigurationApiResource(final PlatformSecurityContext 
context, final EmailReadPlatformService readPlatformService,
+                            final 
DefaultToApiJsonSerializer<EmailConfigurationData> toApiJsonSerializer,
+                            final ApiRequestParameterHelper 
apiRequestParameterHelper,
+                            final PortfolioCommandSourceWritePlatformService 
commandsSourceWritePlatformService,
+                            final EmailConfigurationReadPlatformService 
emailConfigurationReadPlatformService) {
+        this.context = context;
+        this.readPlatformService = readPlatformService;
+        this.toApiJsonSerializer = toApiJsonSerializer;
+        this.apiRequestParameterHelper = apiRequestParameterHelper;
+        this.commandsSourceWritePlatformService = 
commandsSourceWritePlatformService;
+        this.emailConfigurationReadPlatformService = 
emailConfigurationReadPlatformService;
+    }
+
+    @GET
+    public String retrieveAll(@Context final UriInfo uriInfo){
+        
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
+
+        final Collection<EmailConfigurationData> configuration = 
this.emailConfigurationReadPlatformService.retrieveAll();
+
+        final ApiRequestJsonSerializationSettings settings = 
this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+
+        return this.toApiJsonSerializer.serialize(settings, configuration);
+    }
+
+
+    @PUT
+    public String updateConfiguration(@Context final UriInfo uriInfo, final 
String apiRequestBodyAsJson){
+
+        final CommandWrapper commandRequest = new 
CommandWrapperBuilder().updateEmailConfiguration().withJson(apiRequestBodyAsJson).build();
+
+        final CommandProcessingResult result = 
this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+
+        return this.toApiJsonSerializer.serialize(result);
+    }
+}

http://git-wip-us.apache.org/repos/asf/fineract/blob/c338c175/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/data/EmailBusinessRulesData.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/data/EmailBusinessRulesData.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/data/EmailBusinessRulesData.java
new file mode 100644
index 0000000..2d7dfb1
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/data/EmailBusinessRulesData.java
@@ -0,0 +1,96 @@
+/**
+ * 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.email.data;
+
+import java.util.Map;
+
+public class EmailBusinessRulesData {
+
+    @SuppressWarnings("unused")
+    private final Long reportId;
+
+    @SuppressWarnings("unused")
+    private final String reportName;
+
+    @SuppressWarnings("unused")
+    private final String reportType;
+
+    @SuppressWarnings("unused")
+    private final String reportSubType;
+
+    @SuppressWarnings("unused")
+    private final String reportDescription;
+
+    @SuppressWarnings("unused")
+    private final Map<String,Object> reportParamName;
+
+
+
+    public EmailBusinessRulesData(final Long reportId, final String 
reportName,final String reportType, final Map<String,Object> reportParamName,
+                                  final String reportSubType, final String 
reportDescription) {
+        this.reportId = reportId;
+        this.reportName = reportName;
+        this.reportType = reportType;
+        this.reportParamName = reportParamName;
+        this.reportDescription = reportDescription;
+        this.reportSubType = reportSubType;
+    }
+
+
+    public static EmailBusinessRulesData instance(final Long reportId, final 
String reportName, final String reportType, final Map<String,Object> 
reportParamName,
+                                                  final String reportSubType, 
final String reportDescription){
+        return new 
EmailBusinessRulesData(reportId,reportName,reportType,reportParamName,reportSubType,reportDescription);
+    }
+
+    public Map<String, Object> getReportParamName() {
+        return reportParamName;
+    }
+
+    public String getReportType() {
+        return reportType;
+    }
+
+    public String getReportName() {
+        return reportName;
+    }
+
+    public Long getReportId() {
+        return reportId;
+    }
+
+    public String getReportDescription() {
+        return reportDescription;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        EmailBusinessRulesData that = (EmailBusinessRulesData) o;
+
+        return reportId != null ? reportId.equals(that.reportId) : 
that.reportId == null;
+
+    }
+
+    @Override
+    public int hashCode() {
+        return reportId != null ? reportId.hashCode() : 0;
+    }
+}

http://git-wip-us.apache.org/repos/asf/fineract/blob/c338c175/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/data/EmailCampaignData.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/data/EmailCampaignData.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/data/EmailCampaignData.java
new file mode 100644
index 0000000..02ff74e
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/data/EmailCampaignData.java
@@ -0,0 +1,144 @@
+/**
+ * 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.email.data;
+
+import org.joda.time.DateTime;
+import org.joda.time.LocalDate;
+import org.apache.fineract.infrastructure.core.data.EnumOptionData;
+
+public class EmailCampaignData {
+
+    @SuppressWarnings("unused")
+    private Long id;
+    @SuppressWarnings("unused")
+    private final String campaignName;
+    @SuppressWarnings("unused")
+    private final Integer campaignType;
+    @SuppressWarnings("unused")
+    private final Long businessRuleId;
+    @SuppressWarnings("unused")
+    private final String paramValue;
+    @SuppressWarnings("unused")
+    private final EnumOptionData campaignStatus;
+    @SuppressWarnings("unused")
+    private final String emailSubject;
+    @SuppressWarnings("unused")
+    private final String emailMessage;
+    @SuppressWarnings("unused")
+    private final String emailAttachmentFileFormat;
+    @SuppressWarnings("unused")
+    private final Long stretchyReportId;
+    @SuppressWarnings("unused")
+    private final String stretchyReportParamMap;
+    @SuppressWarnings("unused")
+    private final DateTime nextTriggerDate;
+    @SuppressWarnings("unused")
+    private final LocalDate lastTriggerDate;
+    @SuppressWarnings("unused")
+    private final EmailCampaignTimeLine emailCampaignTimeLine;
+
+    @SuppressWarnings("unused")
+    private final DateTime recurrenceStartDate;
+
+    private final String recurrence;
+
+    private EmailCampaignData(final Long id, final String campaignName, final 
Integer campaignType, final Long businessRuleId,
+                              final String paramValue, final EnumOptionData 
campaignStatus, final String emailSubject,
+                              final String message, final String 
emailAttachmentFileFormat, final Long stretchyReportId,
+                              final String stretchyReportParamMap, final 
DateTime nextTriggerDate, final LocalDate lastTriggerDate,
+                              final EmailCampaignTimeLine 
emailCampaignTimeLine, final DateTime recurrenceStartDate, final String 
recurrence) {
+        this.id = id;
+        this.campaignName = campaignName;
+        this.campaignType = campaignType;
+        this.businessRuleId = businessRuleId;
+        this.paramValue = paramValue;
+        this.campaignStatus =campaignStatus;
+        this.emailSubject = emailSubject;
+        this.emailMessage = message;
+        this.emailAttachmentFileFormat = emailAttachmentFileFormat;
+        this.stretchyReportId = stretchyReportId;
+        this.stretchyReportParamMap = stretchyReportParamMap;
+        if(nextTriggerDate !=null){
+            this.nextTriggerDate = nextTriggerDate;
+        }else{
+            this.nextTriggerDate = null;
+        }
+        if(lastTriggerDate !=null){
+            this.lastTriggerDate = lastTriggerDate;
+        }else{
+            this.lastTriggerDate = null;
+        }
+        this.emailCampaignTimeLine =emailCampaignTimeLine;
+        this.recurrenceStartDate = recurrenceStartDate;
+        this.recurrence  = recurrence;
+    }
+
+    public static EmailCampaignData instance(final Long id, final String 
campaignName, final Integer campaignType, final Long runReportId,
+                                             final String paramValue, final 
EnumOptionData campaignStatus, final String emailSubject,
+                                             final String message, final 
String emailAttachmentFileFormat, final Long stretchyReportId,
+                                             final String 
stretchyReportParamMap, final DateTime nextTriggerDate, final LocalDate 
lastTriggerDate,
+                                             final EmailCampaignTimeLine 
emailCampaignTimeLine,
+                                             final DateTime 
recurrenceStartDate, final String recurrence){
+        return new 
EmailCampaignData(id,campaignName,campaignType,runReportId,paramValue,
+                
campaignStatus,emailSubject,message,emailAttachmentFileFormat,stretchyReportId,stretchyReportParamMap,nextTriggerDate,lastTriggerDate,emailCampaignTimeLine,recurrenceStartDate,recurrence);
+    }
+
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getCampaignName() {
+        return this.campaignName;
+    }
+
+    public Integer getCampaignType() {
+        return this.campaignType;
+    }
+
+    public Long getRunReportId() {
+        return this.businessRuleId;
+    }
+
+    public String getParamValue() {
+        return this.paramValue;
+    }
+
+    public EnumOptionData getCampaignStatus() {
+        return this.campaignStatus;
+    }
+
+    public String getEmailSubject() { return this.emailSubject; }
+
+    public String getMessage() {
+        return this.emailMessage;
+    }
+
+    public DateTime getNextTriggerDate() {
+        return this.nextTriggerDate;
+    }
+
+    public LocalDate getLastTriggerDate() {
+        return this.lastTriggerDate;
+    }
+
+    public String getRecurrence() {return this.recurrence;}
+
+    public DateTime getRecurrenceStartDate() {return this.recurrenceStartDate;}
+}

http://git-wip-us.apache.org/repos/asf/fineract/blob/c338c175/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/data/EmailCampaignTimeLine.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/data/EmailCampaignTimeLine.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/data/EmailCampaignTimeLine.java
new file mode 100644
index 0000000..9204626
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/data/EmailCampaignTimeLine.java
@@ -0,0 +1,40 @@
+/**
+ * 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.email.data;
+
+import org.joda.time.LocalDate;
+
+public class EmailCampaignTimeLine {
+    private final LocalDate submittedOnDate;
+    private final String submittedByUsername;
+    private final LocalDate activatedOnDate;
+    private final String activatedByUsername;
+    private final LocalDate closedOnDate;
+    private final String closedByUsername;
+
+    public EmailCampaignTimeLine(final LocalDate submittedOnDate, final String 
submittedByUsername,
+                                 final LocalDate activatedOnDate, final String 
activatedByUsername, final LocalDate closedOnDate, final String 
closedByUsername) {
+        this.submittedOnDate = submittedOnDate;
+        this.submittedByUsername = submittedByUsername;
+        this.activatedOnDate = activatedOnDate;
+        this.activatedByUsername = activatedByUsername;
+        this.closedOnDate = closedOnDate;
+        this.closedByUsername = closedByUsername;
+    }
+}

http://git-wip-us.apache.org/repos/asf/fineract/blob/c338c175/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/data/EmailCampaignValidator.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/data/EmailCampaignValidator.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/data/EmailCampaignValidator.java
new file mode 100644
index 0000000..d85f386
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/data/EmailCampaignValidator.java
@@ -0,0 +1,259 @@
+/**
+ * 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.email.data;
+
+import com.google.gson.JsonElement;
+import com.google.gson.reflect.TypeToken;
+import org.apache.commons.lang.StringUtils;
+import org.joda.time.LocalDate;
+import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
+import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
+import 
org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import 
org.apache.fineract.infrastructure.campaigns.email.domain.EmailCampaignType;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.lang.reflect.Type;
+import java.util.*;
+
+@Component
+public class EmailCampaignValidator {
+
+   
+
+    public static final String RESOURCE_NAME = "email";
+    public static final String campaignName  = "campaignName";
+    public static final String campaignType = "campaignType";
+    public static final String businessRuleId = "businessRuleId";
+    public static final String stretchyReportId = "stretchyReportId";
+    public static final String stretchyReportParamMap = 
"stretchyReportParamMap";
+    public static final String paramValue = "paramValue";
+    public static final String emailSubject = "emailSubject";
+    public static final String emailMessage   = "emailMessage";
+    public static final String emailAttachmentFileFormatId = 
"emailAttachmentFileFormatId";
+    public static final String activationDateParamName = "activationDate";
+    public static final String recurrenceStartDate = "recurrenceStartDate";
+    public static final String submittedOnDateParamName = "submittedOnDate";
+    public static final String closureDateParamName = "closureDate";
+    public static final String recurrenceParamName = "recurrence";
+    public static final String statusParamName = "status";
+
+    public static final String localeParamName = "locale";
+    public static final String dateFormatParamName = "dateFormat";
+
+
+    private final FromJsonHelper fromApiJsonHelper;
+
+
+    public static final Set<String> supportedParams = new 
HashSet<String>(Arrays.asList(campaignName, 
campaignType,localeParamName,dateFormatParamName,
+            
businessRuleId,paramValue,emailMessage,recurrenceStartDate,activationDateParamName,submittedOnDateParamName,closureDateParamName,recurrenceParamName,
+            
emailSubject,stretchyReportId,stretchyReportParamMap,emailAttachmentFileFormatId));
+
+    public static final Set<String> supportedParamsForUpdate = new 
HashSet<>(Arrays.asList(campaignName, 
campaignType,localeParamName,dateFormatParamName,
+            
businessRuleId,paramValue,emailMessage,recurrenceStartDate,activationDateParamName,recurrenceParamName));
+
+    public static final Set<String> ACTIVATION_REQUEST_DATA_PARAMETERS = new 
HashSet<String>(Arrays.asList(localeParamName,
+            dateFormatParamName, activationDateParamName));
+
+    public static final Set<String> CLOSE_REQUEST_DATA_PARAMETERS = new 
HashSet<String>(Arrays.asList(localeParamName,
+            dateFormatParamName, closureDateParamName));
+
+    public static final Set<String> PREVIEW_REQUEST_DATA_PARAMETERS= new 
HashSet<String>(Arrays.asList(paramValue,emailMessage));
+
+    @Autowired
+    public EmailCampaignValidator(FromJsonHelper fromApiJsonHelper) {
+        this.fromApiJsonHelper = fromApiJsonHelper;
+    }
+
+
+    public void validateCreate(String json){
+        if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
+
+        final Type typeOfMap = new TypeToken<Map<String, Object>>() 
{}.getType();
+        this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, 
EmailCampaignValidator.supportedParams);
+        
+        final JsonElement element = this.fromApiJsonHelper.parse(json);
+
+        final List<ApiParameterError> dataValidationErrors = new 
ArrayList<ApiParameterError>();
+
+        final DataValidatorBuilder baseDataValidator = new 
DataValidatorBuilder(dataValidationErrors)
+                .resource(EmailCampaignValidator.RESOURCE_NAME);
+        
+        final String campaignName =  
this.fromApiJsonHelper.extractStringNamed(EmailCampaignValidator.campaignName,element);
+        
baseDataValidator.reset().parameter(EmailCampaignValidator.campaignName).value(campaignName).notBlank().notExceedingLengthOf(100);
+        
+        
+        final Long campaignType = 
this.fromApiJsonHelper.extractLongNamed(EmailCampaignValidator.campaignType,element);
+        
baseDataValidator.reset().parameter(EmailCampaignValidator.campaignType).value(campaignType).notNull().integerGreaterThanZero();
+
+        if(campaignType.intValue() == EmailCampaignType.SCHEDULE.getValue()){
+            final String recurrenceParamName =  
this.fromApiJsonHelper.extractStringNamed(EmailCampaignValidator.recurrenceParamName,
 element);
+            
baseDataValidator.reset().parameter(EmailCampaignValidator.recurrenceParamName).value(recurrenceParamName).notBlank();
+
+            final String recurrenceStartDate =  
this.fromApiJsonHelper.extractStringNamed(EmailCampaignValidator.recurrenceStartDate,
 element);
+            
baseDataValidator.reset().parameter(EmailCampaignValidator.recurrenceStartDate).value(recurrenceStartDate).notBlank();
+        }
+
+        final Long businessRuleId = 
this.fromApiJsonHelper.extractLongNamed(EmailCampaignValidator.businessRuleId,element);
+        
baseDataValidator.reset().parameter(EmailCampaignValidator.businessRuleId).value(businessRuleId).notNull().integerGreaterThanZero();
+
+               final String emailSubject = 
this.fromApiJsonHelper.extractStringNamed(EmailCampaignValidator.emailSubject, 
element);
+        
baseDataValidator.reset().parameter(EmailCampaignValidator.emailSubject).value(emailSubject).notBlank().notExceedingLengthOf(50);
+               
+        final String emailMessage = 
this.fromApiJsonHelper.extractStringNamed(EmailCampaignValidator.emailMessage, 
element);
+        
baseDataValidator.reset().parameter(EmailCampaignValidator.emailMessage).value(emailMessage).notBlank().notExceedingLengthOf(480);
+
+        final String paramValue = 
this.fromApiJsonHelper.extractStringNamed(EmailCampaignValidator.paramValue, 
element);
+        
baseDataValidator.reset().parameter(EmailCampaignValidator.paramValue).value(paramValue).notBlank();
+
+
+
+        if 
(this.fromApiJsonHelper.parameterExists(EmailCampaignValidator.submittedOnDateParamName,
 element)) {
+            final LocalDate submittedOnDate = 
this.fromApiJsonHelper.extractLocalDateNamed(EmailCampaignValidator.submittedOnDateParamName,
+                    element);
+            
baseDataValidator.reset().parameter(EmailCampaignValidator.submittedOnDateParamName).value(submittedOnDate).notNull();
+        }
+
+
+
+        throwExceptionIfValidationWarningsExist(dataValidationErrors);
+
+    }
+
+    public void validateForUpdate(String json){
+        if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
+        final Type typeOfMap = new TypeToken<Map<String, Object>>() 
{}.getType();
+        this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, 
EmailCampaignValidator.supportedParamsForUpdate);
+        final JsonElement element = this.fromApiJsonHelper.parse(json);
+
+        final List<ApiParameterError> dataValidationErrors = new 
ArrayList<ApiParameterError>();
+
+        final DataValidatorBuilder baseDataValidator = new 
DataValidatorBuilder(dataValidationErrors)
+                .resource(EmailCampaignValidator.RESOURCE_NAME);
+
+        final String campaignName =  
this.fromApiJsonHelper.extractStringNamed(EmailCampaignValidator.campaignName,element);
+        
baseDataValidator.reset().parameter(EmailCampaignValidator.campaignName).value(campaignName).notBlank().notExceedingLengthOf(100);
+
+
+        final Long campaignType = 
this.fromApiJsonHelper.extractLongNamed(EmailCampaignValidator.campaignType,element);
+        
baseDataValidator.reset().parameter(EmailCampaignValidator.campaignType).value(campaignType).notNull().integerGreaterThanZero();
+
+        if(campaignType.intValue() == EmailCampaignType.SCHEDULE.getValue()){
+            final String recurrenceParamName =  
this.fromApiJsonHelper.extractStringNamed(EmailCampaignValidator.recurrenceParamName,
 element);
+            
baseDataValidator.reset().parameter(EmailCampaignValidator.recurrenceParamName).value(recurrenceParamName).notBlank();
+
+            final String recurrenceStartDate =  
this.fromApiJsonHelper.extractStringNamed(EmailCampaignValidator.recurrenceStartDate,
 element);
+            
baseDataValidator.reset().parameter(EmailCampaignValidator.recurrenceStartDate).value(recurrenceStartDate).notBlank();
+        }
+
+        final Long runReportId = 
this.fromApiJsonHelper.extractLongNamed(EmailCampaignValidator.businessRuleId,element);
+        
baseDataValidator.reset().parameter(EmailCampaignValidator.businessRuleId).value(runReportId).notNull().integerGreaterThanZero();
+
+        final String message = 
this.fromApiJsonHelper.extractStringNamed(EmailCampaignValidator.emailMessage, 
element);
+        
baseDataValidator.reset().parameter(EmailCampaignValidator.emailMessage).value(message).notBlank().notExceedingLengthOf(480);
+
+        final String paramValue = 
this.fromApiJsonHelper.extractStringNamed(EmailCampaignValidator.paramValue, 
element);
+        
baseDataValidator.reset().parameter(EmailCampaignValidator.paramValue).value(paramValue).notBlank();
+
+        throwExceptionIfValidationWarningsExist(dataValidationErrors);
+
+
+    }
+
+    public void validatePreviewMessage(String json){
+        if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
+        final Type typeOfMap = new TypeToken<Map<String, Object>>() 
{}.getType();
+        this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, 
EmailCampaignValidator.PREVIEW_REQUEST_DATA_PARAMETERS);
+
+        final JsonElement element = this.fromApiJsonHelper.parse(json);
+
+        final List<ApiParameterError> dataValidationErrors = new 
ArrayList<ApiParameterError>();
+        final DataValidatorBuilder baseDataValidator = new 
DataValidatorBuilder(dataValidationErrors)
+                .resource(EmailCampaignValidator.RESOURCE_NAME);
+
+        final String paramValue = 
this.fromApiJsonHelper.extractStringNamed(EmailCampaignValidator.paramValue, 
element);
+        
baseDataValidator.reset().parameter(EmailCampaignValidator.paramValue).value(paramValue).notBlank();
+
+        final String message = 
this.fromApiJsonHelper.extractStringNamed(EmailCampaignValidator.emailMessage, 
element);
+        
baseDataValidator.reset().parameter(EmailCampaignValidator.emailMessage).value(message).notBlank().notExceedingLengthOf(480);
+
+        throwExceptionIfValidationWarningsExist(dataValidationErrors);
+
+
+    }
+
+    public void validateClosedDate(String json){
+        if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
+
+        final Type typeOfMap = new TypeToken<Map<String, Object>>() 
{}.getType();
+        this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, 
EmailCampaignValidator.CLOSE_REQUEST_DATA_PARAMETERS);
+
+        final List<ApiParameterError> dataValidationErrors = new 
ArrayList<ApiParameterError>();
+        final DataValidatorBuilder baseDataValidator = new 
DataValidatorBuilder(dataValidationErrors)
+                .resource(EmailCampaignValidator.RESOURCE_NAME);
+
+        final JsonElement element = this.fromApiJsonHelper.parse(json);
+
+        final LocalDate closeDate = 
this.fromApiJsonHelper.extractLocalDateNamed(EmailCampaignValidator.closureDateParamName,
 element);
+        
baseDataValidator.reset().parameter(EmailCampaignValidator.closureDateParamName).value(closeDate).notNull();
+
+        throwExceptionIfValidationWarningsExist(dataValidationErrors);
+    }
+    public void validateActivation(String json){
+        if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
+
+        final Type typeOfMap = new TypeToken<Map<String, Object>>() 
{}.getType();
+        this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, 
EmailCampaignValidator.ACTIVATION_REQUEST_DATA_PARAMETERS);
+
+        final List<ApiParameterError> dataValidationErrors = new 
ArrayList<ApiParameterError>();
+        final DataValidatorBuilder baseDataValidator = new 
DataValidatorBuilder(dataValidationErrors)
+                .resource(EmailCampaignValidator.RESOURCE_NAME);
+
+        final JsonElement element = this.fromApiJsonHelper.parse(json);
+
+        final LocalDate activationDate = 
this.fromApiJsonHelper.extractLocalDateNamed(EmailCampaignValidator.activationDateParamName,
 element);
+        
baseDataValidator.reset().parameter(EmailCampaignValidator.activationDateParamName).value(activationDate).notNull();
+
+        throwExceptionIfValidationWarningsExist(dataValidationErrors);
+    }
+
+    public void ValidateClosure(String json){
+        if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
+
+        final Type typeOfMap = new TypeToken<Map<String, Object>>() 
{}.getType();
+        this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, 
EmailCampaignValidator.CLOSE_REQUEST_DATA_PARAMETERS);
+
+        final List<ApiParameterError> dataValidationErrors = new 
ArrayList<ApiParameterError>();
+        final DataValidatorBuilder baseDataValidator = new 
DataValidatorBuilder(dataValidationErrors)
+                .resource(EmailCampaignValidator.RESOURCE_NAME);
+
+        final JsonElement element = this.fromApiJsonHelper.parse(json);
+
+        final LocalDate closeDate = 
this.fromApiJsonHelper.extractLocalDateNamed(EmailCampaignValidator.closureDateParamName,
 element);
+        
baseDataValidator.reset().parameter(EmailCampaignValidator.closureDateParamName).value(closeDate).notNull();
+
+        throwExceptionIfValidationWarningsExist(dataValidationErrors);
+    }
+
+    private void throwExceptionIfValidationWarningsExist(final 
List<ApiParameterError> dataValidationErrors) {
+        if (!dataValidationErrors.isEmpty()) { throw new 
PlatformApiDataValidationException(dataValidationErrors); }
+    }
+}

http://git-wip-us.apache.org/repos/asf/fineract/blob/c338c175/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/data/EmailConfigurationData.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/data/EmailConfigurationData.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/data/EmailConfigurationData.java
new file mode 100644
index 0000000..6d005ea
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/data/EmailConfigurationData.java
@@ -0,0 +1,63 @@
+/**
+ * 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.email.data;
+
+/**
+ * Immutable data object representing an Email configuration.
+ */
+public class EmailConfigurationData {
+       @SuppressWarnings("unused")
+       private final Long id;
+       
+       private final String name;
+       
+    private final String value;
+       
+       /** 
+        * @return an instance of the EmailConfigurationData class
+        **/
+       public static EmailConfigurationData instance(Long id, String name, 
String value) {
+               return new EmailConfigurationData(id, name, value);
+       }
+       
+       /** 
+        * EmailConfigurationData constructor
+        **/
+       private EmailConfigurationData(Long id, String name, String value) {
+               this.id = id;
+               this.name = name;
+               this.value = value;
+       }
+
+       /**
+        * @return the id
+        */
+       public Long getId() {
+               return id;
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public String getValue() {
+               return value;
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/fineract/blob/c338c175/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/data/EmailConfigurationValidator.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/data/EmailConfigurationValidator.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/data/EmailConfigurationValidator.java
new file mode 100644
index 0000000..3bb267e
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/data/EmailConfigurationValidator.java
@@ -0,0 +1,111 @@
+/**
+ * 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.email.data;
+
+import com.google.gson.JsonElement;
+import com.google.gson.reflect.TypeToken;
+import org.apache.commons.lang.StringUtils;
+import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
+import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
+import 
org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.campaigns.email.EmailApiConstants;
+import 
org.apache.fineract.infrastructure.campaigns.email.exception.EmailConfigurationSMTPUsernameNotValid;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.lang.reflect.Type;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+@Component
+public class EmailConfigurationValidator {
+
+    private final FromJsonHelper fromApiJsonHelper;
+
+    private static final String EMAIL_REGEX = 
"^[\\w!#$%&’*+/=?`{|}~^-]+(?:\\.[\\w!#$%&’*+/=?`{|}~^-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,6}$";
+    private static final Pattern EMAIL_PATTERN = Pattern.compile(EMAIL_REGEX);
+
+    public static final Set<String> supportedParams = new 
HashSet<String>(Arrays.asList(EmailApiConstants.SMTP_PORT,EmailApiConstants.SMTP_PASSWORD,
+            EmailApiConstants.SMTP_USERNAME,EmailApiConstants.SMTP_SERVER));
+
+    @Autowired
+    private EmailConfigurationValidator(final FromJsonHelper 
fromApiJsonHelper) {
+        this.fromApiJsonHelper = fromApiJsonHelper;
+    }
+
+
+
+    public void validateUpdateConfiguration(String json){
+
+        if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
+
+        final Type typeOfMap = new TypeToken<Map<String, Object>>() 
{}.getType();
+        this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, 
EmailConfigurationValidator.supportedParams);
+        final JsonElement element = this.fromApiJsonHelper.parse(json);
+
+        final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
+
+        final DataValidatorBuilder baseDataValidator = new 
DataValidatorBuilder(dataValidationErrors)
+                .resource(EmailApiConstants.RESOURCE_NAME);
+
+        final String smtpUsername = 
this.fromApiJsonHelper.extractStringNamed(EmailApiConstants.SMTP_USERNAME,element);
+        
baseDataValidator.reset().parameter(EmailApiConstants.SMTP_USERNAME).value(smtpUsername).notBlank().notExceedingLengthOf(150);
+
+
+        final String smtpPassword = 
this.fromApiJsonHelper.extractStringNamed(EmailApiConstants.SMTP_PASSWORD,element);
+        
baseDataValidator.reset().parameter(EmailApiConstants.SMTP_PASSWORD).value(smtpPassword).notBlank().notExceedingLengthOf(50);
+
+        final String smtpServer = 
this.fromApiJsonHelper.extractStringNamed(EmailApiConstants.SMTP_SERVER,element);
+        
baseDataValidator.reset().parameter(EmailApiConstants.SMTP_SERVER).value(smtpServer).notBlank().notExceedingLengthOf(100);
+
+        final Long smtpPort = 
this.fromApiJsonHelper.extractLongNamed(EmailApiConstants.SMTP_PORT,element);
+        
baseDataValidator.reset().parameter(EmailApiConstants.SMTP_PORT).value(smtpPort).notNull().integerGreaterThanZero();
+
+        this.throwExceptionIfValidationWarningsExist(dataValidationErrors);
+
+
+
+    }
+
+    private void throwExceptionIfValidationWarningsExist(final 
List<ApiParameterError> dataValidationErrors) {
+        if (!dataValidationErrors.isEmpty()) { throw new 
PlatformApiDataValidationException(dataValidationErrors); }
+    }
+
+    public boolean isValidEmail(String email) {
+        // this is the easiest check
+        if (email == null) {
+            return false;
+        }else if (email.endsWith(".")) {
+            return false;
+        }
+
+        // Check the whole email address structure
+        Matcher emailMatcher = EMAIL_PATTERN.matcher(email);
+
+        // check if the Matcher matches the email pattern
+        if (!emailMatcher.matches()) {
+            return false;
+        }
+
+        return true;
+    }
+}

Reply via email to