completed group batch feature

This commit is contained in:
2026-06-08 09:18:06 +02:00
parent c87f1e5e23
commit 24f435a09f
60 changed files with 2006 additions and 323 deletions

View File

@@ -0,0 +1,158 @@
package zw.qantra.tm.domain.services;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import zw.qantra.tm.domain.models.Recipient;
import zw.qantra.tm.domain.models.RecipientGroup;
import zw.qantra.tm.domain.models.RecipientGroupMember;
import zw.qantra.tm.domain.repositories.RecipientGroupMemberRepository;
import zw.qantra.tm.domain.repositories.RecipientGroupRepository;
import zw.qantra.tm.domain.repositories.RecipientRepository;
import zw.qantra.tm.exceptions.ApiException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Service
@RequiredArgsConstructor
public class RecipientGroupService {
private final RecipientGroupRepository recipientGroupRepository;
private final RecipientGroupMemberRepository recipientGroupMemberRepository;
private final RecipientRepository recipientRepository;
@Transactional
public RecipientGroup create(RecipientGroup group, List<Recipient> recipients) {
RecipientGroup savedGroup = recipientGroupRepository.save(group);
if (recipients != null && !recipients.isEmpty()) {
addMembers(savedGroup.getId(), savedGroup.getUserId(), recipients);
}
return savedGroup;
}
@Transactional
public List<RecipientGroupMember> addMembers(UUID groupId, String userId, List<Recipient> recipients) {
get(groupId, userId);
List<RecipientGroupMember> added = new ArrayList<>();
for (Recipient incomingRecipient : recipients) {
Recipient recipient = resolveOrCreateRecipient(incomingRecipient, userId);
if (recipientGroupMemberRepository.existsByRecipientGroupIdAndRecipientId(groupId, recipient.getId())) {
continue;
}
RecipientGroupMember member = RecipientGroupMember.builder()
.recipientGroupId(groupId)
.recipientUid(recipient.getId())
.recipient(recipient)
.account(recipient.getAccount())
.userId(userId)
.build();
added.add(recipientGroupMemberRepository.save(member));
}
return added;
}
public Page<RecipientGroup> findAll(Specification<RecipientGroup> spec, Pageable pageable) {
return recipientGroupRepository.findAll(spec, pageable);
}
public List<RecipientGroup> list(String userId) {
return recipientGroupRepository.findAllByUserId(userId);
}
public RecipientGroup get(UUID groupId, String userId) {
return recipientGroupRepository.findByIdAndUserId(groupId, userId)
.orElseThrow(() -> new ApiException("Recipient group not found"));
}
public RecipientGroup update(UUID groupId, String userId, String name, String description) {
RecipientGroup group = get(groupId, userId);
group.setName(name);
group.setDescription(description);
return recipientGroupRepository.save(group);
}
@Transactional
public void delete(UUID groupId, String userId) {
RecipientGroup group = get(groupId, userId);
group.setDeleted(true);
recipientGroupRepository.save(group);
List<RecipientGroupMember> members = recipientGroupMemberRepository.findAllByRecipientGroupId(groupId);
members.forEach(member -> member.setDeleted(true));
recipientGroupMemberRepository.saveAll(members);
}
@Transactional
public List<RecipientGroupMember> addMembersByIds(UUID groupId, String userId, List<UUID> recipientIds) {
get(groupId, userId);
List<RecipientGroupMember> added = new ArrayList<>();
for (UUID recipientId : recipientIds) {
Recipient recipient = recipientRepository.findById(recipientId)
.orElseThrow(() -> new ApiException("Recipient not found: " + recipientId));
if (!userId.equals(recipient.getUserId())) {
throw new ApiException("Recipient does not belong to user");
}
if (recipientGroupMemberRepository.existsByRecipientGroupIdAndRecipientId(groupId, recipientId)) {
continue;
}
RecipientGroupMember member = RecipientGroupMember.builder()
.recipientGroupId(groupId)
.recipientUid(recipientId)
.recipient(recipient)
.account(recipient.getAccount())
.userId(userId)
.build();
added.add(recipientGroupMemberRepository.save(member));
}
return added;
}
private Recipient resolveOrCreateRecipient(Recipient incomingRecipient, String fallbackUserId) {
if (incomingRecipient == null || incomingRecipient.getAccount() == null || incomingRecipient.getAccount().isBlank()) {
throw new ApiException("Recipient account is required");
}
String recipientUserId = incomingRecipient.getUserId() == null || incomingRecipient.getUserId().isBlank()
? fallbackUserId
: incomingRecipient.getUserId();
List<Recipient> existing = recipientRepository.findByAccountAndUserId(incomingRecipient.getAccount(), recipientUserId);
if (!existing.isEmpty()) {
return existing.get(0);
}
incomingRecipient.setId(null);
incomingRecipient.setUserId(recipientUserId);
return recipientRepository.save(incomingRecipient);
}
@Transactional
public void removeMember(UUID groupId, UUID recipientId, String userId) {
get(groupId, userId);
List<RecipientGroupMember> members = recipientGroupMemberRepository.findAllByRecipientGroupId(groupId);
RecipientGroupMember target = members.stream()
.filter(item -> recipientId.equals(item.getRecipientUid()))
.findFirst()
.orElseThrow(() -> new ApiException("Group member not found"));
target.setDeleted(true);
recipientGroupMemberRepository.save(target);
}
public List<RecipientGroupMember> members(UUID groupId, String userId) {
get(groupId, userId);
return recipientGroupMemberRepository.findAllByRecipientGroupId(groupId);
}
public Page<RecipientGroupMember> findAllMembers(Specification<RecipientGroupMember> spec, Pageable pageable) {
return recipientGroupMemberRepository.findAll(spec, pageable);
}
}