Files
cannamanage/cannamanage-service/src/main/java/de/cannamanage/service/ClubService.java
T
2026-06-11 16:56:44 +02:00

121 lines
4.9 KiB
Java

package de.cannamanage.service;
import de.cannamanage.domain.entity.Club;
import de.cannamanage.domain.enums.BatchStatus;
import de.cannamanage.domain.enums.MemberStatus;
import de.cannamanage.service.repository.BatchRepository;
import de.cannamanage.service.repository.ClubRepository;
import de.cannamanage.service.repository.DistributionRepository;
import de.cannamanage.service.repository.MemberRepository;
import de.cannamanage.service.repository.StaffAccountRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.server.ResponseStatusException;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneOffset;
import java.util.UUID;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
@Slf4j
@Service
@RequiredArgsConstructor
public class ClubService {
private final ClubRepository clubRepository;
private final MemberRepository memberRepository;
private final StaffAccountRepository staffAccountRepository;
private final DistributionRepository distributionRepository;
private final BatchRepository batchRepository;
@Transactional(readOnly = true)
public Club getClubByTenantId(UUID tenantId) {
return clubRepository.findByTenantId(tenantId)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Club not found for tenant"));
}
@Transactional
public Club updateClub(UUID tenantId, String name, String registrationNumber,
String contactEmail, String contactPhone,
String addressStreet, String addressCity,
String addressPostalCode, String addressState,
LocalDate foundedDate,
Integer maxPreventionOfficers, String allowedEmailPattern) {
Club club = getClubByTenantId(tenantId);
// Validate regex pattern if provided
if (allowedEmailPattern != null && !allowedEmailPattern.isBlank()) {
validateRegexPattern(allowedEmailPattern);
}
club.setName(name);
club.setRegistrationNumber(registrationNumber);
club.setContactEmail(contactEmail);
club.setContactPhone(contactPhone);
club.setAddressStreet(addressStreet);
club.setAddressCity(addressCity);
club.setAddressPostalCode(addressPostalCode);
club.setAddressState(addressState);
club.setFoundedDate(foundedDate);
if (maxPreventionOfficers != null) {
club.setMaxPreventionOfficers(maxPreventionOfficers);
}
club.setAllowedEmailPattern(allowedEmailPattern);
return clubRepository.save(club);
}
@Transactional(readOnly = true)
public ClubStats getClubStats(UUID tenantId) {
long totalMembers = memberRepository.countByTenantId(tenantId);
long activeMembers = memberRepository.countByTenantIdAndStatus(tenantId, MemberStatus.ACTIVE);
long totalStaff = staffAccountRepository.countByTenantId(tenantId);
long activeStaff = staffAccountRepository.countByTenantIdAndActiveTrue(tenantId);
// Distributions this month
Instant startOfMonth = LocalDate.now().withDayOfMonth(1)
.atStartOfDay(ZoneOffset.UTC).toInstant();
long totalDistributionsThisMonth = distributionRepository
.countByTenantIdAndDistributedAtAfter(tenantId, startOfMonth);
BigDecimal totalGramsThisMonth = distributionRepository
.sumGramsByTenantIdAndDistributedAtAfter(tenantId, startOfMonth);
long activeBatches = batchRepository.countByTenantIdAndStatus(tenantId, BatchStatus.AVAILABLE);
long preventionOfficerCount = staffAccountRepository.countByTenantIdAndPreventionOfficerTrue(tenantId);
return new ClubStats(
totalMembers, activeMembers,
totalStaff, activeStaff,
totalDistributionsThisMonth,
totalGramsThisMonth != null ? totalGramsThisMonth : BigDecimal.ZERO,
activeBatches, preventionOfficerCount
);
}
private void validateRegexPattern(String pattern) {
try {
Pattern.compile(pattern);
} catch (PatternSyntaxException e) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST,
"Invalid regex pattern for allowedEmailPattern: " + e.getDescription());
}
}
public record ClubStats(
long totalMembers,
long activeMembers,
long totalStaff,
long activeStaff,
long totalDistributionsThisMonth,
BigDecimal totalGramsDistributedThisMonth,
long activeBatches,
long preventionOfficerCount
) {}
}