121 lines
4.9 KiB
Java
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
|
|
) {}
|
|
}
|