UserNotificationPreference changes

This commit is contained in:
Efstratios Giannopoulos 2024-04-26 18:10:10 +03:00
parent b58dd531ff
commit b267f2f30c
15 changed files with 203 additions and 99 deletions

View File

@ -6,15 +6,16 @@ BEGIN
CREATE TABLE public."ntf_UserNotificationPreference"
(
id uuid NOT NULL,
"user" uuid NOT NULL,
"type" uuid NOT NULL,
"channel" smallint NOT NULL,
"ordinal" numeric NOT NULL,
"tenant" uuid,
"tenant" uuid NULL,
"created_at" timestamp without time zone NOT NULL,
"updated_at" timestamp without time zone NOT NULL,
"is_active" smallint NOT NULL DEFAULT 1,
CONSTRAINT "ntf_UserNotificationPreference_pkey" PRIMARY KEY ("user", "type", "channel"),
CONSTRAINT "ntf_UserNotificationPreference_pkey" PRIMARY KEY (id),
CONSTRAINT "ntf_UserNotificationPreference_tenant_fkey" FOREIGN KEY ("tenant")
REFERENCES public."ntf_Tenant" (id) MATCH SIMPLE
ON UPDATE NO ACTION

View File

@ -1,8 +1,9 @@
import { Guid } from '@common/types/guid';
import { NotificationType } from '@notification-service/core/enum/notification-type.enum';
import { NotificationContactType } from '../enum/notification-contact-type';
import { BaseEntity, BaseEntityPersist } from '@common/base/base-entity.model';
export interface UserNotificationPreference {
export interface UserNotificationPreference extends BaseEntity {
userId?: Guid;
type: NotificationType;
channel: NotificationContactType;
@ -10,7 +11,7 @@ export interface UserNotificationPreference {
createdAt?: Date;
}
export interface UserNotificationPreferencePersist {
export interface UserNotificationPreferencePersist extends BaseEntityPersist {
userId?: Guid;
notificationPreferences: { [key: string]: NotificationContactType[] };
}

View File

@ -4,6 +4,8 @@ import { NotificationType } from '@notification-service/core/enum/notification-t
import { NotificationContactType } from '../enum/notification-contact-type';
export class UserNotificationPreferenceLookup extends Lookup implements UserNotificationPreferenceFilter {
ids: Guid[];
excludedIds: Guid[];
userIds?: Guid[];
type?: NotificationType[];
channel?: NotificationContactType[];
@ -14,6 +16,8 @@ export class UserNotificationPreferenceLookup extends Lookup implements UserNoti
}
export interface UserNotificationPreferenceFilter {
ids: Guid[];
excludedIds: Guid[];
userIds?: Guid[];
type?: NotificationType[];
channel?: NotificationContactType[];

View File

@ -10,6 +10,7 @@ import { NotificationServiceEnumUtils } from '@notification-service/core/formatt
import { InAppNotificationService } from './http/inapp-notification.service';
import { NotificationService } from './http/notification-service';
import { NotificationTemplateService } from './http/notification-template.service';
import { TenantConfigurationService } from './http/tenant-configuration.service';
//
//
@ -38,6 +39,7 @@ export class CoreNotificationServiceModule {
NotificationService,
InAppNotificationService,
NotificationTemplateService,
TenantConfigurationService,
UserNotificationPreferenceService
],
};

View File

@ -4,8 +4,11 @@ import gr.cite.notification.audit.AuditableAction;
import gr.cite.notification.authorization.AuthorizationFlags;
import gr.cite.notification.common.enums.IsActive;
import gr.cite.notification.common.enums.TenantConfigurationType;
import gr.cite.notification.common.scope.tenant.TenantScope;
import gr.cite.notification.common.types.tenantconfiguration.NotifierListTenantConfigurationEntity;
import gr.cite.notification.data.TenantEntity;
import gr.cite.notification.data.UserNotificationPreferenceEntity;
import gr.cite.notification.event.TenantConfigurationTouchedEvent;
import gr.cite.notification.model.UserNotificationPreference;
import gr.cite.notification.model.builder.UserNotificationPreferenceBuilder;
import gr.cite.notification.model.censorship.UserNotificationPreferenceCensor;
@ -30,9 +33,12 @@ import gr.cite.tools.validation.ValidationFilterAnnotation;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.bind.annotation.*;
import jakarta.transaction.Transactional;
import javax.management.InvalidApplicationException;
import java.util.*;
@RestController
@ -46,6 +52,7 @@ public class UserNotificationPreferenceController {
private final CensorFactory censorFactory;
private final QueryFactory queryFactory;
private final MessageSource messageSource;
private final TenantScope tenantScope;
@Autowired
public UserNotificationPreferenceController(BuilderFactory builderFactory,
@ -53,13 +60,14 @@ public class UserNotificationPreferenceController {
UserNotificationPreferenceService userNotificationPreferenceService,
CensorFactory censorFactory,
QueryFactory queryFactory,
MessageSource messageSource) {
MessageSource messageSource, TenantScope tenantScope) {
this.builderFactory = builderFactory;
this.auditService = auditService;
this.userNotificationPreferenceService = userNotificationPreferenceService;
this.censorFactory = censorFactory;
this.queryFactory = queryFactory;
this.messageSource = messageSource;
this.tenantScope = tenantScope;
}
@PostMapping("query")
@ -80,7 +88,7 @@ public class UserNotificationPreferenceController {
@GetMapping("user/{userId}/current")
@Transactional
public List<UserNotificationPreference> current(@PathVariable UUID userId, FieldSet fieldSet, Locale locale) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
public List<UserNotificationPreference> current(@PathVariable UUID userId, FieldSet fieldSet, Locale locale) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException {
logger.debug(new MapLogEntry("retrieving" + UserNotificationPreference.class.getSimpleName()).And("userId", userId).And("fields", fieldSet));
this.censorFactory.censor(UserNotificationPreferenceCensor.class).censor(fieldSet, userId);
@ -89,6 +97,13 @@ public class UserNotificationPreferenceController {
ordering.addAscending(UserNotificationPreference._ordinal);
UserNotificationPreferenceQuery query = this.queryFactory.query(UserNotificationPreferenceQuery.class).userId(userId).isActives(IsActive.Active);
query.setOrder(ordering);
if (this.tenantScope.isMultitenant() && this.tenantScope.isSet()) {
if (!this.tenantScope.isDefaultTenant()) {
query.tenantIsSet(true).tenantIds(this.tenantScope.getTenant());
} else {
query.tenantIsSet(false);
}
}
List<UserNotificationPreference> model = this.builderFactory.builder(UserNotificationPreferenceBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(fieldSet, query.collectAs(fieldSet));
this.auditService.track(AuditableAction.User_Notification_Preference_Lookup, Map.ofEntries(

View File

@ -2,7 +2,6 @@ package gr.cite.notification.data;
import gr.cite.notification.common.enums.IsActive;
import gr.cite.notification.common.enums.NotificationContactType;
import gr.cite.notification.data.composite.CompositeUserNotificationPreferenceId;
import gr.cite.notification.data.conventers.IsActiveConverter;
import gr.cite.notification.data.conventers.NotificationContactTypeConverter;
import gr.cite.notification.data.tenant.TenantScopedBaseEntity;
@ -13,22 +12,23 @@ import java.util.UUID;
@Entity
@Table(name = "\"UserNotificationPreference\"")
@IdClass(CompositeUserNotificationPreferenceId.class)
public class UserNotificationPreferenceEntity extends TenantScopedBaseEntity {
@Id
@Column(name = "id", columnDefinition = "uuid", updatable = false, nullable = false)
private UUID id;
public static final String _id = "id";
@Column(name = "user", columnDefinition = "uuid", nullable = false)
private UUID userId;
public static final String _userId = "userId";
@Id
@Column(name = "type", columnDefinition = "uuid", nullable = false)
private UUID type;
public static final String _type = "type";
@Id
@Column(name = "channel", nullable = false)
@Convert(converter = NotificationContactTypeConverter.class)
private NotificationContactType channel;
@ -56,6 +56,14 @@ public class UserNotificationPreferenceEntity extends TenantScopedBaseEntity {
public static final String _isActive = "isActive";
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public UUID getUserId() {
return userId;
}

View File

@ -1,45 +0,0 @@
package gr.cite.notification.data.composite;
import gr.cite.notification.common.enums.NotificationContactType;
import java.io.Serializable;
import java.util.UUID;
public class CompositeUserNotificationPreferenceId implements Serializable {
private UUID userId;
private UUID type;
private NotificationContactType channel;
public CompositeUserNotificationPreferenceId() {
}
public CompositeUserNotificationPreferenceId(UUID userId, UUID type, NotificationContactType channel) {
this.userId = userId;
this.type = type;
this.channel = channel;
}
public UUID getUserId() {
return userId;
}
public void setUserId(UUID userId) {
this.userId = userId;
}
public UUID getType() {
return type;
}
public void setType(UUID type) {
this.type = type;
}
public NotificationContactType getChannel() {
return channel;
}
public void setChannel(NotificationContactType channel) {
this.channel = channel;
}
}

View File

@ -8,6 +8,10 @@ import java.util.UUID;
public class UserNotificationPreference {
private UUID id;
public static final String _id = "id";
private UUID userId;
public static final String _userId = "userId";
@ -40,6 +44,14 @@ public class UserNotificationPreference {
public static final String _isActive = "isActive";
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public UUID getUserId() {
return userId;
}

View File

@ -42,6 +42,7 @@ public class UserNotificationPreferenceBuilder extends BaseBuilder<UserNotificat
List<UserNotificationPreference> models = new ArrayList<>();
for(UserNotificationPreferenceEntity d : data){
UserNotificationPreference m = new UserNotificationPreference();
if(fields.hasField(this.asIndexer(UserNotificationPreference._id))) m.setId(d.getId());
if(fields.hasField(this.asIndexer(UserNotificationPreference._userId))) m.setUserId(d.getUserId());
if(fields.hasField(this.asIndexer(UserNotificationPreference._tenantId))) m.setTenantId(d.getTenantId());
if(fields.hasField(this.asIndexer(UserNotificationPreference._type))) m.setType(d.getType());

View File

@ -2,6 +2,8 @@ package gr.cite.notification.query;
import gr.cite.notification.common.enums.IsActive;
import gr.cite.notification.common.enums.NotificationContactType;
import gr.cite.notification.data.TenantConfigurationEntity;
import gr.cite.notification.data.UserCredentialEntity;
import gr.cite.notification.data.UserNotificationPreferenceEntity;
import gr.cite.notification.model.UserNotificationPreference;
import gr.cite.tools.data.query.FieldResolver;
@ -15,15 +17,16 @@ import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.*;
@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class UserNotificationPreferenceQuery extends QueryBase<UserNotificationPreferenceEntity> {
private Collection<UUID> ids;
private Collection<UUID> excludedIds;
private List<UUID> userId;
private List<IsActive> isActives;
@ -32,6 +35,58 @@ public class UserNotificationPreferenceQuery extends QueryBase<UserNotificationP
private List<NotificationContactType> channel;
private Collection<UUID> tenantIds;
private Boolean tenantIsSet;
public UserNotificationPreferenceQuery ids(UUID value) {
this.ids = List.of(value);
return this;
}
public UserNotificationPreferenceQuery ids(UUID... value) {
this.ids = Arrays.asList(value);
return this;
}
public UserNotificationPreferenceQuery ids(Collection<UUID> values) {
this.ids = values;
return this;
}
public UserNotificationPreferenceQuery tenantIds(UUID value) {
this.tenantIds = List.of(value);
return this;
}
public UserNotificationPreferenceQuery tenantIds(UUID... value) {
this.tenantIds = Arrays.asList(value);
return this;
}
public UserNotificationPreferenceQuery tenantIds(Collection<UUID> values) {
this.tenantIds = values;
return this;
}
public UserNotificationPreferenceQuery tenantIsSet(Boolean values) {
this.tenantIsSet = values;
return this;
}
public UserNotificationPreferenceQuery excludedIds(Collection<UUID> values) {
this.excludedIds = values;
return this;
}
public UserNotificationPreferenceQuery excludedIds(UUID value) {
this.excludedIds = List.of(value);
return this;
}
public UserNotificationPreferenceQuery excludedIds(UUID... value) {
this.excludedIds = Arrays.asList(value);
return this;
}
public UserNotificationPreferenceQuery userId(UUID... userId) {
this.userId = List.of(userId);
return this;
@ -74,7 +129,7 @@ public class UserNotificationPreferenceQuery extends QueryBase<UserNotificationP
@Override
protected Boolean isFalseQuery() {
return this.isNullOrEmpty(this.userId) && this.isNullOrEmpty(this.type) && this.isNullOrEmpty(this.channel);
return this.isEmpty(this.ids) || this.isEmpty(this.tenantIds) ||this.isEmpty(this.excludedIds) ||this.isNullOrEmpty(this.userId) && this.isNullOrEmpty(this.type) && this.isNullOrEmpty(this.channel);
}
@Override
@ -85,6 +140,28 @@ public class UserNotificationPreferenceQuery extends QueryBase<UserNotificationP
@Override
protected <X, Y> Predicate applyFilters(QueryContext<X, Y> queryContext) {
List<Predicate> predicates = new ArrayList<>();
if (this.ids != null) {
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(UserNotificationPreferenceEntity._id));
for (UUID item : this.ids)
inClause.value(item);
predicates.add(inClause);
}
if (this.excludedIds != null) {
CriteriaBuilder.In<UUID> notInClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(UserNotificationPreferenceEntity._id));
for (UUID item : this.excludedIds)
notInClause.value(item);
predicates.add(notInClause.not());
}
if (this.tenantIds != null) {
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(UserNotificationPreferenceEntity._tenantId));
for (UUID item : this.tenantIds) inClause.value(item);
predicates.add(inClause);
}
if (this.tenantIsSet != null) {
if (this.tenantIsSet) predicates.add(queryContext.CriteriaBuilder.isNotNull(queryContext.Root.get(UserNotificationPreferenceEntity._tenantId)));
else predicates.add(queryContext.CriteriaBuilder.isNull(queryContext.Root.get(UserNotificationPreferenceEntity._tenantId)));
}
if (this.userId != null) {
predicates.add(queryContext.Root.get(UserNotificationPreferenceEntity._userId).in(this.userId));
}
@ -119,6 +196,8 @@ public class UserNotificationPreferenceQuery extends QueryBase<UserNotificationP
protected String fieldNameOf(FieldResolver item) {
if (item.match(UserNotificationPreference._userId))
return UserNotificationPreferenceEntity._userId;
else if (item.match(UserNotificationPreference._id))
return UserNotificationPreferenceEntity._id;
else if (item.match(UserNotificationPreference._tenantId))
return UserNotificationPreferenceEntity._tenantId;
else if (item.match(UserNotificationPreference._type))
@ -140,6 +219,7 @@ public class UserNotificationPreferenceQuery extends QueryBase<UserNotificationP
@Override
protected UserNotificationPreferenceEntity convert(Tuple tuple, Set<String> columns) {
UserNotificationPreferenceEntity item = new UserNotificationPreferenceEntity();
item.setId(QueryBase.convertSafe(tuple, columns, UserNotificationPreferenceEntity._id, UUID.class));
item.setUserId(QueryBase.convertSafe(tuple, columns, UserNotificationPreferenceEntity._userId, UUID.class));
item.setChannel(QueryBase.convertSafe(tuple, columns, UserNotificationPreferenceEntity._channel, NotificationContactType.class));
item.setType(QueryBase.convertSafe(tuple, columns, UserNotificationPreferenceEntity._type, UUID.class));

View File

@ -12,6 +12,8 @@ import java.util.List;
import java.util.UUID;
public class UserNotificationPreferenceLookup extends Lookup {
private List<UUID> ids;
private List<UUID> excludedIds;
private List<UUID> userId;
private List<UUID> type;
private List<NotificationContactType> channel;
@ -45,6 +47,8 @@ public class UserNotificationPreferenceLookup extends Lookup {
if (this.userId != null) query.userId(this.userId);
if (this.channel != null) query.channel(this.channel);
if (this.type != null) query.type(this.type);
if (this.ids != null) query.ids(this.ids);
if (this.excludedIds != null) query.excludedIds(this.excludedIds);
this.enrichCommon(query);

View File

@ -15,6 +15,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.web.context.annotation.RequestScope;
import javax.management.InvalidApplicationException;
import java.util.*;
import java.util.stream.Collectors;
@ -104,7 +105,12 @@ public class ChannelResolutionServiceImpl implements ChannelResolutionService{
private Map<UUID, List<NotificationContactType>> lookupOrCollectUserPolicies(List<UUID> users, UUID type) {
Map<UUID, List<NotificationContactType>> contactsByUser = new HashMap<>();
Map<UUID, List<UserNotificationPreference>> userNotificationPreferences = this.userNotificationPreferenceService.collectUserNotificationPreferences(users);
Map<UUID, List<UserNotificationPreference>> userNotificationPreferences = null;
try {
userNotificationPreferences = this.userNotificationPreferenceService.collectUserNotificationPreferences(users);
} catch (InvalidApplicationException e) {
throw new RuntimeException(e);
}
for (Map.Entry<UUID, List<UserNotificationPreference>> notificationPreference: userNotificationPreferences.entrySet())
{
contactsByUser.put(notificationPreference.getKey(), notificationPreference.getValue().stream().filter(x -> x.getType() != null && x.getType() == type && x.getChannel() != null).sorted(Comparator.comparingInt(x -> x.getOrdinal())).map(x -> x.getChannel()).collect(Collectors.toList()));

View File

@ -73,6 +73,7 @@ public class NotificationServiceImpl implements NotificationService {
private final NotifierFactory notifierFactory;
private final ApplicationContext applicationContext;
private final QueryFactory queryFactory;
private final TenantScope tenantScope;
@Autowired
public NotificationServiceImpl(
@ -83,7 +84,7 @@ public class NotificationServiceImpl implements NotificationService {
ConventionService conventionService,
ErrorThesaurusProperties errors,
MessageSource messageSource,
ChannelResolutionService channelResolutionService, MessageBuilderFactory messageBuilderFactory, ContactExtractorFactory contactExtractorFactory, NotifierFactory notifierFactory, ApplicationContext applicationContext, QueryFactory queryFactory) {
ChannelResolutionService channelResolutionService, MessageBuilderFactory messageBuilderFactory, ContactExtractorFactory contactExtractorFactory, NotifierFactory notifierFactory, ApplicationContext applicationContext, QueryFactory queryFactory, TenantScope tenantScope) {
this.entityManager = entityManager;
this.authService = authService;
this.deleterFactory = deleterFactory;
@ -97,6 +98,7 @@ public class NotificationServiceImpl implements NotificationService {
this.notifierFactory = notifierFactory;
this.applicationContext = applicationContext;
this.queryFactory = queryFactory;
this.tenantScope = tenantScope;
}
@Override
@ -146,6 +148,7 @@ public class NotificationServiceImpl implements NotificationService {
public SendNotificationResult doNotify(NotificationEntity notification) {
List<NotificationContactType> contactTypes = this.orderContactTypesFromPreferences(notification);
if (this.conventionService.isListNullOrEmpty(contactTypes)) contactTypes = this.orderContactTypes(notification);
if (contactTypes == null) return null;
for (NotificationContactType contactType: contactTypes) {
SendNotificationResult result = this.sendNotification(notification, contactType);
@ -160,8 +163,14 @@ public class NotificationServiceImpl implements NotificationService {
UserNotificationPreferenceQuery query = this.queryFactory.query(UserNotificationPreferenceQuery.class).userId(notification.getUserId()).type(notification.getType()).isActives(IsActive.Active);
query.setOrder(ordering);
List<UserNotificationPreferenceEntity> preferences = query.collectAs(new BaseFieldSet().ensure(UserNotificationPreference._channel));
if (!this.conventionService.isListNullOrEmpty(preferences)) return preferences.stream().map(x -> x.getChannel()).collect(Collectors.toList());
List<UserNotificationPreferenceEntity> preferences = query.collectAs(new BaseFieldSet().ensure(UserNotificationPreference._channel).ensure(UserNotificationPreference._tenantId).ensure(UserNotificationPreference._id));
if (!this.conventionService.isListNullOrEmpty(preferences)) return preferences.stream().filter(x -> {
try {
return !this.tenantScope.isMultitenant() || this.tenantScope.isDefaultTenant() ? x.getTenantId() == null : x.getTenantId() == this.tenantScope.getTenant();
} catch (InvalidApplicationException e) {
throw new RuntimeException(e);
}
}).map(UserNotificationPreferenceEntity::getChannel).collect(Collectors.toList());
return null;
}

View File

@ -5,6 +5,7 @@ import gr.cite.notification.model.UserNotificationPreference;
import gr.cite.notification.model.persist.UserNotificationPreferencePersist;
import gr.cite.tools.fieldset.FieldSet;
import javax.management.InvalidApplicationException;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -14,6 +15,6 @@ public interface UserNotificationPreferenceService {
List<UserNotificationPreference> persist(UserNotificationPreferencePersist model, FieldSet fieldSet);
NotifierListTenantConfigurationEntity collectUserAvailableNotifierList(Set<UUID> notificationTypes);
List<UserNotificationPreference> collectUserNotificationPreferences(UUID id);
Map<UUID, List<UserNotificationPreference>> collectUserNotificationPreferences(List<UUID> ids);
List<UserNotificationPreference> collectUserNotificationPreferences(UUID id) throws InvalidApplicationException;
Map<UUID, List<UserNotificationPreference>> collectUserNotificationPreferences(List<UUID> ids) throws InvalidApplicationException;
}

View File

@ -117,7 +117,7 @@ public class UserNotificationPreferenceServiceImpl implements UserNotificationPr
}
@Override
public List<UserNotificationPreference> collectUserNotificationPreferences(UUID id) {
public List<UserNotificationPreference> collectUserNotificationPreferences(UUID id) throws InvalidApplicationException {
Map<UUID, List<UserNotificationPreference>> result = this.collectUserNotificationPreferences(List.of(id));
if (result != null) {
return result.values().stream().flatMap(Collection::stream).collect(Collectors.toList());
@ -127,18 +127,20 @@ public class UserNotificationPreferenceServiceImpl implements UserNotificationPr
}
@Override
public Map<UUID, List<UserNotificationPreference>> collectUserNotificationPreferences(List<UUID> ids) {
public Map<UUID, List<UserNotificationPreference>> collectUserNotificationPreferences(List<UUID> ids) throws InvalidApplicationException {
UserNotificationPreferenceQuery query = this.queryFactory
.query(UserNotificationPreferenceQuery.class)
.userId(ids);
if (this.tenantScope.isMultitenant() && this.tenantScope.isSet()) {
if (!this.tenantScope.isDefaultTenant()) {
query.tenantIsSet(true).tenantIds(this.tenantScope.getTenant());
} else {
query.tenantIsSet(false);
}
}
return this.builderFactory.builder(UserNotificationPreferenceBuilder.class)
.build(new BaseFieldSet(UserNotificationPreference._userId, UserNotificationPreference._type,
UserNotificationPreference._channel, UserNotificationPreference._ordinal), this.queryFactory
.query(UserNotificationPreferenceQuery.class)
.userId(ids).collect()).stream().filter(x -> {
try {
return !this.tenantScope.isMultitenant() || this.tenantScope.isDefaultTenant() ? x.getTenantId() == null : x.getTenantId() == this.tenantScope.getTenant();
} catch (InvalidApplicationException e) {
throw new RuntimeException(e);
}
})
UserNotificationPreference._channel, UserNotificationPreference._ordinal, UserNotificationPreference._tenantId, UserNotificationPreference._id), query.collect()).stream()
.collect(Collectors.groupingBy(UserNotificationPreference::getUserId)); //GK: Yep that exist on JAVA Streams
}
@ -178,22 +180,24 @@ public class UserNotificationPreferenceServiceImpl implements UserNotificationPr
{
List<UserNotificationPreferenceEntity> preferences = null;
try {
preferences = this.queryFactory
UserNotificationPreferenceQuery query = this.queryFactory
.query(UserNotificationPreferenceQuery.class)
.type(type)
.isActives(IsActive.Active)
.userId(userId).collect();
.userId(userId);
if (this.tenantScope.isMultitenant() && this.tenantScope.isSet()) {
if (!this.tenantScope.isDefaultTenant()) {
query.tenantIsSet(true).tenantIds(this.tenantScope.getTenant());
} else {
query.tenantIsSet(false);
}
}
preferences = query.collect();
int ordinal = 0;
List<UserNotificationPreferenceEntity> updatedPreferences = new ArrayList<>();
for (NotificationContactType contactType : contactTypes) {
UserNotificationPreferenceEntity preference = preferences.stream().filter(x -> {
try {
return x.getChannel() == contactType && (!this.tenantScope.isMultitenant() ||this.tenantScope.isDefaultTenant() ? x.getTenantId() == null : x.getTenantId() == this.tenantScope.getTenant());
} catch (InvalidApplicationException e) {
throw new RuntimeException(e);
}
}).findFirst().orElse(null);
UserNotificationPreferenceEntity preference = preferences.stream().filter(x -> x.getChannel() == contactType).findFirst().orElse(null);
boolean isUpdate = preference != null;
if (preference != null) {
@ -201,6 +205,7 @@ public class UserNotificationPreferenceServiceImpl implements UserNotificationPr
} else {
preference = new UserNotificationPreferenceEntity();
preference.setId(UUID.randomUUID());
preference.setUserId(userId);
preference.setType(type);
preference.setOrdinal(ordinal);
@ -215,7 +220,7 @@ public class UserNotificationPreferenceServiceImpl implements UserNotificationPr
updatedPreferences.add(preference);
ordinal++;
}
List<UserNotificationPreferenceEntity> toDelete = preferences.stream().filter(x -> !updatedPreferences.stream().map(y-> y.getChannel()).collect(Collectors.toList()).contains(x.getChannel())).collect(Collectors.toList());
List<UserNotificationPreferenceEntity> toDelete = preferences.stream().filter(x -> !updatedPreferences.stream().map(UserNotificationPreferenceEntity::getChannel).toList().contains(x.getChannel())).toList();
for (UserNotificationPreferenceEntity deletable: toDelete) {
this.entityManager.remove(deletable);
}