FINERACT-1724: Put user notification feature behind feature toggle
This commit is contained in:
committed by
Arnold Gálovics
parent
3a176f4cbf
commit
d21110f7b2
+15
@@ -58,6 +58,8 @@ public class FineractProperties {
|
|||||||
private FineractQueryProperties query;
|
private FineractQueryProperties query;
|
||||||
private FineractApiProperties api;
|
private FineractApiProperties api;
|
||||||
|
|
||||||
|
private FineractNotificationProperties notification;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public static class FineractTenantProperties {
|
public static class FineractTenantProperties {
|
||||||
@@ -280,4 +282,17 @@ public class FineractProperties {
|
|||||||
private int inlineLoanCob;
|
private int inlineLoanCob;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public static class FineractNotificationProperties {
|
||||||
|
|
||||||
|
private UserNotificationSystemProperties userNotificationSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public static class UserNotificationSystemProperties {
|
||||||
|
|
||||||
|
private boolean enabled;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -37,7 +37,7 @@ import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
|||||||
import org.apache.fineract.infrastructure.security.data.PlatformRequestLog;
|
import org.apache.fineract.infrastructure.security.data.PlatformRequestLog;
|
||||||
import org.apache.fineract.infrastructure.security.exception.InvalidTenantIdentifierException;
|
import org.apache.fineract.infrastructure.security.exception.InvalidTenantIdentifierException;
|
||||||
import org.apache.fineract.infrastructure.security.service.BasicAuthTenantDetailsService;
|
import org.apache.fineract.infrastructure.security.service.BasicAuthTenantDetailsService;
|
||||||
import org.apache.fineract.notification.service.NotificationReadPlatformService;
|
import org.apache.fineract.notification.service.UserNotificationService;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -79,7 +79,7 @@ public class TenantAwareBasicAuthenticationFilter extends BasicAuthenticationFil
|
|||||||
private CacheWritePlatformService cacheWritePlatformService;
|
private CacheWritePlatformService cacheWritePlatformService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private NotificationReadPlatformService notificationReadPlatformService;
|
private UserNotificationService userNotificationService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private BasicAuthTenantDetailsService basicAuthTenantDetailsService;
|
private BasicAuthTenantDetailsService basicAuthTenantDetailsService;
|
||||||
@@ -170,7 +170,7 @@ public class TenantAwareBasicAuthenticationFilter extends BasicAuthenticationFil
|
|||||||
super.onSuccessfulAuthentication(request, response, authResult);
|
super.onSuccessfulAuthentication(request, response, authResult);
|
||||||
AppUser user = (AppUser) authResult.getPrincipal();
|
AppUser user = (AppUser) authResult.getPrincipal();
|
||||||
|
|
||||||
if (notificationReadPlatformService.hasUnreadNotifications(user.getId())) {
|
if (userNotificationService.hasUnreadUserNotifications(user.getId())) {
|
||||||
response.addHeader("X-Notification-Refresh", "true");
|
response.addHeader("X-Notification-Refresh", "true");
|
||||||
} else {
|
} else {
|
||||||
response.addHeader("X-Notification-Refresh", "false");
|
response.addHeader("X-Notification-Refresh", "false");
|
||||||
|
|||||||
+3
-30
@@ -18,46 +18,19 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.notification.eventandlistener;
|
package org.apache.fineract.notification.eventandlistener;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.apache.fineract.notification.data.NotificationData;
|
import org.apache.fineract.notification.data.NotificationData;
|
||||||
import org.apache.fineract.notification.service.NotificationWritePlatformService;
|
import org.apache.fineract.notification.service.UserNotificationService;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
|
||||||
import org.apache.fineract.useradministration.domain.AppUserRepository;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class NotificationEventListener {
|
public class NotificationEventListener {
|
||||||
|
|
||||||
private final NotificationWritePlatformService notificationWritePlatformService;
|
private final UserNotificationService userNotificationService;
|
||||||
private final AppUserRepository appUserRepository;
|
|
||||||
|
|
||||||
public void receive(NotificationData notificationData) {
|
public void receive(NotificationData notificationData) {
|
||||||
Long appUserId = notificationData.getActorId();
|
userNotificationService.notifyUsers(notificationData);
|
||||||
|
|
||||||
Set<Long> userIds = notificationData.getUserIds();
|
|
||||||
|
|
||||||
if (notificationData.getOfficeId() != null) {
|
|
||||||
List<Long> tempUserIds = new ArrayList<>(userIds);
|
|
||||||
for (Long userId : tempUserIds) {
|
|
||||||
AppUser appUser = appUserRepository.findById(userId).orElseThrow();
|
|
||||||
if (!Objects.equals(appUser.getOffice().getId(), notificationData.getOfficeId())) {
|
|
||||||
userIds.remove(userId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't notify the same user who triggered the event
|
|
||||||
if (userIds.contains(appUserId)) {
|
|
||||||
userIds.remove(appUserId);
|
|
||||||
}
|
|
||||||
|
|
||||||
notificationWritePlatformService.notify(userIds, notificationData.getObjectType(), notificationData.getObjectId(),
|
|
||||||
notificationData.getAction(), notificationData.getActorId(), notificationData.getContent(),
|
|
||||||
notificationData.isSystemGenerated());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-27
@@ -18,15 +18,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.notification.service;
|
package org.apache.fineract.notification.service;
|
||||||
|
|
||||||
import static java.util.stream.Collectors.toSet;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Set;
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||||
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
|
||||||
import org.apache.fineract.infrastructure.event.business.BusinessEventListener;
|
import org.apache.fineract.infrastructure.event.business.BusinessEventListener;
|
||||||
import org.apache.fineract.infrastructure.event.business.domain.client.ClientCreateBusinessEvent;
|
import org.apache.fineract.infrastructure.event.business.domain.client.ClientCreateBusinessEvent;
|
||||||
import org.apache.fineract.infrastructure.event.business.domain.deposit.FixedDepositAccountCreateBusinessEvent;
|
import org.apache.fineract.infrastructure.event.business.domain.deposit.FixedDepositAccountCreateBusinessEvent;
|
||||||
@@ -50,8 +45,6 @@ import org.apache.fineract.infrastructure.event.business.domain.share.ShareAccou
|
|||||||
import org.apache.fineract.infrastructure.event.business.domain.share.ShareProductDividentsCreateBusinessEvent;
|
import org.apache.fineract.infrastructure.event.business.domain.share.ShareProductDividentsCreateBusinessEvent;
|
||||||
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
|
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
|
||||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||||
import org.apache.fineract.notification.data.NotificationData;
|
|
||||||
import org.apache.fineract.notification.eventandlistener.NotificationEventPublisher;
|
|
||||||
import org.apache.fineract.portfolio.client.domain.Client;
|
import org.apache.fineract.portfolio.client.domain.Client;
|
||||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
|
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
|
||||||
@@ -62,8 +55,6 @@ import org.apache.fineract.portfolio.savings.domain.RecurringDepositAccount;
|
|||||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
|
import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
|
||||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransaction;
|
import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransaction;
|
||||||
import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccount;
|
import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccount;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
|
||||||
import org.apache.fineract.useradministration.domain.AppUserRepository;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@@ -73,8 +64,7 @@ public class NotificationDomainServiceImpl implements NotificationDomainService
|
|||||||
|
|
||||||
private final BusinessEventNotifierService businessEventNotifierService;
|
private final BusinessEventNotifierService businessEventNotifierService;
|
||||||
private final PlatformSecurityContext context;
|
private final PlatformSecurityContext context;
|
||||||
private final NotificationEventPublisher notificationEventPublisher;
|
private final UserNotificationService userNotificationService;
|
||||||
private final AppUserRepository appUserRepository;
|
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void addListeners() {
|
public void addListeners() {
|
||||||
@@ -327,22 +317,7 @@ public class NotificationDomainServiceImpl implements NotificationDomainService
|
|||||||
private void buildNotification(String permission, String objectType, Long objectIdentifier, String notificationContent,
|
private void buildNotification(String permission, String objectType, Long objectIdentifier, String notificationContent,
|
||||||
String eventType, Long appUserId, Long officeId) {
|
String eventType, Long appUserId, Long officeId) {
|
||||||
|
|
||||||
String tenantIdentifier = ThreadLocalContextUtil.getTenant().getTenantIdentifier();
|
userNotificationService.notifyUsers(permission, objectType, objectIdentifier, notificationContent, eventType, appUserId, officeId);
|
||||||
Set<Long> userIds = getNotifiableUserIds(officeId, permission);
|
|
||||||
NotificationData notificationData = new NotificationData().setObjectType(objectType).setObjectId(objectIdentifier)
|
|
||||||
.setAction(eventType).setActorId(appUserId).setContent(notificationContent).setRead(false).setSystemGenerated(false)
|
|
||||||
.setTenantIdentifier(tenantIdentifier).setOfficeId(officeId).setUserIds(userIds);
|
|
||||||
try {
|
|
||||||
notificationEventPublisher.broadcastNotification(notificationData);
|
|
||||||
} catch (Exception e) {
|
|
||||||
// We want to avoid rethrowing the exception to stop the business transaction from rolling back
|
|
||||||
log.error("Error while broadcasting notification event", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<Long> getNotifiableUserIds(Long officeId, String permission) {
|
|
||||||
Collection<AppUser> users = appUserRepository.findByOfficeId(officeId);
|
|
||||||
Collection<AppUser> usersWithPermission = users.stream().filter(aU -> aU.hasAnyPermission(permission, "ALL_FUNCTIONS")).toList();
|
|
||||||
return usersWithPermission.stream().map(AppUser::getId).collect(toSet());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
-3
@@ -22,9 +22,6 @@ import java.util.Collection;
|
|||||||
|
|
||||||
public interface NotificationWritePlatformService {
|
public interface NotificationWritePlatformService {
|
||||||
|
|
||||||
Long notify(Long userId, String objectType, Long objectId, String action, Long actorId, String notificationContent,
|
|
||||||
boolean isSystemGenerated);
|
|
||||||
|
|
||||||
Long notify(Collection<Long> userIds, String objectType, Long objectId, String action, Long actorId, String notificationContent,
|
Long notify(Collection<Long> userIds, String objectType, Long objectId, String action, Long actorId, String notificationContent,
|
||||||
boolean isSystemGenerated);
|
boolean isSystemGenerated);
|
||||||
}
|
}
|
||||||
|
|||||||
-20
@@ -40,26 +40,6 @@ public class NotificationWritePlatformServiceImpl implements NotificationWritePl
|
|||||||
private final AppUserRepository appUserRepository;
|
private final AppUserRepository appUserRepository;
|
||||||
private final NotificationMapperWritePlatformService notificationMapperWritePlatformService;
|
private final 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.findById(userId).orElse(null);
|
|
||||||
NotificationMapper notificationMapper = new NotificationMapper()
|
|
||||||
.setNotification(this.notificationGeneratorReadRepositoryWrapper.findById(generatedNotificationId)).setUserId(appUser)
|
|
||||||
.setRead(false).setCreatedAt(DateUtils.getLocalDateTimeOfSystem());
|
|
||||||
|
|
||||||
this.notificationMapperWritePlatformService.create(notificationMapper);
|
|
||||||
return notificationMapper.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Long insertIntoNotificationGenerator(String objectType, Long objectIdentifier, String action, Long actorId,
|
private Long insertIntoNotificationGenerator(String objectType, Long objectIdentifier, String action, Long actorId,
|
||||||
String notificationContent, boolean isSystemGenerated) {
|
String notificationContent, boolean isSystemGenerated) {
|
||||||
|
|
||||||
|
|||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* 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.data.NotificationData;
|
||||||
|
|
||||||
|
public interface UserNotificationService {
|
||||||
|
|
||||||
|
void notifyUsers(String permission, String objectType, Long objectIdentifier, String notificationContent, String eventType,
|
||||||
|
Long appUserId, Long officeId);
|
||||||
|
|
||||||
|
boolean hasUnreadUserNotifications(Long appUserId);
|
||||||
|
|
||||||
|
void notifyUsers(NotificationData notificationData);
|
||||||
|
}
|
||||||
+114
@@ -0,0 +1,114 @@
|
|||||||
|
/**
|
||||||
|
* 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 static java.util.stream.Collectors.toSet;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.fineract.infrastructure.core.config.FineractProperties;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
||||||
|
import org.apache.fineract.notification.data.NotificationData;
|
||||||
|
import org.apache.fineract.notification.eventandlistener.NotificationEventPublisher;
|
||||||
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
|
import org.apache.fineract.useradministration.domain.AppUserRepository;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
public class UserNotificationServiceImpl implements UserNotificationService {
|
||||||
|
|
||||||
|
private final NotificationEventPublisher notificationEventPublisher;
|
||||||
|
private final AppUserRepository appUserRepository;
|
||||||
|
private final FineractProperties fineractProperties;
|
||||||
|
private final NotificationReadPlatformService notificationReadPlatformService;
|
||||||
|
private final NotificationWritePlatformService notificationWritePlatformService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notifyUsers(String permission, String objectType, Long objectIdentifier, String notificationContent, String eventType,
|
||||||
|
Long appUserId, Long officeId) {
|
||||||
|
|
||||||
|
if (userNotificationSystemIsEnabled()) {
|
||||||
|
String tenantIdentifier = ThreadLocalContextUtil.getTenant().getTenantIdentifier();
|
||||||
|
Set<Long> userIds = getNotifiableUserIds(officeId, permission);
|
||||||
|
NotificationData notificationData = new NotificationData().setObjectType(objectType).setObjectId(objectIdentifier)
|
||||||
|
.setAction(eventType).setActorId(appUserId).setContent(notificationContent).setRead(false).setSystemGenerated(false)
|
||||||
|
.setTenantIdentifier(tenantIdentifier).setOfficeId(officeId).setUserIds(userIds);
|
||||||
|
try {
|
||||||
|
notificationEventPublisher.broadcastNotification(notificationData);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// We want to avoid rethrowing the exception to stop the business transaction from rolling back
|
||||||
|
log.error("Error while broadcasting notification event", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasUnreadUserNotifications(Long appUserId) {
|
||||||
|
if (userNotificationSystemIsEnabled()) {
|
||||||
|
return notificationReadPlatformService.hasUnreadNotifications(appUserId);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notifyUsers(NotificationData notificationData) {
|
||||||
|
if (userNotificationSystemIsEnabled()) {
|
||||||
|
Long appUserId = notificationData.getActorId();
|
||||||
|
|
||||||
|
Set<Long> userIds = notificationData.getUserIds();
|
||||||
|
|
||||||
|
if (notificationData.getOfficeId() != null) {
|
||||||
|
List<Long> tempUserIds = new ArrayList<>(userIds);
|
||||||
|
for (Long userId : tempUserIds) {
|
||||||
|
AppUser appUser = appUserRepository.findById(userId).orElseThrow();
|
||||||
|
if (!Objects.equals(appUser.getOffice().getId(), notificationData.getOfficeId())) {
|
||||||
|
userIds.remove(userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't notify the same user who triggered the event
|
||||||
|
if (userIds.contains(appUserId)) {
|
||||||
|
userIds.remove(appUserId);
|
||||||
|
}
|
||||||
|
|
||||||
|
notificationWritePlatformService.notify(userIds, notificationData.getObjectType(), notificationData.getObjectId(),
|
||||||
|
notificationData.getAction(), notificationData.getActorId(), notificationData.getContent(),
|
||||||
|
notificationData.isSystemGenerated());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean userNotificationSystemIsEnabled() {
|
||||||
|
return fineractProperties.getNotification().getUserNotificationSystem().isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<Long> getNotifiableUserIds(Long officeId, String permission) {
|
||||||
|
Collection<AppUser> users = appUserRepository.findByOfficeId(officeId);
|
||||||
|
Collection<AppUser> usersWithPermission = users.stream().filter(aU -> aU.hasAnyPermission(permission, "ALL_FUNCTIONS")).toList();
|
||||||
|
return usersWithPermission.stream().map(AppUser::getId).collect(toSet());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -102,6 +102,8 @@ fineract.report.export.s3.enabled=${FINERACT_REPORT_EXPORT_S3_ENABLED:false}
|
|||||||
|
|
||||||
fineract.jpa.statementLoggingEnabled=${FINERACT_STATEMENT_LOGGING_ENABLED:false}
|
fineract.jpa.statementLoggingEnabled=${FINERACT_STATEMENT_LOGGING_ENABLED:false}
|
||||||
|
|
||||||
|
fineract.notification.user-notification-system.enabled=${FINERACT_USER_NOTIFICATION_SYSTEM_ENABLED:true}
|
||||||
|
|
||||||
# Logging pattern for the console
|
# Logging pattern for the console
|
||||||
logging.pattern.console=${CONSOLE_LOG_PATTERN:%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(%replace([%X{correlationId}]){'\\[\\]', ''}) %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:%wEx}}
|
logging.pattern.console=${CONSOLE_LOG_PATTERN:%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(%replace([%X{correlationId}]){'\\[\\]', ''}) %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:%wEx}}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user