package ru.kayashov.bar.mapper; import lombok.RequiredArgsConstructor; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import ru.kayashov.bar.controller.dto.cocktail.CocktailForIngredientModalDto; import ru.kayashov.bar.controller.dto.cocktail.CocktailForListResponseDto; import ru.kayashov.bar.controller.dto.cocktail.CocktailModalDto; import ru.kayashov.bar.controller.dto.cocktail.RatingResponseDto; import ru.kayashov.bar.controller.dto.cocktail.ReceiptResponseDto; import ru.kayashov.bar.controller.dto.ingredient.IngredientSimpleResponseDto; import ru.kayashov.bar.model.entity.CocktailEntity; import ru.kayashov.bar.model.entity.IngredientEntity; import ru.kayashov.bar.model.entity.ReceiptEntity; import ru.kayashov.bar.model.entity.Visitor; import ru.kayashov.bar.repository.VisitorsRepository; import java.util.List; import java.util.stream.Collectors; @Component @RequiredArgsConstructor public class CocktailMapper { private final VisitorsRepository visitorsRepository; @Transactional public List cocktailsToDtoList(List cocktails, Boolean all, boolean withReceipts) { return cocktails.stream() .map(c -> cocktailToDto(c, withReceipts)) .toList(); } public CocktailForListResponseDto cocktailToFullDto(CocktailEntity e) { return CocktailForListResponseDto.builder() .id(e.getId()) .name(e.getName()) .image(e.getImage()) .category(e.getCategory().getName()) .alcoholic(e.getAlcoholic().getValue()) .glass(e.getGlass().getName()) .instructions(e.getInstructions()) .video(e.getVideo()) .receipt(createReceiptDtoList(e.getReceipt())) .build(); } private CocktailForListResponseDto cocktailToDto(CocktailEntity e, boolean withReceipts) { boolean hasError = false; int volume = 0; Float abv = 0f; Integer p = null; for (ReceiptEntity receipt : e.getReceipt()) { if (receipt.getCount() == null) { hasError = true; break; } if (receipt.getUnit() == null) { hasError = true; break; } if (!receipt.getUnit().getId().equals(74L) && abv != null) { abv = null; } if (abv != null) { IngredientEntity ingredient = receipt.getIngredient(); if (ingredient.getAlcohol() && ingredient.getAbv() == null) { hasError = true; break; } if (ingredient.getAlcohol()) { abv += ingredient.getAbv() * receipt.getCount(); } volume += receipt.getCount(); } } if (!hasError && abv != null) { p = Math.round(abv / volume); } return CocktailForListResponseDto.builder() .id(e.getId()) .name(e.getName()) .image(e.getImage()) .hasError(hasError) .volume(p) .category(e.getCategory().getName()) .alcoholic(e.getAlcoholic().getValue()) .glass(e.getGlass().getName()) .components(containCocktailComponents(e.getReceipt())) .rating(createRatingDto(e)) .isAllowed(e.getAllowed()) .receipt(!withReceipts ? null : e.getReceipt().stream().map(ReceiptResponseDto::mapToDto).toList()) .build(); } private RatingResponseDto createRatingDto(CocktailEntity entity) { RatingResponseDto result = new RatingResponseDto(); result.setRating(entity.getRating()); result.setFavourite(entity.getIsFavorite()); return result; } private String containCocktailComponents(List receipts) { return receipts.stream() .map(ReceiptEntity::getIngredient) .map(IngredientEntity::getName) .collect(Collectors.joining(", ")); } private Visitor getCurrentVisitor() { SecurityContext context = SecurityContextHolder.getContext(); Authentication authentication = context.getAuthentication(); Long visitorId; if (authentication.getPrincipal() instanceof Visitor) { visitorId = ((Visitor) authentication.getPrincipal()).getId(); } else { visitorId = 1L; } return visitorsRepository.findById(visitorId).orElseThrow(RuntimeException::new); } public CocktailModalDto cocktailToModalDto(CocktailEntity e) { return CocktailModalDto.builder() .id(e.getId()) .name(e.getName()) .image(e.getImage()) .instructions(e.getInstructions()) .rating(createRatingDto(e)) .receipt(createReceiptDtoList(e.getReceipt())) .build(); } private List createReceiptDtoList(List receipts) { return receipts.stream() .map(this::createReceiptDto) .toList(); } private ReceiptResponseDto createReceiptDto(ReceiptEntity e) { return ReceiptResponseDto.builder() .id(e.getId()) .ingredient(createIngredientResponseDto(e.getIngredient())) .count(e.getCount()) .unit(e.getUnit()) .measure(e.getMeasure()) .build(); } private IngredientSimpleResponseDto createIngredientResponseDto(IngredientEntity i) { return new IngredientSimpleResponseDto(i.getId(), i.getName(), i.getImage(), i.getIsHave()); } public CocktailForIngredientModalDto cocktailToIngredientDtoList(CocktailEntity e) { return CocktailForIngredientModalDto.builder() .id(e.getId()) .name(e.getName()) .image(e.getImage()) .rating(createRatingDto(e)) .build(); } }