package ru.soune.nocopy.service.tariff; import jakarta.mail.MessagingException; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import ru.soune.nocopy.dto.tarriff.TariffInfoDTO; import ru.soune.nocopy.entity.company.Company; import ru.soune.nocopy.entity.tarif.Tariff; import ru.soune.nocopy.entity.tarif.TariffInfo; import ru.soune.nocopy.entity.tarif.TariffStatus; import ru.soune.nocopy.entity.tarif.TariffType; import ru.soune.nocopy.entity.tokenoperation.OperationType; import ru.soune.nocopy.entity.user.User; import ru.soune.nocopy.exception.TariffNotFoundException; import ru.soune.nocopy.repository.CompanyRepository; import ru.soune.nocopy.repository.TariffInfoRepository; import ru.soune.nocopy.repository.TariffRepository; import ru.soune.nocopy.repository.UserRepository; import ru.soune.nocopy.service.mail.EmailService; import ru.soune.nocopy.service.tokenoperation.TokenOperationService; import java.io.IOException; import java.time.LocalDateTime; import java.util.List; import java.util.stream.Collectors; @Service @AllArgsConstructor @Slf4j public class TariffInfoService { private TariffInfoRepository tariffInfoRepository; private TariffRepository tariffRepository; private UserRepository userRepository; private EmailService emailService; private TokenOperationService tokenOperationService; private CompanyRepository companyRepository; public TariffInfo createTariffInfo(LocalDateTime startTariff, LocalDateTime endTariff, TariffStatus tariffStatus, Integer tokens) { TariffInfo tariffInfo = new TariffInfo(); tariffInfo.setStartTariff(startTariff); tariffInfo.setStatus(tariffStatus); tariffInfo.setEndTariff(endTariff); tariffInfo.setTokens(tokens); tariffInfo.setBoughtTokens(0); return tariffInfoRepository.save(tariffInfo); } @Transactional public void writeOffTokens(long userId, Integer value, OperationType operationType) throws MessagingException, IOException { User user = userRepository.findById(userId).orElseThrow(); Company company = user.getCompany(); TariffInfo activeTariffInfo; if (company == null) { activeTariffInfo = user.getPersonalTariffInfo(); } else { activeTariffInfo = company.getTariffInfo(); } writeOffTokensForTariff(activeTariffInfo, value); tokenOperationService.create(operationType, userId, Long.valueOf(value)); } public void writeOffTokensForTariff(TariffInfo activeTariffInfo, Integer value) throws MessagingException, IOException { Integer tokens = activeTariffInfo.getTokens(); Integer boughtTokens = activeTariffInfo.getBoughtTokens(); if (tokens - value >= 0) { activeTariffInfo.setTokens(activeTariffInfo.getTokens() - value); tariffInfoRepository.save(activeTariffInfo); } else if (boughtTokens - value >= 0) { activeTariffInfo.setTokens(activeTariffInfo.getBoughtTokens() - value); tariffInfoRepository.save(activeTariffInfo); } else { int needTokens = boughtTokens - value; User user = userRepository.findByPersonalTariffInfo(activeTariffInfo); emailService.sendTokensNotFoundEmail(user, tokens, Math.abs(needTokens)); log.error("User:" + user.getId() + " not have tokens for protect"); throw new TariffNotFoundException("User not have tokens for protect"); } } public TariffInfo createTariffInfo(TariffType tariffType) { Tariff tariff = tariffRepository.findByType(tariffType.toString()).orElseThrow(); TariffInfo tariffInfo = createTariffInfo(LocalDateTime.now(), LocalDateTime.now().plusDays(tariff.getTariffTerm().getDays()), TariffStatus.ACTIVE, tariff.getTokens()); tariffInfo.setTariff(tariff); return tariffInfoRepository.save(tariffInfo); } public TariffInfo addTariffInfo(TariffInfo tariffInfo) { return tariffInfoRepository.save(tariffInfo); } public List getAllTariffInfos() { return tariffInfoRepository.findAll() .stream() .map(this::convertToInfoDTO) .collect(Collectors.toList()); } public TariffInfoDTO getTariffInfoById(String id) { return tariffInfoRepository.findById(id) .map(this::convertToInfoDTO) .orElseThrow(() -> new TariffNotFoundException("Tariff info not found")); } @Transactional public TariffInfoDTO createTariffInfo(TariffInfoDTO tariffInfoDTO) { TariffInfo tariffInfo = new TariffInfo(); updateTariffInfoFromDTO(tariffInfo, tariffInfoDTO); return convertToInfoDTO(tariffInfoRepository.save(tariffInfo)); } @Transactional public TariffInfoDTO updateTariffInfo(String id, TariffInfoDTO tariffInfoDTO) { TariffInfo tariffInfo = tariffInfoRepository.findById(id) .orElseThrow(() -> new TariffNotFoundException("Tariff not found")); updateTariffInfoFromDTO(tariffInfo, tariffInfoDTO); return convertToInfoDTO(tariffInfoRepository.save(tariffInfo)); } @Transactional public void deleteTariffInfo(String id) { tariffInfoRepository.deleteById(id); } private TariffInfoDTO convertToInfoDTO(TariffInfo tariffInfo) { return new TariffInfoDTO( tariffInfo.getId(), tariffInfo.getStatus().name(), tariffInfo.getStartTariff(), tariffInfo.getEndTariff(), tariffInfo.getTariff() != null ? tariffInfo.getTariff().getId() : null, tariffInfo.getTariff() != null ? tariffInfo.getTariff().getName() : null, tariffInfo.getTokens() + tariffInfo.getBoughtTokens(), tariffInfo.getTariff().getDiskSize(), 0L, 0, tariffInfo.getTariff().getMaxFilesCount()); } @Transactional public void linkUserTariffInfo(User user, TariffInfo tariffInfo) { user.setPersonalTariffInfo(tariffInfo); userRepository.save(user); } @Transactional public void linkCompanyTariffInfo(Long userId, TariffInfo tariffInfo) { User user = userRepository.findById(userId).orElse(null); log.info("user in link: " + user); log.info("Company: " + user.getCompany()); if (user.getCompany() != null) { Company company = user.getCompany(); company.setTariffInfo(tariffInfo); companyRepository.save(company); } } private void updateTariffInfoFromDTO(TariffInfo tariffInfo, TariffInfoDTO dto) { tariffInfo.setStatus(TariffStatus.valueOf(dto.getStatus())); tariffInfo.setStartTariff(dto.getStartTariff()); tariffInfo.setEndTariff(dto.getEndTariff()); if (dto.getTariffId() != null) { Tariff tariff = tariffRepository.findById(dto.getTariffId()) .orElseThrow(() -> new TariffNotFoundException("Tariff not found")); tariffInfo.setTariff(tariff); } } }