blob: f6c8e4c37510292099d2a84adb0ffa265207c2e1 [file] [log] [blame]
/**
* 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.data.TopicSubscriberData;
import org.apache.fineract.notification.eventandlistener.NotificationEventService;
import org.apache.fineract.notification.eventandlistener.SpringEventPublisher;
import org.apache.fineract.organisation.office.domain.OfficeRepository;
import org.apache.fineract.portfolio.client.domain.Client;
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants;
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.BUSINESS_ENTITY;
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.BUSINESS_EVENTS;
import org.apache.fineract.portfolio.common.service.BusinessEventListner;
import org.apache.fineract.portfolio.common.service.BusinessEventNotifierService;
import org.apache.fineract.portfolio.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.Role;
import org.apache.fineract.useradministration.domain.RoleRepository;
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.Collection;
import java.util.List;
import java.util.Map;
@Service
public class NotificationDomainServiceImpl implements NotificationDomainService {
private final BusinessEventNotifierService businessEventNotifierService;
final PlatformSecurityContext context;
private final RoleRepository roleRepository;
private final OfficeRepository officeRepository;
private final TopicSubscriberReadPlatformService topicSubscriberReadPlatformService;
private final NotificationEventService notificationEvent;
private final SpringEventPublisher springEventPublisher;
@Autowired
public NotificationDomainServiceImpl(final BusinessEventNotifierService businessEventNotifierService,
final PlatformSecurityContext context, final RoleRepository roleRepository,
final TopicSubscriberReadPlatformService topicSubscriberReadPlatformService,
final OfficeRepository officeRepository, final NotificationEventService notificationEvent,
final SpringEventPublisher springEventPublisher) {
this.businessEventNotifierService = businessEventNotifierService;
this.context = context;
this.roleRepository = roleRepository;
this.topicSubscriberReadPlatformService = topicSubscriberReadPlatformService;
this.officeRepository = officeRepository;
this.notificationEvent = notificationEvent;
this.springEventPublisher = springEventPublisher;
}
@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) {
}
}
private class ClientCreatedListener extends NotificationBusinessEventAdapter {
@Override
public void businessEventWasExecuted(Map<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 = retrieveSubscribers(officeId, permission);
NotificationData notificationData = new NotificationData(
objectType,
objectIdentifier,
eventType,
appUserId,
notificationContent,
false,
false,
tenantIdentifier,
officeId,
userIds
);
try {
this.notificationEvent.broadcastNotification(queue, notificationData);
} catch(Exception e) {
this.springEventPublisher.broadcastNotification(notificationData);
}
}
private List<Long> retrieveSubscribers(Long officeId, String permission) {
Collection<TopicSubscriberData> topicSubscribers = new ArrayList<>();
List<Long> subscriberIds = new ArrayList<>();
Long entityId = officeId;
String entityType= "";
if (officeRepository.findOne(entityId).getParent() == null) {
entityType = "OFFICE";
} else {
entityType = "BRANCH";
}
List<Role> allRoles = roleRepository.findAll();
for (Role curRole : allRoles) {
if (curRole.hasPermissionTo(permission) || curRole.hasPermissionTo("ALL_FUNCTIONS")) {
String memberType = curRole.getName();
topicSubscribers = topicSubscriberReadPlatformService.getSubscribers(entityId, entityType, memberType);
}
}
for (TopicSubscriberData topicSubscriber : topicSubscribers) {
subscriberIds.add(topicSubscriber.getUserId());
}
return subscriberIds;
}
}