Added Notification Module

Added Notification Module

Added Notification Module

Added Notification Module

Added license file for jar analyzer

Added entry into LICENSE_RELEASE file

Added gradle wrapper
This commit is contained in:
Adhyan
2017-08-20 21:21:24 +05:30
parent 455ef98276
commit c60c6601c0
51 changed files with 2810 additions and 24 deletions
@@ -37,6 +37,7 @@ import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
import org.apache.fineract.infrastructure.security.data.PlatformRequestLog;
import org.apache.fineract.infrastructure.security.exception.InvalidTenantIdentiferException;
import org.apache.fineract.infrastructure.security.service.BasicAuthTenantDetailsService;
import org.apache.fineract.notification.service.NotificationReadPlatformService;
import org.apache.fineract.useradministration.domain.AppUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -77,7 +78,7 @@ public class TenantAwareBasicAuthenticationFilter extends BasicAuthenticationFil
private final ToApiJsonSerializer<PlatformRequestLog> toApiJsonSerializer;
private final ConfigurationDomainService configurationDomainService;
private final CacheWritePlatformService cacheWritePlatformService;
private final NotificationReadPlatformService notificationReadPlatformService;
private final String tenantRequestHeader = "Fineract-Platform-TenantId";
private final boolean exceptionIfHeaderMissing = true;
@@ -85,12 +86,14 @@ public class TenantAwareBasicAuthenticationFilter extends BasicAuthenticationFil
public TenantAwareBasicAuthenticationFilter(final AuthenticationManager authenticationManager,
final AuthenticationEntryPoint authenticationEntryPoint, final BasicAuthTenantDetailsService basicAuthTenantDetailsService,
final ToApiJsonSerializer<PlatformRequestLog> toApiJsonSerializer, final ConfigurationDomainService configurationDomainService,
final CacheWritePlatformService cacheWritePlatformService) {
final CacheWritePlatformService cacheWritePlatformService,
final NotificationReadPlatformService notificationReadPlatformService) {
super(authenticationManager, authenticationEntryPoint);
this.basicAuthTenantDetailsService = basicAuthTenantDetailsService;
this.toApiJsonSerializer = toApiJsonSerializer;
this.configurationDomainService = configurationDomainService;
this.cacheWritePlatformService = cacheWritePlatformService;
this.notificationReadPlatformService = notificationReadPlatformService;
}
@Override
@@ -167,6 +170,12 @@ public class TenantAwareBasicAuthenticationFilter extends BasicAuthenticationFil
throws IOException {
super.onSuccessfulAuthentication(request, response, authResult);
AppUser user = (AppUser) authResult.getPrincipal();
if (notificationReadPlatformService.hasUnreadNotifications(user.getId())) {
response.addHeader("X-Notification-Refresh", "true");
} else {
response.addHeader("X-Notification-Refresh", "false");
}
String pathURL = request.getRequestURI();
boolean isSelfServiceRequest = (pathURL != null && pathURL.contains("/self/"));
@@ -0,0 +1,89 @@
/**
* 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.notification.api;
import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.apache.fineract.infrastructure.core.serialization.ToApiJsonSerializer;
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.notification.data.NotificationData;
import org.apache.fineract.notification.service.NotificationReadPlatformService;
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;
@Path("/notifications")
@Component
@Scope("singleton")
public class NotificationApiResource {
private final PlatformSecurityContext context;
private final NotificationReadPlatformService notificationReadPlatformService;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final ToApiJsonSerializer<NotificationData> toApiJsonSerializer;
@Autowired
public NotificationApiResource(PlatformSecurityContext context,
NotificationReadPlatformService notificationReadPlatformService,
ApiRequestParameterHelper apiRequestParameterHelper,
ToApiJsonSerializer<NotificationData> toApiJsonSerializer) {
this.context = context;
this.notificationReadPlatformService = notificationReadPlatformService;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.toApiJsonSerializer = toApiJsonSerializer;
}
@GET
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public String getAllNotifications(@Context final UriInfo uriInfo, @QueryParam("orderBy") final String orderBy,
@QueryParam("limit") final Integer limit,
@QueryParam("offset") final Integer offset,
@QueryParam("sortOrder") final String sortOrder,
@QueryParam("isRead") final boolean isRead) {
this.context.authenticatedUser();
final Page<NotificationData> notificationData;
final SearchParameters searchParameters = SearchParameters.forPagination(offset, limit, orderBy, sortOrder);
if (!isRead) {
notificationData = this.notificationReadPlatformService.getAllUnreadNotifications(searchParameters);
} else {
notificationData = this.notificationReadPlatformService.getAllNotifications(searchParameters);
}
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper
.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, notificationData);
}
@PUT
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public void update() {
this.context.authenticatedUser();
this.notificationReadPlatformService.updateNotificationReadStatus();
}
}
@@ -0,0 +1,50 @@
/**
* 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.notification.cache;
public class CacheNotificationResponseHeader {
private boolean hasNotifications;
private Long lastFetch;
public CacheNotificationResponseHeader() {
}
public CacheNotificationResponseHeader(boolean hasNotifications, Long lastFetch) {
this.hasNotifications = hasNotifications;
this.lastFetch = lastFetch;
}
public boolean hasNotifications() {
return hasNotifications;
}
public void setHasNotifications(boolean hasNotifications) {
this.hasNotifications = hasNotifications;
}
public Long getLastFetch() {
return lastFetch;
}
public void setLastFetch(Long lastFetch) {
this.lastFetch = lastFetch;
}
}
@@ -0,0 +1,143 @@
/**
* 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.notification.data;
import java.io.Serializable;
import java.util.List;
public class NotificationData implements Serializable {
private Long id;
private String objectType;
private Long objectId;
private String action;
private Long actorId;
private String content;
private boolean isSystemGenerated;
private String tenantIdentifier;
private String createdAt;
private Long officeId;
private List<Long> userIds;
public NotificationData() {
}
public NotificationData(String objectType, Long objectId, String action, Long actorId, String content, boolean isSystemGenerated,
String tenantIdentifier, Long officeId, List<Long> userIds) {
this.objectType = objectType;
this.objectId = objectId;
this.action = action;
this.actorId = actorId;
this.content = content;
this.isSystemGenerated = isSystemGenerated;
this.tenantIdentifier = tenantIdentifier;
this.officeId = officeId;
this.userIds = userIds;
}
public Long getOfficeId() {
return officeId;
}
public void setOfficeId(Long officeId) {
this.officeId = officeId;
}
public List<Long> getUserIds() {
return userIds;
}
public void setUserId(List<Long> userIds) {
this.userIds = userIds;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCreatedAt() {
return createdAt;
}
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}
public String getObjectType() {
return objectType;
}
public void setObjectType(String objectType) {
this.objectType = objectType;
}
public Long getObjectIdentfier() {
return objectId;
}
public void entifier(Long objectIdentifier) {
this.objectId = objectIdentifier;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public Long getActor() {
return actorId;
}
public void setActor(Long actorId) {
this.actorId = actorId;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public boolean isSystemGenerated() {
return isSystemGenerated;
}
public void setSystemGenerated(boolean systemGenerated) {
isSystemGenerated = systemGenerated;
}
public String getTenantIdentifier() {
return tenantIdentifier;
}
public void setTenantIdentifier(String tenantIdentifier) {
this.tenantIdentifier = tenantIdentifier;
}
}
@@ -0,0 +1,78 @@
/**
* 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.notification.data;
public class NotificationMapperData {
private Long id;
private Long notificationId;
private Long userId;
private boolean isRead;
private String createdAt;
public NotificationMapperData(Long id, Long notificationId, Long userId, boolean isRead, String createdAt) {
this.id = id;
this.notificationId = notificationId;
this.userId = userId;
this.isRead = isRead;
this.createdAt = createdAt;
}
public NotificationMapperData() {}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getNotificationId() {
return notificationId;
}
public void setNotificationId(Long notificationId) {
this.notificationId = notificationId;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public boolean isRead() {
return isRead;
}
public void setRead(boolean read) {
isRead = read;
}
public String getCreatedAt() {
return createdAt;
}
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}
}
@@ -0,0 +1,112 @@
/**
* 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.notification.domain;
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name = "notification_generator")
public class Notification extends AbstractPersistableCustom<Long> {
@Column(name = "object_type")
private String objectType;
@Column(name = "object_identifier")
private Long objectIdentifier;
@Column(name = "action")
private String action;
@Column(name = "actor")
private Long actorId;
@Column(name = "is_system_generated")
private boolean isSystemGenerated;
@Column(name = "notification_content")
private String notificationContent;
@Column(name = "created_at")
private String createdAt;
public Notification() {}
public Notification(String objectType, Long objectIdentifier, String action, Long actorId, boolean isSystemGenerated,
String notificationContent, String createdAt) {
this.objectType = objectType;
this.objectIdentifier = objectIdentifier;
this.action = action;
this.actorId = actorId;
this.isSystemGenerated = isSystemGenerated;
this.notificationContent = notificationContent;
this.createdAt = createdAt;
}
public String getObjectType() {
return objectType;
}
public void setObjectType(String objectType) {
this.objectType = objectType;
}
public Long getObjectIdentifier() {
return objectIdentifier;
}
public void setObjectIdentifier(Long objectIdentifier) {
this.objectIdentifier = objectIdentifier;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public Long getActor() {
return actorId;
}
public void setActor(Long actor) {
this.actorId = actorId;
}
public boolean isSystemGenerated() {
return isSystemGenerated;
}
public void setSystemGenerated(boolean systemGenerated) {
isSystemGenerated = systemGenerated;
}
public String getNotificationContent() {
return notificationContent;
}
public void setNotificationContent(String notificationContent) {
this.notificationContent = notificationContent;
}
}
@@ -0,0 +1,78 @@
/**
* 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.notification.domain;
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
import org.apache.fineract.useradministration.domain.AppUser;
import javax.persistence.*;
@Entity
@Table(name = "notification_mapper")
public class NotificationMapper extends AbstractPersistableCustom<Long> {
@ManyToOne
@JoinColumn(name = "notification_id")
private Notification notification;
@ManyToOne
@JoinColumn(name = "user_id")
private AppUser userId;
@Column(name = "is_read")
private boolean isRead;
@Column(name = "created_at")
private String createdAt;
public NotificationMapper() {}
public NotificationMapper(Notification notification, AppUser userId, boolean isRead, String createdAt) {
this.notification = notification;
this.userId = userId;
this.isRead = isRead;
this.createdAt = createdAt;
}
public Notification getNotification() {
return notification;
}
public void setNotification(Notification notification) {
this.notification = notification;
}
public AppUser getUserId() {
return userId;
}
public void setUserId(AppUser userId) {
this.userId = userId;
}
public boolean isRead() {
return isRead;
}
public void setRead(boolean read) {
isRead = read;
}
}
@@ -0,0 +1,24 @@
/**
* 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.notification.domain;
import org.springframework.data.jpa.repository.JpaRepository;
public interface NotificationMapperRepository extends JpaRepository<NotificationMapper, Long> {}
@@ -0,0 +1,24 @@
/**
* 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.notification.domain;
import org.springframework.data.jpa.repository.JpaRepository;
public interface NotificationRepository extends JpaRepository<Notification, Long> {}
@@ -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.notification.eventandlistener;
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
import org.apache.fineract.infrastructure.security.service.BasicAuthTenantDetailsService;
import org.apache.fineract.notification.data.NotificationData;
import org.apache.fineract.notification.service.NotificationWritePlatformService;
import org.apache.fineract.useradministration.domain.AppUser;
import org.apache.fineract.useradministration.domain.AppUserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.listener.SessionAwareMessageListener;
import org.springframework.stereotype.Service;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@Service
public class NotificationEventListener implements SessionAwareMessageListener {
private final BasicAuthTenantDetailsService basicAuthTenantDetailsService;
private final NotificationWritePlatformService notificationWritePlatformService;
private final AppUserRepository appUserRepository;
@Autowired
public NotificationEventListener(BasicAuthTenantDetailsService basicAuthTenantDetailsService,
NotificationWritePlatformService notificationWritePlatformService,
AppUserRepository appUserRepository) {
this.basicAuthTenantDetailsService = basicAuthTenantDetailsService;
this.notificationWritePlatformService = notificationWritePlatformService;
this.appUserRepository = appUserRepository;
}
@Override
public void onMessage(Message message, Session session) throws JMSException {
if (message instanceof ObjectMessage) {
NotificationData notificationData = (NotificationData) ((ObjectMessage) message).getObject();
final FineractPlatformTenant tenant = this.basicAuthTenantDetailsService
.loadTenantById(notificationData.getTenantIdentifier(), false);
ThreadLocalContextUtil.setTenant(tenant);
Long appUserId = notificationData.getActor();
List<Long> userIds = notificationData.getUserIds();
if (notificationData.getOfficeId() != null) {
List<Long> tempUserIds = new ArrayList<>(userIds);
for (Long userId : tempUserIds) {
AppUser appUser = appUserRepository.findOne(userId);
if (!Objects.equals(appUser.getOffice().getId(), notificationData.getOfficeId())) {
userIds.remove(userId);
}
}
}
if (userIds.contains(appUserId)) {
userIds.remove(appUserId);
}
notificationWritePlatformService.notify(
userIds,
notificationData.getObjectType(),
notificationData.getObjectIdentfier(),
notificationData.getAction(),
notificationData.getActor(),
notificationData.getContent(),
notificationData.isSystemGenerated()
);
}
}
}
@@ -0,0 +1,50 @@
/**
* 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.notification.eventandlistener;
import org.apache.fineract.notification.data.NotificationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Service;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
@Service
public class NotificationEventService {
private final JmsTemplate jmsTemplate;
@Autowired
public NotificationEventService(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}
public void broadcastNotification(final Destination destination, final NotificationData notificationData) {
this.jmsTemplate.send(destination, new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
return session.createObjectMessage(notificationData);
}
});
}
}
@@ -0,0 +1,23 @@
/**
* 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.notification.service;
public interface NotificationDomainService {
}
@@ -0,0 +1,590 @@
/**
* 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.notification.service;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.notification.data.NotificationData;
import org.apache.fineract.notification.eventandlistener.NotificationEventService;
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.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
import org.apache.fineract.portfolio.savings.DepositAccountType;
import org.apache.fineract.portfolio.savings.domain.FixedDepositAccount;
import org.apache.fineract.portfolio.savings.domain.RecurringDepositAccount;
import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransaction;
import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccount;
import org.apache.fineract.useradministration.domain.AppUser;
import org.apache.fineract.useradministration.domain.AppUserRepository;
import org.apache.fineract.useradministration.domain.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.jms.Queue;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Service
public class NotificationDomainServiceImpl implements NotificationDomainService {
private final BusinessEventNotifierService businessEventNotifierService;
private final NotificationEventService notificationEventService;
private final AppUserRepository appUserRepository;
private final PlatformSecurityContext context;
@Autowired
public NotificationDomainServiceImpl(final BusinessEventNotifierService businessEventNotifierService,
final NotificationEventService notificationEventService,
final AppUserRepository appUserRepository,
final PlatformSecurityContext context) {
this.businessEventNotifierService = businessEventNotifierService;
this.notificationEventService = notificationEventService;
this.appUserRepository = appUserRepository;
this.context = context;
}
@PostConstruct
public void addListeners() {
businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.CLIENTS_CREATE,
new ClientCreatedListener());
businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.SAVINGS_APPROVE,
new SavingsAccountApprovedListener());
businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.CENTERS_CREATE,
new CenterCreatedListener());
businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.GROUPS_CREATE,
new GroupCreatedListener());
businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.SAVINGS_DEPOSIT,
new SavingsAccountDepositListener());
businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.SHARE_PRODUCT_DIVIDENDS_CREATE,
new ShareProductDividendCreatedListener());
businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.FIXED_DEPOSIT_ACCOUNT_CREATE,
new FixedDepositAccountCreatedListener());
businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.RECURRING_DEPOSIT_ACCOUNT_CREATE,
new RecurringDepositAccountCreatedListener());
businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.SAVINGS_POST_INTEREST,
new SavingsPostInterestListener());
businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.LOAN_CREATE,
new LoanCreatedListener());
businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.LOAN_APPROVED,
new LoanApprovedListener());
businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.LOAN_CLOSE,
new LoanClosedListener());
businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.LOAN_CLOSE_AS_RESCHEDULE,
new LoanCloseAsRescheduledListener());
businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.LOAN_MAKE_REPAYMENT,
new LoanMakeRepaymentListener());
businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.LOAN_PRODUCT_CREATE,
new LoanProductCreatedListener());
businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.SAVINGS_CREATE,
new SavingsAccountCreatedListener());
businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.SAVINGS_CLOSE,
new SavingsAccountClosedListener());
businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.SHARE_ACCOUNT_CREATE,
new ShareAccountCreatedListener());
businessEventNotifierService.addBusinessEventPostListners(BUSINESS_EVENTS.SHARE_ACCOUNT_APPROVE,
new ShareAccountApprovedListener());
}
private abstract class NotificationBusinessEventAdapter implements BusinessEventListner {
@Override
public void businessEventToBeExecuted(Map<BusinessEventNotificationConstants.BUSINESS_ENTITY, Object> businessEventEntity) {
//Nothing to do
}
}
private class ClientCreatedListener extends NotificationBusinessEventAdapter {
@Override
public void businessEventWasExecuted(Map<BusinessEventNotificationConstants.BUSINESS_ENTITY, Object> businessEventEntity) {
Client client;
Object entity = businessEventEntity.get(BusinessEventNotificationConstants.BUSINESS_ENTITY.CLIENT);
if (entity != null) {
client = (Client) entity;
buildNotification(
"ACTIVATE_CLIENT",
"client",
client.getId(),
"New client created",
"created",
context.authenticatedUser().getId(),
client.getOffice().getId()
);
}
}
}
private class CenterCreatedListener extends NotificationBusinessEventAdapter {
@Override
public void businessEventWasExecuted(Map<BusinessEventNotificationConstants.BUSINESS_ENTITY, Object> businessEventEntity) {
CommandProcessingResult commandProcessingResult;
Object entity = businessEventEntity.get(BUSINESS_ENTITY.GROUP);
if (entity != null) {
commandProcessingResult = (CommandProcessingResult) entity;
buildNotification(
"ACTIVATE_CENTER",
"center",
commandProcessingResult.getGroupId(),
"New center created",
"created",
context.authenticatedUser().getId(),
commandProcessingResult.getOfficeId()
);
}
}
}
private class GroupCreatedListener extends NotificationBusinessEventAdapter {
@Override
public void businessEventWasExecuted(Map<BusinessEventNotificationConstants.BUSINESS_ENTITY, Object> businessEventEntity) {
CommandProcessingResult commandProcessingResult;
Object entity = businessEventEntity.get(BUSINESS_ENTITY.GROUP);
if (entity != null) {
commandProcessingResult = (CommandProcessingResult) entity;
buildNotification(
"ACTIVATE_GROUP",
"group",
commandProcessingResult.getGroupId(),
"New group created",
"created",
context.authenticatedUser().getId(),
commandProcessingResult.getOfficeId()
);
}
}
}
private class SavingsAccountDepositListener extends NotificationBusinessEventAdapter {
@Override
public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
SavingsAccountTransaction savingsAccountTransaction;
Object entity = businessEventEntity.get(BUSINESS_ENTITY.SAVINGS_TRANSACTION);
if (entity != null) {
savingsAccountTransaction = (SavingsAccountTransaction) entity;
buildNotification(
"READ_SAVINGSACCOUNT",
"savingsAccount",
savingsAccountTransaction.getSavingsAccount().getId(),
"Deposit made",
"depositMade",
context.authenticatedUser().getId(),
savingsAccountTransaction.getSavingsAccount().officeId()
);
}
}
}
private class ShareProductDividendCreatedListener extends NotificationBusinessEventAdapter {
@Override
public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
Long shareProductId;
Object entity = businessEventEntity.get(BUSINESS_ENTITY.SHARE_PRODUCT);
if (entity != null) {
shareProductId = (Long) entity;
buildNotification(
"READ_DIVIDEND_SHAREPRODUCT",
"shareProduct",
shareProductId,
"Dividend posted to account",
"dividendPosted",
context.authenticatedUser().getId(),
context.authenticatedUser().getOffice().getId()
);
}
}
}
private class FixedDepositAccountCreatedListener extends NotificationBusinessEventAdapter {
@Override
public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
FixedDepositAccount fixedDepositAccount;
Object entity = businessEventEntity.get(BUSINESS_ENTITY.DEPOSIT_ACCOUNT);
if (entity != null) {
fixedDepositAccount = (FixedDepositAccount) entity;
buildNotification(
"APPROVE_FIXEDDEPOSITACCOUNT",
"fixedDeposit",
fixedDepositAccount.getId(),
"New fixed deposit account created",
"created",
context.authenticatedUser().getId(),
fixedDepositAccount.officeId()
);
}
}
}
private class RecurringDepositAccountCreatedListener extends NotificationBusinessEventAdapter {
@Override
public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
RecurringDepositAccount recurringDepositAccount;
Object entity = businessEventEntity.get(BUSINESS_ENTITY.DEPOSIT_ACCOUNT);
if (entity != null) {
recurringDepositAccount = (RecurringDepositAccount) entity;
buildNotification(
"APPROVE_RECURRINGDEPOSITACCOUNT",
"recurringDepositAccount",
recurringDepositAccount.getId(),
"New recurring deposit account created",
"created",
context.authenticatedUser().getId(),
recurringDepositAccount.officeId()
);
}
}
}
private class SavingsAccountApprovedListener extends NotificationBusinessEventAdapter {
@Override
public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
SavingsAccount savingsAccount;
Object entity = businessEventEntity.get(BUSINESS_ENTITY.SAVING);
if (entity != null) {
savingsAccount = (SavingsAccount) entity;
if (savingsAccount.depositAccountType().equals(DepositAccountType.FIXED_DEPOSIT)) {
buildNotification(
"ACTIVATE_FIXEDDEPOSITACCOUNT",
"fixedDeposit",
savingsAccount.getId(),
"Fixed deposit account approved",
"approved",
context.authenticatedUser().getId(),
savingsAccount.officeId()
);
} else if (savingsAccount.depositAccountType().equals(DepositAccountType.RECURRING_DEPOSIT)) {
buildNotification(
"ACTIVATE_RECURRINGDEPOSITACCOUNT",
"recurringDepositAccount",
savingsAccount.getId(),
"Recurring deposit account approved",
"approved",
context.authenticatedUser().getId(),
savingsAccount.officeId()
);
} else if (savingsAccount.depositAccountType().equals(DepositAccountType.SAVINGS_DEPOSIT)) {
buildNotification(
"ACTIVATE_SAVINGSACCOUNT",
"savingsAccount",
savingsAccount.getId(),
"Savings account approved",
"approved",
context.authenticatedUser().getId(),
savingsAccount.officeId()
);
}
}
}
}
private class SavingsPostInterestListener extends NotificationBusinessEventAdapter {
@Override
public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
SavingsAccount savingsAccount;
Object entity = businessEventEntity.get(BUSINESS_ENTITY.SAVING);
if (entity != null) {
savingsAccount = (SavingsAccount) entity;
buildNotification(
"READ_SAVINGSACCOUNT",
"savingsAccount",
savingsAccount.getId(),
"Interest posted to account",
"interestPosted",
context.authenticatedUser().getId(),
savingsAccount.officeId()
);
}
}
}
private class LoanCreatedListener extends NotificationBusinessEventAdapter {
@Override
public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
Loan loan;
Object entity = businessEventEntity.get(BUSINESS_ENTITY.LOAN);
if (entity != null) {
loan = (Loan) entity;
buildNotification(
"APPROVE_LOAN",
"loan",
loan.getId(),
"New loan created",
"created",
context.authenticatedUser().getId(),
loan.getOfficeId()
);
}
}
}
private class LoanApprovedListener extends NotificationBusinessEventAdapter {
@Override
public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
Loan loan;
Object entity = businessEventEntity.get(BUSINESS_ENTITY.LOAN);
if (entity != null) {
loan = (Loan) entity;
buildNotification(
"DISBURSE_LOAN",
"loan",
loan.getId(),
"New loan approved",
"approved",
context.authenticatedUser().getId(),
loan.getOfficeId()
);
}
}
}
private class LoanClosedListener extends NotificationBusinessEventAdapter {
@Override
public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
Loan loan;
Object entity = businessEventEntity.get(BUSINESS_ENTITY.LOAN);
if (entity != null) {
loan = (Loan) entity;
buildNotification(
"READ_LOAN",
"loan",
loan.getId(),
"Loan closed",
"loanClosed",
context.authenticatedUser().getId(),
loan.getOfficeId()
);
}
}
}
private class LoanCloseAsRescheduledListener extends NotificationBusinessEventAdapter {
@Override
public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
Loan loan;
Object entity = businessEventEntity.get(BUSINESS_ENTITY.LOAN);
if (entity != null) {
loan = (Loan) entity;
buildNotification(
"READ_Rescheduled Loans",
"loan",
loan.getId(),
"Loan has been rescheduled",
"loanRescheduled",
context.authenticatedUser().getId(),
loan.getOfficeId()
);
}
}
}
private class LoanMakeRepaymentListener extends NotificationBusinessEventAdapter {
@Override
public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
Loan loan;
Object entity = businessEventEntity.get(BUSINESS_ENTITY.LOAN);
if (entity != null) {
loan = (Loan) entity;
buildNotification(
"READ_LOAN",
"loan",
loan.getId(),
"Repayment made",
"repaymentMade",
context.authenticatedUser().getId(),
loan.getOfficeId()
);
}
}
}
private class LoanProductCreatedListener extends NotificationBusinessEventAdapter {
@Override
public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
LoanProduct loanProduct;
Object entity = businessEventEntity.get(BUSINESS_ENTITY.LOAN_PRODUCT);
if (entity != null) {
loanProduct = (LoanProduct) entity;
buildNotification(
"READ_LOANPRODUCT",
"loanProduct",
loanProduct.getId(),
"New loan product created",
"created",
context.authenticatedUser().getId(),
context.authenticatedUser().getOffice().getId()
);
}
}
}
private class SavingsAccountCreatedListener extends NotificationBusinessEventAdapter {
@Override
public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
SavingsAccount savingsAccount;
Object entity = businessEventEntity.get(BUSINESS_ENTITY.SAVING);
if (entity != null) {
savingsAccount = (SavingsAccount) entity;
buildNotification(
"APPROVE_SAVINGSACCOUNT",
"savingsAccount",
savingsAccount.getId(),
"New savings account created",
"created",
context.authenticatedUser().getId(),
savingsAccount.officeId()
);
}
}
}
private class SavingsAccountClosedListener extends NotificationBusinessEventAdapter {
@Override
public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
SavingsAccount savingsAccount;
Object entity = businessEventEntity.get(BUSINESS_ENTITY.SAVING);
if (entity != null) {
savingsAccount = (SavingsAccount) entity;
buildNotification(
"READ_SAVINGSACCOUNT",
"savingsAccount",
savingsAccount.getId(),
"Savings has gone into dormant",
"closed",
context.authenticatedUser().getId(),
savingsAccount.officeId()
);
}
}
}
private class ShareAccountCreatedListener extends NotificationBusinessEventAdapter {
@Override
public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
ShareAccount shareAccount;
Object entity = businessEventEntity.get(BUSINESS_ENTITY.SHARE_ACCOUNT);
if (entity != null) {
shareAccount = (ShareAccount) entity;
buildNotification(
"APPROVE_SHAREACCOUNT",
"shareAccount",
shareAccount.getId(),
"New share account created",
"created",
context.authenticatedUser().getId(),
shareAccount.getOfficeId()
);
}
}
}
private class ShareAccountApprovedListener extends NotificationBusinessEventAdapter {
@Override
public void businessEventWasExecuted(Map<BUSINESS_ENTITY, Object> businessEventEntity) {
ShareAccount shareAccount;
Object entity = businessEventEntity.get(BUSINESS_ENTITY.SHARE_ACCOUNT);
if (entity != null) {
shareAccount = (ShareAccount) entity;
buildNotification(
"ACTIVATE_SHAREACCOUNT",
"shareAccount",
shareAccount.getId(),
"Share account approved",
"approved",
context.authenticatedUser().getId(),
shareAccount.getOfficeId()
);
}
}
}
private void buildNotification(String permission, String objectType,
Long objectIdentifier, String notificationContent, String eventType,
Long appUserId, Long officeId) {
String tenantIdentifier = ThreadLocalContextUtil.getTenant().getTenantIdentifier();
Queue queue = new ActiveMQQueue("NotificationQueue");
List<Long> userIds = retrieveUsersWithSpecificPermission(permission);
NotificationData notificationData = new NotificationData(
objectType,
objectIdentifier,
eventType,
appUserId,
notificationContent,
false,
tenantIdentifier,
officeId,
userIds
);
notificationEventService.broadcastNotification(queue, notificationData);
}
private List<Long> retrieveUsersWithSpecificPermission(String permission) {
List<AppUser> appUsers = appUserRepository.findAll();
List<Long> userIds = new ArrayList<>();
for (AppUser appUser : appUsers) {
Set<Role> roles = appUser.getRoles();
for (Role role : roles) {
if (role.hasPermissionTo(permission)) {
if (!(userIds.contains(appUser.getId()))) {
userIds.add(appUser.getId());
}
}
}
}
return userIds;
}
}
@@ -0,0 +1,35 @@
/**
* 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.notification.service;
import org.apache.fineract.notification.domain.Notification;
import java.util.List;
public interface NotificationGeneratorReadRepositoryWrapper {
Notification findById(Long id);
List<Notification> fetchAllNotifications();
void delete(Long id);
}
@@ -0,0 +1,53 @@
/**
* 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.notification.service;
import org.apache.fineract.notification.domain.Notification;
import org.apache.fineract.notification.domain.NotificationRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class NotificationGeneratorReadRepositoryWrapperImpl implements NotificationGeneratorReadRepositoryWrapper {
private final NotificationRepository notificationRepository;
@Autowired
public NotificationGeneratorReadRepositoryWrapperImpl(NotificationRepository notificationRepository) {
this.notificationRepository = notificationRepository;
}
@Override
public Notification findById(Long id) {
return this.notificationRepository.findOne(id);
}
@Override
public List<Notification> fetchAllNotifications() {
return this.notificationRepository.findAll();
}
@Override
public void delete(Long id) {
this.notificationRepository.delete(id);
}
}
@@ -0,0 +1,27 @@
/**
* 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.notification.service;
import org.apache.fineract.notification.domain.Notification;
public interface NotificationGeneratorWritePlatformService {
Long create(Notification notification);
}
@@ -0,0 +1,41 @@
/**
* 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.notification.service;
import org.apache.fineract.notification.domain.Notification;
import org.apache.fineract.notification.domain.NotificationRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class NotificationGeneratorWritePlatformServiceImpl implements NotificationGeneratorWritePlatformService {
private final NotificationRepository notificationRepository;
@Autowired
public NotificationGeneratorWritePlatformServiceImpl(NotificationRepository notificationRepository) {
this.notificationRepository = notificationRepository;
}
@Override
public Long create(Notification notification) {
this.notificationRepository.save(notification);
return notification.getId();
}
}
@@ -0,0 +1,34 @@
/**
* 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.notification.service;
import org.apache.fineract.notification.domain.NotificationMapper;
import java.util.List;
public interface NotificationMapperReadRepositoryWrapper {
NotificationMapper findById(Long id);
List<NotificationMapper> fetchAllNotifications();
void delete(Long id);
}
@@ -0,0 +1,53 @@
/**
* 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.notification.service;
import org.apache.fineract.notification.domain.NotificationMapper;
import org.apache.fineract.notification.domain.NotificationMapperRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class NotificationMapperReadRepositoryWrapperImpl implements NotificationMapperReadRepositoryWrapper {
private final NotificationMapperRepository notificationMapperRepository;
@Autowired
public NotificationMapperReadRepositoryWrapperImpl(NotificationMapperRepository notificationMapperRepository) {
this.notificationMapperRepository = notificationMapperRepository;
}
@Override
public NotificationMapper findById(Long id) {
return this.notificationMapperRepository.findOne(id);
}
@Override
public List<NotificationMapper> fetchAllNotifications() {
return this.notificationMapperRepository.findAll();
}
@Override
public void delete(Long id) {
this.notificationMapperRepository.delete(id);
}
}
@@ -0,0 +1,27 @@
/**
* 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.notification.service;
import org.apache.fineract.notification.domain.NotificationMapper;
public interface NotificationMapperWritePlatformService {
Long create(NotificationMapper notificationMapper);
}
@@ -0,0 +1,41 @@
/**
* 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.notification.service;
import org.apache.fineract.notification.domain.NotificationMapper;
import org.apache.fineract.notification.domain.NotificationMapperRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class NotificationMapperWritePlatformServiceImpl implements NotificationMapperWritePlatformService {
private final NotificationMapperRepository notificationMapperRepository;
@Autowired
public NotificationMapperWritePlatformServiceImpl(NotificationMapperRepository notificationMapperRepository) {
this.notificationMapperRepository = notificationMapperRepository;
}
@Override
public Long create(NotificationMapper notificationMapper) {
this.notificationMapperRepository.save(notificationMapper);
return notificationMapper.getId();
}
}
@@ -0,0 +1,34 @@
/**
* 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.notification.service;
import org.apache.fineract.infrastructure.core.service.Page;
import org.apache.fineract.infrastructure.core.service.SearchParameters;
import org.apache.fineract.notification.data.NotificationData;
public interface NotificationReadPlatformService {
boolean hasUnreadNotifications(Long appUserId);
Page<NotificationData> getAllUnreadNotifications(SearchParameters searchParameters);
Page<NotificationData> getAllNotifications(SearchParameters searchParameters);
void updateNotificationReadStatus();
}
@@ -0,0 +1,219 @@
/**
* 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.notification.service;
import org.apache.fineract.infrastructure.core.service.*;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.notification.cache.CacheNotificationResponseHeader;
import org.apache.fineract.notification.data.NotificationData;
import org.apache.fineract.notification.data.NotificationMapperData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
@Service
public class NotificationReadPlatformServiceImpl implements NotificationReadPlatformService {
private final JdbcTemplate jdbcTemplate;
private final PlatformSecurityContext context;
private final PaginationHelper<NotificationData> paginationHelper = new PaginationHelper<>();
private final NotificationDataRow notificationDataRow = new NotificationDataRow();
private final NotificationMapperRow notificationMapperRow = new NotificationMapperRow();
private HashMap<Long, HashMap<Long, CacheNotificationResponseHeader>>
tenantNotificationResponseHeaderCache = new HashMap<>();
@Autowired
public NotificationReadPlatformServiceImpl(final RoutingDataSource dataSource, final PlatformSecurityContext context) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.context = context;
}
@Override
public boolean hasUnreadNotifications(Long appUserId) {
Long tenantId = ThreadLocalContextUtil.getTenant().getId();
Long now = System.currentTimeMillis()/1000L;
if (this.tenantNotificationResponseHeaderCache.containsKey(tenantId)) {
HashMap<Long, CacheNotificationResponseHeader> notificationResponseHeaderCache =
this.tenantNotificationResponseHeaderCache.get(tenantId);
if (notificationResponseHeaderCache.containsKey(appUserId)) {
Long lastFetch = notificationResponseHeaderCache.get(appUserId).getLastFetch();
if ((now - lastFetch) > 1) {
return this.createUpdateCacheValue(appUserId, now, notificationResponseHeaderCache);
} else {
return notificationResponseHeaderCache.get(appUserId).hasNotifications();
}
} else {
return this.createUpdateCacheValue(appUserId, now, notificationResponseHeaderCache);
}
} else {
return this.initializeTenantNotificationResponseHeaderCache(tenantId, now, appUserId);
}
}
private boolean initializeTenantNotificationResponseHeaderCache(Long tenantId, Long now, Long appUserId) {
HashMap<Long, CacheNotificationResponseHeader> notificationResponseHeaderCache = new HashMap<>();
this.tenantNotificationResponseHeaderCache.put(tenantId, notificationResponseHeaderCache);
return this.createUpdateCacheValue(appUserId, now, notificationResponseHeaderCache);
}
private boolean createUpdateCacheValue(Long appUserId, Long now, HashMap<Long,
CacheNotificationResponseHeader> notificationResponseHeaderCache) {
boolean hasNotifications;
Long tenantId = ThreadLocalContextUtil.getTenant().getId();
CacheNotificationResponseHeader cacheNotificationResponseHeader;
hasNotifications = checkForUnreadNotifications(appUserId);
cacheNotificationResponseHeader = new CacheNotificationResponseHeader(hasNotifications, now);
notificationResponseHeaderCache.put(appUserId, cacheNotificationResponseHeader);
this.tenantNotificationResponseHeaderCache.put(tenantId, notificationResponseHeaderCache);
return hasNotifications;
}
private boolean checkForUnreadNotifications(Long appUserId) {
String sql = "SELECT id, notification_id as notificationId, user_id as userId, is_read as isRead, created_at " +
"as createdAt FROM notification_mapper WHERE user_id = ? AND is_read = false";
List<NotificationMapperData > notificationMappers = this.jdbcTemplate.query(
sql,
notificationMapperRow,
appUserId);
return notificationMappers.size() > 0;
}
@Override
public void updateNotificationReadStatus() {
final Long appUserId = context.authenticatedUser().getId();
String sql = "UPDATE notification_mapper SET is_read = true WHERE is_read = false and user_id = ?";
this.jdbcTemplate.update(sql, appUserId);
}
@Override
public Page<NotificationData> getAllUnreadNotifications(final SearchParameters searchParameters) {
final Long appUserId = context.authenticatedUser().getId();
String sql = "SELECT SQL_CALC_FOUND_ROWS ng.id as id, nm.user_id as userId, ng.object_type as objectType, " +
"ng.object_identifier as objectId, ng.actor as actor, ng.action action, ng.notification_content " +
"as content, ng.is_system_generated as isSystemGenerated, nm.created_at as createdAt " +
"FROM notification_mapper nm INNER JOIN notification_generator ng ON nm.notification_id = ng.id " +
"WHERE nm.user_id = ? AND nm.is_read = false order by nm.created_at desc";
return getNotificationDataPage(searchParameters, appUserId, sql);
}
@Override
public Page<NotificationData> getAllNotifications(SearchParameters searchParameters) {
final Long appUserId = context.authenticatedUser().getId();
String sql = "SELECT SQL_CALC_FOUND_ROWS ng.id as id, nm.user_id as userId, ng.object_type as objectType, " +
"ng.object_identifier as objectId, ng.actor as actor, ng.action action, ng.notification_content " +
"as content, ng.is_system_generated as isSystemGenerated, nm.created_at as createdAt " +
"FROM notification_mapper nm INNER JOIN notification_generator ng ON nm.notification_id = ng.id " +
"WHERE nm.user_id = ? order by nm.created_at desc";
return getNotificationDataPage(searchParameters, appUserId, sql);
}
private Page<NotificationData> getNotificationDataPage(SearchParameters searchParameters, Long appUserId, String sql) {
final StringBuilder sqlBuilder = new StringBuilder(200);
sqlBuilder.append(sql);
if (searchParameters.isOrderByRequested()) {
sqlBuilder.append(" order by ").append(searchParameters.getOrderBy());
if (searchParameters.isSortOrderProvided()) {
sqlBuilder.append(' ').append(searchParameters.getSortOrder());
}
}
if (searchParameters.isLimited()) {
sqlBuilder.append(" limit ").append(searchParameters.getLimit());
if (searchParameters.isOffset()) {
sqlBuilder.append(" offset ").append(searchParameters.getOffset());
}
}
final String sqlCountRows = "SELECT FOUND_ROWS()";
Object[] params = new Object[]{appUserId};
return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(),
params, this.notificationDataRow);
}
private static final class NotificationMapperRow implements RowMapper<NotificationMapperData> {
@Override
public NotificationMapperData mapRow(ResultSet rs, int rowNum) throws SQLException {
NotificationMapperData notificationMapperData = new NotificationMapperData();
final Long id = rs.getLong("id");
notificationMapperData.setId(id);
final Long notificationId = rs.getLong("notificationId");
notificationMapperData.setNotificationId(notificationId);
final Long userId = rs.getLong("userId");
notificationMapperData.setUserId(userId);
final boolean isRead = rs.getBoolean("isRead");
notificationMapperData.setRead(isRead);
final String createdAt = rs.getString("createdAt");
notificationMapperData.setCreatedAt(createdAt);
return notificationMapperData;
}
}
private static final class NotificationDataRow implements RowMapper<NotificationData> {
@Override
public NotificationData mapRow(ResultSet rs, int rowNum) throws SQLException {
NotificationData notificationData = new NotificationData();
final Long id = rs.getLong("id");
notificationData.setId(id);
final String objectType = rs.getString("objectType");
notificationData.setObjectType(objectType);
final Long objectId = rs.getLong("objectId");
notificationData.entifier(objectId);
final Long actorId = rs.getLong("actor");
notificationData.setActor(actorId);
final String action = rs.getString("action");
notificationData.setAction(action);
final String content = rs.getString("content");
notificationData.setContent(content);
final boolean isSystemGenerated = rs.getBoolean("isSystemGenerated");
notificationData.setSystemGenerated(isSystemGenerated);
final String createdAt = rs.getString("createdAt");
notificationData.setCreatedAt(createdAt);
return notificationData;
}
}
}
@@ -0,0 +1,29 @@
/**
* 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.notification.service;
import java.util.List;
public interface NotificationWritePlatformService {
Long notify(Long userId, String objectType, Long objectId, String action,
Long actorId, String notificationContent, boolean isSystemGenerated);
Long notify(List<Long> userIds, String objectType, Long objectId, String action,
Long actorId, String notificationContent, boolean isSystemGenerated);
}
@@ -0,0 +1,129 @@
/**
* 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.notification.service;
import org.apache.fineract.notification.domain.Notification;
import org.apache.fineract.notification.domain.NotificationMapper;
import org.apache.fineract.useradministration.domain.AppUser;
import org.apache.fineract.useradministration.domain.AppUserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Service
public class NotificationWritePlatformServiceImpl implements NotificationWritePlatformService {
private final NotificationGeneratorWritePlatformService notificationGeneratorWritePlatformService;
private final NotificationGeneratorReadRepositoryWrapper notificationGeneratorReadRepositoryWrapper;
private final AppUserRepository appUserRepository;
private final NotificationMapperWritePlatformService notificationMapperWritePlatformService;
@Autowired
public NotificationWritePlatformServiceImpl(
final NotificationGeneratorWritePlatformService notificationGeneratorWritePlatformService,
final NotificationGeneratorReadRepositoryWrapper notificationGeneratorReadRepositoryWrapper,
final AppUserRepository appUserRepository,
final NotificationMapperWritePlatformService notificationMapperWritePlatformService) {
this.notificationGeneratorWritePlatformService = notificationGeneratorWritePlatformService;
this.notificationGeneratorReadRepositoryWrapper = notificationGeneratorReadRepositoryWrapper;
this.appUserRepository = appUserRepository;
this.notificationMapperWritePlatformService = notificationMapperWritePlatformService;
}
@Override
public Long notify(Long userId, String objectType, Long objectIdentifier, String action,
Long actorId, String notificationContent, boolean isSystemGenerated) {
Long generatedNotificationId = insertIntoNotificationGenerator(objectType, objectIdentifier, action,
actorId, notificationContent, isSystemGenerated);
insertIntoNotificationMapper(userId, generatedNotificationId);
return generatedNotificationId;
}
private Long insertIntoNotificationMapper(Long userId, Long generatedNotificationId) {
AppUser appUser = this.appUserRepository.findOne(userId);
NotificationMapper notificationMapper = new NotificationMapper(
this.notificationGeneratorReadRepositoryWrapper.findById(generatedNotificationId),
appUser,
false,
getCurrentDateTime()
);
this.notificationMapperWritePlatformService.create(notificationMapper);
return notificationMapper.getId();
}
private Long insertIntoNotificationGenerator(String objectType, Long objectIdentifier, String action,
Long actorId, String notificationContent,
boolean isSystemGenerated) {
Notification notification = new Notification(
objectType,
objectIdentifier,
action,
actorId,
isSystemGenerated,
notificationContent,
getCurrentDateTime()
);
return this.notificationGeneratorWritePlatformService.create(notification);
}
@Override
public Long notify(List<Long> userIds, String objectType, Long objectId, String action,
Long actorId, String notificationContent, boolean isSystemGenerated) {
Long generatedNotificationId = insertIntoNotificationGenerator(objectType, objectId, action,
actorId, notificationContent, isSystemGenerated);
insertIntoNotificationMapper(userIds, generatedNotificationId);
return generatedNotificationId;
}
private List<Long> insertIntoNotificationMapper(List<Long> userIds, Long generatedNotificationId) {
List<Long> mappedIds = new ArrayList<>();
for (Long userId : userIds) {
AppUser appUser = this.appUserRepository.findOne(userId);
NotificationMapper notificationMapper = new NotificationMapper(
this.notificationGeneratorReadRepositoryWrapper.findById(generatedNotificationId),
appUser,
false,
getCurrentDateTime()
);
this.notificationMapperWritePlatformService.create(notificationMapper);
mappedIds.add(notificationMapper.getId());
}
return mappedIds;
}
private String getCurrentDateTime() {
Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return formatter.format(date);
}
}
@@ -342,6 +342,9 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
command.arrayOfParameterNamed(ClientApiConstants.datatables));
}
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.CLIENTS_CREATE,
constructEntityMap(BUSINESS_ENTITY.CLIENT, newClient));
this.entityDatatableChecksWritePlatformService.runTheCheck(newClient.getId(), EntityTables.CLIENT.getName(),
StatusEnum.CREATE.getCode().longValue(), EntityTables.CLIENT.getForeignKeyColumnNameOnDatatable());
return new CommandProcessingResultBuilder() //
@@ -32,10 +32,13 @@ public class BusinessEventNotificationConstants {
"loan_update_charge"), LOAN_WAIVE_CHARGE("loan_waive_charge"), LOAN_DELETE_CHARGE("loan_delete_charge"), LOAN_CHARGE_PAYMENT(
"loan_charge_payment"), LOAN_INITIATE_TRANSFER("loan_initiate_transfer"), LOAN_ACCEPT_TRANSFER("loan_accept_transfer"), LOAN_WITHDRAW_TRANSFER(
"loan_withdraw_transfer"), LOAN_REJECT_TRANSFER("loan_reject_transfer"), LOAN_REASSIGN_OFFICER("loan_reassign_officer"), LOAN_REMOVE_OFFICER(
"loan_remove_officer"), LOAN_APPLY_OVERDUE_CHARGE("loan_apply_overdue_charge"), LOAN_INTEREST_RECALCULATION(
"loan_interest_recalculation"), LOAN_REFUND("loan_refund"), LOAN_FORECLOSURE("loan_foreclosure"), SAVINGS_ACTIVATE(
"savings_activated"), SAVINGS_REJECT("savings_reject"), SAVINGS_DEPOSIT("savings_deposit"), SAVINGS_WITHDRAWAL(
"savings_withdrawal"), CLIENTS_ACTIVATE("clients_activate"), CLIENTS_REJECT("clients_reject");
"loan_remove_officer"), LOAN_APPLY_OVERDUE_CHARGE("loan_apply_overdue_charge"), LOAN_INTEREST_RECALCULATION("loan_interest_recalculation"),
LOAN_REFUND("loan_refund"), LOAN_FORECLOSURE("loan_foreclosure"), LOAN_CREATE("loan_create"), LOAN_PRODUCT_CREATE("loan_product_create"), SAVINGS_ACTIVATE("savings_activated"),
SAVINGS_REJECT("savings_reject"), SAVINGS_POST_INTEREST("savings_post_interest"), SAVINGS_DEPOSIT("savings_deposit"), SAVINGS_CLOSE("savings_close"),
SAVINGS_WITHDRAWAL("savings_withdrawal"), SAVINGS_APPROVE("savings_approve"), SAVINGS_CREATE("savings_create"), CLIENTS_ACTIVATE("clients_activate"), SHARE_ACCOUNT_CREATE("share_account_create"),
CLIENTS_REJECT("clients_reject"), CLIENTS_CREATE("clients_create"),CENTERS_CREATE("centers_create"), GROUPS_CREATE("groups_create"),
SHARE_PRODUCT_DIVIDENDS_CREATE("share_product_dividends_create"),FIXED_DEPOSIT_ACCOUNT_CREATE("fixed_deposit_account_create"),
SHARE_ACCOUNT_APPROVE("share_account_approve"), RECURRING_DEPOSIT_ACCOUNT_CREATE("recurring_deposit_account_create");
private final String value;
@@ -61,7 +64,8 @@ public class BusinessEventNotificationConstants {
public static enum BUSINESS_ENTITY {
LOAN("loan"), LOAN_TRANSACTION("loan_transaction"), LOAN_CHARGE("loan_charge"), LOAN_ADJUSTED_TRANSACTION(
"loan_adjusted_transaction"), SAVING("saving"), CLIENT("client"), SAVINGS_TRANSACTION("Savings Transaction");
"loan_adjusted_transaction"), SAVING("saving"), CLIENT("client"), SAVINGS_TRANSACTION("Savings Transaction"), GROUP("group"),
SHARE_ACCOUNT("share_account"), SHARE_PRODUCT("share_product"), DEPOSIT_ACCOUNT("deposit_account"), LOAN_PRODUCT("loan_product");
private final String value;
@@ -52,6 +52,8 @@ import org.apache.fineract.portfolio.client.domain.AccountNumberGenerator;
import org.apache.fineract.portfolio.client.domain.Client;
import org.apache.fineract.portfolio.client.domain.ClientRepositoryWrapper;
import org.apache.fineract.portfolio.client.service.LoanStatusMapper;
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants;
import org.apache.fineract.portfolio.common.service.BusinessEventNotifierService;
import org.apache.fineract.portfolio.group.api.GroupingTypesApiConstants;
import org.apache.fineract.portfolio.group.domain.*;
import org.apache.fineract.portfolio.group.exception.*;
@@ -72,6 +74,8 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.BUSINESS_ENTITY;
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.BUSINESS_EVENTS;
@Service
public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements GroupingTypesWritePlatformService {
@@ -95,6 +99,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
private final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository;
private final AccountNumberGenerator accountNumberGenerator;
private final EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService;
private final BusinessEventNotifierService businessEventNotifierService;
@Autowired
public GroupingTypesWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
@@ -106,7 +111,8 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
final CalendarInstanceRepository calendarInstanceRepository, final ConfigurationDomainService configurationDomainService,
final LoanRepositoryWrapper loanRepositoryWrapper,
final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository, final AccountNumberGenerator accountNumberGenerator,
final EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService) {
final EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService,
final BusinessEventNotifierService businessEventNotifierService) {
this.context = context;
this.groupRepository = groupRepository;
this.clientRepositoryWrapper = clientRepositoryWrapper;
@@ -124,6 +130,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
this.accountNumberFormatRepository = accountNumberFormatRepository;
this.accountNumberGenerator = accountNumberGenerator;
this.entityDatatableChecksWritePlatformService = entityDatatableChecksWritePlatformService;
this.businessEventNotifierService = businessEventNotifierService;
}
private CommandProcessingResult createGroupingType(final JsonCommand command, final GroupTypes groupingType, final Long centerId) {
@@ -263,7 +270,13 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
this.fromApiJsonDeserializer.validateForCreateCenter(command);
final Long centerId = null;
return createGroupingType(command, GroupTypes.CENTER, centerId);
CommandProcessingResult commandProcessingResult = createGroupingType(command, GroupTypes.CENTER, centerId);
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.CENTERS_CREATE,
constructEntityMap(BUSINESS_ENTITY.GROUP, commandProcessingResult));
return commandProcessingResult;
}
@Transactional
@@ -276,7 +289,12 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
this.fromApiJsonDeserializer.validateForCreateGroup(command);
}
return createGroupingType(command, GroupTypes.GROUP, centerId);
CommandProcessingResult commandProcessingResult = createGroupingType(command, GroupTypes.GROUP, centerId);
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BusinessEventNotificationConstants.BUSINESS_EVENTS.GROUPS_CREATE,
constructEntityMap(BUSINESS_ENTITY.GROUP, commandProcessingResult));
return commandProcessingResult;
}
@Transactional
@@ -961,4 +979,10 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
}
}
}
private Map<BusinessEventNotificationConstants.BUSINESS_ENTITY, Object> constructEntityMap(final BUSINESS_ENTITY entityEvent, Object entity) {
Map<BUSINESS_ENTITY, Object> map = new HashMap<>(1);
map.put(entityEvent, entity);
return map;
}
}
@@ -394,6 +394,8 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
EntityTables.LOAN.getName(), StatusEnum.CREATE.getCode().longValue(),
EntityTables.LOAN.getForeignKeyColumnNameOnDatatable(), newLoanApplication.productId());
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.LOAN_CREATE,
constructEntityMap(BUSINESS_ENTITY.LOAN, newLoanApplication));
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
@@ -128,6 +128,7 @@ import org.springframework.util.CollectionUtils;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
@Service
public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatformService {
@@ -1172,7 +1173,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
this.loanAccountDomainService.recalculateAccruals(loan);
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.LOAN_CLOSE,
constructEntityMap(BUSINESS_ENTITY.LOAN, loan));
// disable all active standing instructions linked to the loan
this.loanAccountDomainService.disableStandingInstructionsLinkedToClosedLoan(loan);
@@ -19,6 +19,7 @@
package org.apache.fineract.portfolio.loanproduct.service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -35,6 +36,8 @@ import org.apache.fineract.infrastructure.entityaccess.service.FineractEntityAcc
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.portfolio.charge.domain.Charge;
import org.apache.fineract.portfolio.charge.domain.ChargeRepositoryWrapper;
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants;
import org.apache.fineract.portfolio.common.service.BusinessEventNotifierService;
import org.apache.fineract.portfolio.floatingrates.domain.FloatingRate;
import org.apache.fineract.portfolio.floatingrates.domain.FloatingRateRepositoryWrapper;
import org.apache.fineract.portfolio.fund.domain.Fund;
@@ -43,6 +46,8 @@ import org.apache.fineract.portfolio.fund.exception.FundNotFoundException;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionProcessingStrategyRepository;
import org.apache.fineract.portfolio.loanaccount.exception.LoanTransactionProcessingStrategyNotFoundException;
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.BUSINESS_ENTITY;
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.BUSINESS_EVENTS;
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.AprCalculator;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRepository;
@@ -78,6 +83,7 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
private final FineractEntityAccessUtil fineractEntityAccessUtil;
private final FloatingRateRepositoryWrapper floatingRateRepository;
private final LoanRepositoryWrapper loanRepositoryWrapper;
private final BusinessEventNotifierService businessEventNotifierService;
@Autowired
public LoanProductWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
@@ -88,7 +94,8 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
final ProductToGLAccountMappingWritePlatformService accountMappingWritePlatformService,
final FineractEntityAccessUtil fineractEntityAccessUtil,
final FloatingRateRepositoryWrapper floatingRateRepository,
final LoanRepositoryWrapper loanRepositoryWrapper) {
final LoanRepositoryWrapper loanRepositoryWrapper,
final BusinessEventNotifierService businessEventNotifierService) {
this.context = context;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.loanProductRepository = loanProductRepository;
@@ -100,6 +107,7 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
this.fineractEntityAccessUtil = fineractEntityAccessUtil;
this.floatingRateRepository = floatingRateRepository;
this.loanRepositoryWrapper = loanRepositoryWrapper;
this.businessEventNotifierService = businessEventNotifierService;
}
@Transactional
@@ -139,6 +147,9 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
fineractEntityAccessUtil.checkConfigurationAndAddProductResrictionsForUserOffice(
FineractEntityAccessType.OFFICE_ACCESS_TO_LOAN_PRODUCTS,
loanproduct.getId());
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.LOAN_PRODUCT_CREATE,
constructEntityMap(BUSINESS_ENTITY.LOAN_PRODUCT, loanproduct));
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
@@ -332,4 +343,10 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
private void logAsErrorUnexpectedDataIntegrityException(final Exception dve) {
logger.error(dve.getMessage(), dve);
}
private Map<BusinessEventNotificationConstants.BUSINESS_ENTITY, Object> constructEntityMap(final BusinessEventNotificationConstants.BUSINESS_ENTITY entityEvent, Object entity) {
Map<BusinessEventNotificationConstants.BUSINESS_ENTITY, Object> map = new HashMap<>(1);
map.put(entityEvent, entity);
return map;
}
}
@@ -24,11 +24,7 @@ import static org.apache.fineract.portfolio.savings.DepositsApiConstants.recurri
import static org.apache.fineract.portfolio.savings.DepositsApiConstants.transferInterestToSavingsParamName;
import java.math.MathContext;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import javax.persistence.PersistenceException;
@@ -65,7 +61,9 @@ import org.apache.fineract.portfolio.client.domain.AccountNumberGenerator;
import org.apache.fineract.portfolio.client.domain.Client;
import org.apache.fineract.portfolio.client.domain.ClientRepositoryWrapper;
import org.apache.fineract.portfolio.client.exception.ClientNotActiveException;
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants;
import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
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.group.exception.CenterNotActiveException;
@@ -97,6 +95,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.BUSINESS_ENTITY;
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.BUSINESS_EVENTS;
@Service
public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl implements DepositApplicationProcessWritePlatformService {
@@ -122,6 +122,7 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
private final CalendarInstanceRepository calendarInstanceRepository;
private final ConfigurationDomainService configurationDomainService;
private final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository;
private final BusinessEventNotifierService businessEventNotifierService;
@Autowired
public DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
@@ -136,7 +137,8 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
final RecurringDepositAccountRepository recurringDepositAccountRepository,
final AccountAssociationsRepository accountAssociationsRepository, final FromJsonHelper fromJsonHelper,
final CalendarInstanceRepository calendarInstanceRepository, final ConfigurationDomainService configurationDomainService,
final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository) {
final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository,
final BusinessEventNotifierService businessEventNotifierService) {
this.context = context;
this.savingAccountRepository = savingAccountRepository;
this.depositAccountAssembler = depositAccountAssembler;
@@ -156,6 +158,7 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
this.calendarInstanceRepository = calendarInstanceRepository;
this.configurationDomainService = configurationDomainService;
this.accountNumberFormatRepository = accountNumberFormatRepository;
this.businessEventNotifierService = businessEventNotifierService;
}
/*
@@ -227,6 +230,9 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
final Long savingsId = account.getId();
this.businessEventNotifierService.notifyBusinessEventWasExecuted( BUSINESS_EVENTS.FIXED_DEPOSIT_ACCOUNT_CREATE,
constructEntityMap(BUSINESS_ENTITY.DEPOSIT_ACCOUNT, account));
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.withEntityId(savingsId) //
@@ -285,6 +291,9 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
account.validateApplicableInterestRate();
this.savingAccountRepository.save(account);
this.businessEventNotifierService.notifyBusinessEventWasExecuted( BUSINESS_EVENTS.RECURRING_DEPOSIT_ACCOUNT_CREATE,
constructEntityMap(BUSINESS_ENTITY.DEPOSIT_ACCOUNT, account));
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.withEntityId(savingsId) //
@@ -769,4 +778,10 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
}
}
}
private Map<BusinessEventNotificationConstants.BUSINESS_ENTITY, Object> constructEntityMap(final BUSINESS_ENTITY entityEvent, Object entity) {
Map<BusinessEventNotificationConstants.BUSINESS_ENTITY, Object> map = new HashMap<>(1);
map.put(entityEvent, entity);
return map;
}
}
@@ -382,6 +382,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
}
postInterest(account,postInterestAs,transactionDate);
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.SAVINGS_POST_INTEREST,
constructEntityMap(BUSINESS_ENTITY.SAVING, account));
return new CommandProcessingResultBuilder() //
.withEntityId(savingsId) //
.withOfficeId(account.officeId()) //
@@ -682,7 +685,10 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
}
}
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.SAVINGS_CLOSE,
constructEntityMap(BUSINESS_ENTITY.SAVING, account));
// disable all standing orders linked to the savings account
this.disableStandingInstructionsLinkedToClosedSavings(account);
return new CommandProcessingResultBuilder() //
@@ -181,6 +181,9 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
EntityTables.SAVING.getName(), StatusEnum.CREATE.getCode().longValue(),
EntityTables.SAVING.getForeignKeyColumnNameOnDatatable(), account.productId());
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.SAVINGS_CREATE,
constructEntityMap(BUSINESS_ENTITY.SAVING, account));
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.withEntityId(savingsId) //
@@ -362,6 +365,9 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
}
}
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.SAVINGS_APPROVE,
constructEntityMap(BUSINESS_ENTITY.SAVING, savingsAccount));
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.withEntityId(savingsId) //
@@ -42,8 +42,12 @@ import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityEx
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.organisation.monetary.data.CurrencyData;
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.BUSINESS_ENTITY;
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.BUSINESS_EVENTS;
import org.apache.fineract.portfolio.accounts.constants.ShareAccountApiConstants;
import org.apache.fineract.portfolio.client.domain.AccountNumberGenerator;
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants;
import org.apache.fineract.portfolio.common.service.BusinessEventNotifierService;
import org.apache.fineract.portfolio.note.domain.Note;
import org.apache.fineract.portfolio.note.domain.NoteRepository;
import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountTransactionEnumData;
@@ -75,6 +79,8 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA
private final JournalEntryWritePlatformService journalEntryWritePlatformService;
private final NoteRepository noteRepository;
private final BusinessEventNotifierService businessEventNotifierService;
@Autowired
public ShareAccountWritePlatformServiceJpaRepositoryImpl(final ShareAccountDataSerializer accountDataSerializer,
@@ -83,14 +89,16 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA
final AccountNumberGenerator accountNumberGenerator,
final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository,
final JournalEntryWritePlatformService journalEntryWritePlatformService,
final NoteRepository noteRepository) {
final NoteRepository noteRepository,
final BusinessEventNotifierService businessEventNotifierService) {
this.accountDataSerializer = accountDataSerializer;
this.shareAccountRepository = shareAccountRepository;
this.shareProductRepository = shareProductRepository ;
this.accountNumberGenerator = accountNumberGenerator;
this.accountNumberFormatRepository = accountNumberFormatRepository;
this.journalEntryWritePlatformService = journalEntryWritePlatformService;
this.noteRepository = noteRepository ;
this.noteRepository = noteRepository;
this.businessEventNotifierService = businessEventNotifierService;
}
@Override
@@ -101,6 +109,10 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA
generateAccountNumber(account);
journalEntryWritePlatformService.createJournalEntriesForShares(populateJournalEntries(account,
account.getPendingForApprovalSharePurchaseTransactions()));
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.SHARE_ACCOUNT_CREATE,
constructEntityMap(BUSINESS_ENTITY.SHARE_ACCOUNT, account));
return new CommandProcessingResultBuilder() //
.withCommandId(jsonCommand.commandId()) //
.withEntityId(account.getId()) //
@@ -273,6 +285,10 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA
this.shareProductRepository.save(shareProduct);
this.journalEntryWritePlatformService.createJournalEntriesForShares(populateJournalEntries(account, journalTransactions));
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.SHARE_ACCOUNT_APPROVE,
constructEntityMap(BUSINESS_ENTITY.SHARE_ACCOUNT, account));
return new CommandProcessingResultBuilder() //
.withCommandId(jsonCommand.commandId()) //
.withEntityId(accountId) //
@@ -516,4 +532,10 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA
throw new PlatformDataIntegrityException("error.msg.shareaccount.unknown.data.integrity.issue",
"Unknown data integrity issue with resource.");
}
private Map<BusinessEventNotificationConstants.BUSINESS_ENTITY, Object> constructEntityMap(final BusinessEventNotificationConstants.BUSINESS_ENTITY entityEvent, Object entity) {
Map<BusinessEventNotificationConstants.BUSINESS_ENTITY, Object> map = new HashMap<>(1);
map.put(entityEvent, entity);
return map;
}
}
@@ -19,6 +19,7 @@
package org.apache.fineract.portfolio.shareproducts.service;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.PersistenceException;
@@ -30,6 +31,10 @@ import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.BUSINESS_ENTITY;
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.BUSINESS_EVENTS;
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants;
import org.apache.fineract.portfolio.common.service.BusinessEventNotifierService;
import org.apache.fineract.portfolio.shareproducts.constants.ShareProductApiConstants;
import org.apache.fineract.portfolio.shareproducts.domain.ShareProduct;
import org.apache.fineract.portfolio.shareproducts.domain.ShareProductDividendPayOutDetails;
@@ -53,19 +58,22 @@ public class ShareProductWritePlatformServiceJpaRepositoryImpl implements ShareP
private final ShareProductDividentPayOutDetailsRepositoryWrapper shareProductDividentPayOutDetailsRepository;
private final ShareProductDividendAssembler shareProductDividendAssembler;
private final ProductToGLAccountMappingWritePlatformService accountMappingWritePlatformService;
private final BusinessEventNotifierService businessEventNotifierService;
@Autowired
public ShareProductWritePlatformServiceJpaRepositoryImpl(final ShareProductRepositoryWrapper repository,
final ShareProductDataSerializer serializer, final FromJsonHelper fromApiJsonHelper,
final ShareProductDividentPayOutDetailsRepositoryWrapper shareProductDividentPayOutDetailsRepositor,
final ShareProductDividendAssembler shareProductDividendAssembler,
final ProductToGLAccountMappingWritePlatformService accountMappingWritePlatformService) {
final ProductToGLAccountMappingWritePlatformService accountMappingWritePlatformService,
final BusinessEventNotifierService businessEventNotifierService) {
this.repository = repository;
this.serializer = serializer;
this.fromApiJsonHelper = fromApiJsonHelper;
this.shareProductDividentPayOutDetailsRepository = shareProductDividentPayOutDetailsRepositor;
this.shareProductDividendAssembler = shareProductDividendAssembler;
this.accountMappingWritePlatformService = accountMappingWritePlatformService;
this.businessEventNotifierService = businessEventNotifierService;
}
@Override
@@ -140,6 +148,10 @@ public class ShareProductWritePlatformServiceJpaRepositoryImpl implements ShareP
"No eligible shares for creating dividends"); }
this.shareProductDividentPayOutDetailsRepository.save(dividendPayOutDetails);
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.SHARE_PRODUCT_DIVIDENDS_CREATE,
constructEntityMap(BUSINESS_ENTITY.SHARE_PRODUCT, productId));
return new CommandProcessingResultBuilder() //
.withCommandId(jsonCommand.commandId()) //
.withEntityId(productId) //
@@ -204,4 +216,10 @@ public class ShareProductWritePlatformServiceJpaRepositoryImpl implements ShareP
"Unknown data integrity issue with resource.");
}
private Map<BusinessEventNotificationConstants.BUSINESS_ENTITY, Object> constructEntityMap(final BusinessEventNotificationConstants.BUSINESS_ENTITY entityEvent, Object entity) {
Map<BusinessEventNotificationConstants.BUSINESS_ENTITY, Object> map = new HashMap<>(1);
map.put(entityEvent, entity);
return map;
}
}