Compare commits

...

7 Commits

15 changed files with 183 additions and 111 deletions

View File

@@ -19,7 +19,7 @@ export function BarChangePage() {
const [bars, setBars] = useState([]) const [bars, setBars] = useState([])
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
const [oldId, setOldId] = useState(null); const [oldId, setOldId] = useState(null);
const {createError, createSuccess, createWarning, notImplement} = useAlert(); const {createError, createSuccess, createWarning} = useAlert();
const createHandler = (id, name) => { const createHandler = (id, name) => {
if (id) { if (id) {
@@ -29,6 +29,7 @@ export function BarChangePage() {
} }
} }
// eslint-disable-next-line
useEffect(() => barClient.getBarList(setBars, createError), []); useEffect(() => barClient.getBarList(setBars, createError), []);
return (<> return (<>

View File

@@ -9,7 +9,7 @@ import {Counter} from "./Counter";
export function CocktailItemCalc({cocktail, deleteHandler, changeHandler}) { export function CocktailItemCalc({cocktail, deleteHandler, changeHandler}) {
return ( return (
<Card sx={{mb: 1, height: '250px', display: 'relative', p: 2}}> <Card sx={{mb: 1, display: 'relative', p: 2}}>
<Stack justifyContent={'start'} spacing={2}> <Stack justifyContent={'start'} spacing={2}>
<Stack direction='row' justifyContent='start' alignItems='center'> <Stack direction='row' justifyContent='start' alignItems='center'>
<Box sx={{width: '100px', height: '100px'}}> <Box sx={{width: '100px', height: '100px'}}>

View File

@@ -3,7 +3,7 @@ import {Box, TextField, Button} from '@mui/material';
import {styled} from '@mui/material/styles'; import {styled} from '@mui/material/styles';
// Стилизуем контейнер счетчика // Стилизуем контейнер счетчика
const CounterContainer = styled(Box)` styled(Box)`
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;

View File

@@ -35,7 +35,8 @@ const CocktailsPageContent = () => {
const {createError, createSuccess} = useAlert(); const {createError, createSuccess} = useAlert();
const [rows, setRows] = useState([]); const [rows, setRows] = useState([]);
const [filter, setFilter] = useState(emptyFilter) const [filter, setFilter] = useState(emptyFilter)
const [chips, setChips] = useState([]) // const [chips, setChips] = useState([])
const chips = [];
const [page, setPage] = useState(-1); const [page, setPage] = useState(-1);
const [load, setLoad] = useState(false); const [load, setLoad] = useState(false);
const [isEnd, setIsEnd] = useState(false); const [isEnd, setIsEnd] = useState(false);
@@ -63,6 +64,7 @@ const CocktailsPageContent = () => {
return () => window.removeEventListener('scroll', handleScroll); return () => window.removeEventListener('scroll', handleScroll);
// eslint-disable-next-line // eslint-disable-next-line
}, [loading]); }, [loading]);
// eslint-disable-next-line
useEffect(() => loading(), [filter]) useEffect(() => loading(), [filter])
const renderSkeleton = () => { const renderSkeleton = () => {
@@ -122,6 +124,13 @@ const CocktailsPageContent = () => {
const handleSelectCocktail = (row) => selectCocktail(row.id) const handleSelectCocktail = (row) => selectCocktail(row.id)
const deleteHandle = (row) => cocktailClient.deleteCocktail(row.id, rows, setRows, createSuccess, createError) const deleteHandle = (row) => cocktailClient.deleteCocktail(row.id, rows, setRows, createSuccess, createError)
const hideHandler = (id) => {
cocktailClient.hiddenCocktail(id)
.then(() => {
createSuccess("Коктейль скрыт успешно");
setRows(rows.filter((r) => r.id !== id))
}).catch(() => createError("Ошибка при попытке скрыть коктейль"))
}
return ( return (
<Box> <Box>
@@ -156,6 +165,7 @@ const CocktailsPageContent = () => {
handleChangeRating={handleChangeRating} handleChangeRating={handleChangeRating}
handleSelect={handleSelectCocktail} handleSelect={handleSelectCocktail}
deleteHandler={deleteHandle} deleteHandler={deleteHandle}
hideHandler={hideHandler}
/> />
) )
})} })}

View File

@@ -81,6 +81,7 @@ export function EditCocktailPage() {
// eslint-disable-next-line // eslint-disable-next-line
}, []); }, []);
// eslint-disable-next-line
useEffect(() => cocktailClient.getOneCocktail(selected, setCocktail, getError, emptyCocktail), [selected]) useEffect(() => cocktailClient.getOneCocktail(selected, setCocktail, getError, emptyCocktail), [selected])
const saveHandler = () => cocktailClient.saveChangeCocktail(cocktail, createError, createSuccess) const saveHandler = () => cocktailClient.saveChangeCocktail(cocktail, createError, createSuccess)
const deleteHandle = () => cocktailClient.deleteCocktailFromEdit(setCocktails, setCocktail, createError, cocktails, cocktail, emptyCocktail) const deleteHandle = () => cocktailClient.deleteCocktailFromEdit(setCocktails, setCocktail, createError, cocktails, cocktail, emptyCocktail)

View File

@@ -10,6 +10,7 @@ import {CocktailDescription} from "./CocktailDescription";
import EditIcon from '@mui/icons-material/Edit'; import EditIcon from '@mui/icons-material/Edit';
import DeleteIcon from '@mui/icons-material/Delete'; import DeleteIcon from '@mui/icons-material/Delete';
import LocalBarIcon from '@mui/icons-material/LocalBar'; import LocalBarIcon from '@mui/icons-material/LocalBar';
import VisibilityOffIcon from '@mui/icons-material/VisibilityOff';
import {paths} from "../../path"; import {paths} from "../../path";
import {useAlert} from "../../hooks/useAlert"; import {useAlert} from "../../hooks/useAlert";
import {useUser} from "../../hooks/useUser"; import {useUser} from "../../hooks/useUser";
@@ -35,7 +36,7 @@ function renderRating(handleChangeRating, row) {
) )
} }
export function Cocktail({row, handleFavourite, handleChangeRating, handleSelect, deleteHandler}) { export function Cocktail({row, handleFavourite, handleChangeRating, handleSelect, deleteHandler, hideHandler}) {
const {createError, createSuccess} = useAlert(); const {createError, createSuccess} = useAlert();
const {user} = useUser(); const {user} = useUser();
return ( return (
@@ -73,6 +74,9 @@ export function Cocktail({row, handleFavourite, handleChangeRating, handleSelect
<IconButton size='small' href={`${paths.bar.cocktailEdit}?id=${row.id}`}> <IconButton size='small' href={`${paths.bar.cocktailEdit}?id=${row.id}`}>
<EditIcon fontSize='small'/> <EditIcon fontSize='small'/>
</IconButton> </IconButton>
<IconButton size='small' onClick={() => hideHandler(row.id)}>
<VisibilityOffIcon fontSize='small'/>
</IconButton>
<IconButton size='small' onClick={() => deleteHandler(row)}> <IconButton size='small' onClick={() => deleteHandler(row)}>
<DeleteIcon fontSize='small'/> <DeleteIcon fontSize='small'/>
</IconButton> </IconButton>

View File

@@ -30,6 +30,7 @@ export function CocktailInfoModal({row}) {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const {closeCocktail, selectIngredient, getIngredient, getOpenCocktail} = useSelect(); const {closeCocktail, selectIngredient, getIngredient, getOpenCocktail} = useSelect();
// eslint-disable-next-line
useEffect(() => cocktailClient.getCocktailForModal(row, setLoading, setCocktail, closeCocktail, getError), [row]); useEffect(() => cocktailClient.getCocktailForModal(row, setLoading, setCocktail, closeCocktail, getError), [row]);
if (!row || !cocktail) { if (!row || !cocktail) {

View File

@@ -119,6 +119,10 @@ class CocktailClient {
.catch(() => createError("Ошибка удаления коктейля")) .catch(() => createError("Ошибка удаления коктейля"))
} }
async hiddenCocktail(id) {
return api().post(requests.cocktails.hide + id);
}
saveChangeCocktail (cocktail, createError, createSuccess) { saveChangeCocktail (cocktail, createError, createSuccess) {
api().patch(requests.cocktails.basic, cocktail) api().patch(requests.cocktails.basic, cocktail)
.then((r) => { .then((r) => {

View File

@@ -38,6 +38,7 @@ export const requests = {
favourite: routes.cocktail + "/favourite?id=", favourite: routes.cocktail + "/favourite?id=",
rating: routes.cocktail + "/rating?id=", rating: routes.cocktail + "/rating?id=",
drink: routes.cocktail + "/drink", drink: routes.cocktail + "/drink",
hide: routes.cocktail + "/hidden/",
}, },
glass: { glass: {
list: routes.glass, list: routes.glass,

View File

@@ -62,6 +62,11 @@ public class CocktailController {
return cocktailService.savePhoto(file); return cocktailService.savePhoto(file);
} }
@PostMapping("/hidden/{id}")
public void hiddenCocktail(@PathVariable Long id) {
cocktailService.hiddenCocktail(id);
}
@GetMapping @GetMapping
public CocktailForListResponseDto getOne(@RequestParam Long id) { public CocktailForListResponseDto getOne(@RequestParam Long id) {
return cocktailService.findById(id); return cocktailService.findById(id);

View File

@@ -32,4 +32,12 @@ public class BarEntity {
inverseJoinColumns = @JoinColumn(name = "ingredient") inverseJoinColumns = @JoinColumn(name = "ingredient")
) )
private List<IngredientEntity> ingredients; private List<IngredientEntity> ingredients;
@ManyToMany
@JoinTable(
name = "hidden_cocktails",
joinColumns = @JoinColumn(name = "bar"),
inverseJoinColumns = @JoinColumn(name = "cocktail")
)
private List<CocktailEntity> hiddenCocktails;
} }

View File

@@ -1,16 +1,15 @@
package ru.kayashov.bar.model.entity; package ru.kayashov.bar.model.entity;
import javax.persistence.Column; import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.GeneratedValue; import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType; import javax.persistence.GenerationType;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.OneToMany; import javax.persistence.OneToMany;
import javax.persistence.Table; import javax.persistence.Table;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.List; import java.util.List;
@Entity @Entity
@@ -19,17 +18,12 @@ import java.util.List;
@Table(name = "ingredient_type") @Table(name = "ingredient_type")
@NoArgsConstructor @NoArgsConstructor
public class TypeEntity { public class TypeEntity {
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; private Long id;
private String name; private String name;
@Column(name = "en_name")
private String enName;
@OneToMany(mappedBy = "type") @OneToMany(mappedBy = "type")
private List<IngredientEntity> ingredients; private List<IngredientEntity> ingredients;
public TypeEntity(String enName) {
this.enName = enName;
}
} }

View File

@@ -1,18 +1,11 @@
package ru.kayashov.bar.repository; package ru.kayashov.bar.repository;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import ru.kayashov.bar.model.entity.TypeEntity; import ru.kayashov.bar.model.entity.TypeEntity;
import java.util.List;
import java.util.Optional; import java.util.Optional;
public interface TypeRepository extends JpaRepository<TypeEntity, Long> { public interface TypeRepository extends JpaRepository<TypeEntity, Long> {
Optional<TypeEntity> findByEnNameIgnoreCase(String name);
Optional<TypeEntity> findByName(String name); Optional<TypeEntity> findByName(String name);
@Query("select i from TypeEntity i where upper(i.name) like upper(?1) or upper(i.enName) like upper(?1)")
List<TypeEntity> findByWord(String word);
} }

View File

@@ -30,6 +30,7 @@ public class BarService {
private final CocktailRepository cocktailRepository; private final CocktailRepository cocktailRepository;
private final EventService eventService; private final EventService eventService;
@Transactional
public void changeActiveBar(Long id) { public void changeActiveBar(Long id) {
Optional<BarEntity> lastBarOpt = barEntityRepository.findByActiveTrue(); Optional<BarEntity> lastBarOpt = barEntityRepository.findByActiveTrue();
if (lastBarOpt.isPresent()) { if (lastBarOpt.isPresent()) {
@@ -55,7 +56,7 @@ public class BarService {
.map(ingredientRepository::save) .map(ingredientRepository::save)
.toList(); .toList();
cocktailRepository.saveAll(findAllowedCocktails(ingredients)); cocktailRepository.saveAll(findAllowedCocktails(ingredients, barEntity.getHiddenCocktails().stream().map(CocktailEntity::getId).toList()));
barEntityRepository.save(barEntity); barEntityRepository.save(barEntity);
@@ -112,7 +113,7 @@ public class BarService {
return BarResponseDto.mapToDto(entity); return BarResponseDto.mapToDto(entity);
} }
private List<CocktailEntity> findAllowedCocktails(List<IngredientEntity> ingredients) { private List<CocktailEntity> findAllowedCocktails(List<IngredientEntity> ingredients, List<Long> hiddenCocktails) {
List<CocktailEntity> result = new ArrayList<>(); List<CocktailEntity> result = new ArrayList<>();
for (IngredientEntity ingredient : ingredients) { for (IngredientEntity ingredient : ingredients) {
List<CocktailEntity> cocktails = ingredient.getReceipts().stream() List<CocktailEntity> cocktails = ingredient.getReceipts().stream()
@@ -120,7 +121,8 @@ public class BarService {
.toList(); .toList();
for (CocktailEntity cocktail : cocktails) { for (CocktailEntity cocktail : cocktails) {
if (cocktail.getReceipt().stream().allMatch(r -> r.getIngredient().getIsHave())) { if (cocktail.getReceipt().stream().allMatch(r -> r.getIngredient().getIsHave())
&& !hiddenCocktails.contains(cocktail.getId())) {
cocktail.setAllowed(true); cocktail.setAllowed(true);
result.add(cocktail); result.add(cocktail);
} }

View File

@@ -2,8 +2,6 @@ package ru.kayashov.bar.service;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.hibernate.Session;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -18,6 +16,7 @@ import ru.kayashov.bar.controller.dto.cocktail.SortingEnum;
import ru.kayashov.bar.controller.dto.ingredient.IngredientSimpleResponseDto; import ru.kayashov.bar.controller.dto.ingredient.IngredientSimpleResponseDto;
import ru.kayashov.bar.mapper.CocktailMapper; import ru.kayashov.bar.mapper.CocktailMapper;
import ru.kayashov.bar.model.entity.Alcoholic; import ru.kayashov.bar.model.entity.Alcoholic;
import ru.kayashov.bar.model.entity.BarEntity;
import ru.kayashov.bar.model.entity.Category; import ru.kayashov.bar.model.entity.Category;
import ru.kayashov.bar.model.entity.CocktailEntity; import ru.kayashov.bar.model.entity.CocktailEntity;
import ru.kayashov.bar.model.entity.Event; import ru.kayashov.bar.model.entity.Event;
@@ -25,25 +24,24 @@ import ru.kayashov.bar.model.entity.EventType;
import ru.kayashov.bar.model.entity.Glass; import ru.kayashov.bar.model.entity.Glass;
import ru.kayashov.bar.model.entity.IngredientEntity; import ru.kayashov.bar.model.entity.IngredientEntity;
import ru.kayashov.bar.model.entity.ReceiptEntity; import ru.kayashov.bar.model.entity.ReceiptEntity;
import ru.kayashov.bar.repository.BarEntityRepository;
import ru.kayashov.bar.repository.CocktailRepository; import ru.kayashov.bar.repository.CocktailRepository;
import ru.kayashov.bar.repository.IngredientRepository; import ru.kayashov.bar.repository.IngredientRepository;
import ru.kayashov.bar.repository.ReceiptRepository; import ru.kayashov.bar.repository.ReceiptRepository;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
@Slf4j @Slf4j
@Service @Service
@@ -52,6 +50,7 @@ public class CocktailService {
private final CocktailRepository cocktailRepository; private final CocktailRepository cocktailRepository;
private final EventService eventService; private final EventService eventService;
private final BarEntityRepository barRepository;
@Value("${cocktail.photo.path}") @Value("${cocktail.photo.path}")
private String photoFolder; private String photoFolder;
@@ -84,65 +83,6 @@ public class CocktailService {
return mapper.cocktailsToDtoList(criteria(dto), false, true); return mapper.cocktailsToDtoList(criteria(dto), false, true);
} }
private List<CocktailEntity> criteria(CocktailFilterRequestDto dto) {
Session session = entityManager.unwrap(Session.class);
CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<CocktailEntity> criteriaQuery = cb.createQuery(CocktailEntity.class);
Root<CocktailEntity> root = criteriaQuery.from(CocktailEntity.class);
List<Predicate> predicates = new ArrayList<>();
criteriaQuery.distinct(true);
if (!dto.getAll()) {
Predicate pr = cb.isTrue(root.get("allowed"));
predicates.add(pr);
}
if (!dto.getSearch().isEmpty()) {
String[] search = dto.getSearch().split(" ");
List<Predicate> in = new ArrayList<>();
Join<CocktailEntity, ReceiptEntity> receiptJoin = root.join("receipt", JoinType.LEFT);
for (String s : search) {
in.add(cb.like(cb.lower(root.get("name")), "%" + s.toLowerCase() + "%"));
in.add(cb.like(cb.lower(receiptJoin.get("ingredient").get("name")), "%" + s.toLowerCase() + "%"));
}
predicates.add(cb.or(in.toArray(new Predicate[0])));
}
if (dto.getOnlyFavourite()) {
predicates.add(cb.isTrue(root.get("isFavorite")));
}
if (dto.getGlass() != null && !dto.getGlass().isEmpty()) {
predicates.add(root.get("glass").in(dto.getGlass().stream().map(Glass::findValue).toList()));
}
if (dto.getCategory() != null && !dto.getCategory().isEmpty()) {
predicates.add(root.get("category").in(dto.getCategory().stream().map(Category::findValue).toList()));
}
if (dto.getAlcohol() != null && !dto.getAlcohol().isEmpty()) {
predicates.add(root.get("alcoholic").in(dto.getAlcohol().stream().map(Alcoholic::findValue).toList()));
}
//todo: доделать другие виды сортировки
Order order;
switch (dto.getSort()) {
case NAME_ASC -> order = cb.asc(root.get("name"));
case NAME_DESC -> order = cb.desc(root.get("name"));
default -> order = cb.asc(root.get("name"));
}
criteriaQuery.where(predicates.toArray(new Predicate[0]))
.orderBy(order);
Query<CocktailEntity> query = session.createQuery(criteriaQuery);
query.setFirstResult(dto.getPage() * dto.getSize());
query.setMaxResults(dto.getSize());
List<CocktailEntity> cocktailEntities = query.getResultList();
log.info("Найдено {} коктейлей", cocktailEntities.size());
return cocktailEntities;
}
public CocktailForListResponseDto findById(Long id) { public CocktailForListResponseDto findById(Long id) {
CocktailEntity cocktail = repository.findById(id).orElseThrow(); CocktailEntity cocktail = repository.findById(id).orElseThrow();
return mapper.cocktailToFullDto(cocktail); return mapper.cocktailToFullDto(cocktail);
@@ -219,11 +159,6 @@ public class CocktailService {
repository.delete(cocktail); repository.delete(cocktail);
} }
public String findInstructions(Long id) {
CocktailEntity cocktail = repository.findById(id).orElseThrow(RuntimeException::new);
return cocktail.getInstructions();
}
public List<CocktailForIngredientModalDto> findByIngredient(Long id) { public List<CocktailForIngredientModalDto> findByIngredient(Long id) {
return ingredientRepository.findById(id).orElseThrow(RuntimeException::new) return ingredientRepository.findById(id).orElseThrow(RuntimeException::new)
.getReceipts() .getReceipts()
@@ -234,6 +169,72 @@ public class CocktailService {
.toList(); .toList();
} }
public void hiddenCocktail(Long id) {
CocktailEntity cocktail = repository.findById(id).orElseThrow(RuntimeException::new);
BarEntity bar = barRepository.findByActiveTrue().orElseThrow();
bar.getHiddenCocktails().add(cocktail);
barRepository.save(bar);
cocktail.setAllowed(false);
repository.save(cocktail);
log.info("Коктейль {} - {} был скрыт для бара {} - {}", cocktail.getId(), cocktail.getName(), bar.getId(), bar.getName());
}
public void drink(Long id) {
CocktailEntity cocktail = repository.findById(id).orElseThrow(RuntimeException::new);
int count = cocktail.getCountDrink() + 1;
cocktail.setCountDrink(count);
repository.save(cocktail);
eventService.createEvent(Event.builder()
.type(EventType.DRINK)
.date(LocalDateTime.now())
.oldState(cocktail.getName())
.newState(String.valueOf(count))
.build());
}
//todo: написать функцию в БД, чтобы ускорить работу и сохранить читаемый код
private List<CocktailEntity> criteria(CocktailFilterRequestDto dto) {
Instant now = Instant.now();
List<CocktailEntity> cocktails = repository.findAll()
.stream()
//todo: доделать другие виды сортировки
.sorted(Comparator.comparing(CocktailEntity::getName))
.filter(c -> c.getAllowed() || dto.getAll())
.filter(c -> c.getIsFavorite() || !dto.getOnlyFavourite())
.filter(c -> isEmpty(dto.getGlass()) || dto.getGlass().contains(c.getGlass().getName()))
.filter(c -> isEmpty(dto.getCategory()) || dto.getCategory().contains(c.getCategory().getName()))
.filter(c -> isEmpty(dto.getAlcohol()) || dto.getAlcohol().contains(c.getAlcoholic().getValue()))
.filter(c -> dto.getSearch().isEmpty() || textSearchFilter(c, dto.getSearch()))
.skip((long) dto.getPage() * dto.getSize())
.limit(dto.getSize())
.toList();
log.info("Найдено {} коктейлей за {} ms", cocktails.size(), Duration.between(now, Instant.now()).toMillis());
return cocktails;
}
private boolean textSearchFilter(CocktailEntity cocktail, String founding) {
String[] search = founding.split(" ");
if (Arrays.stream(search).anyMatch(s -> cocktail.getName().toLowerCase().contains(s.toLowerCase()))) {
return true;
}
Set<String> ingredientsNames = cocktail.getReceipt().stream()
.map(ReceiptEntity::getIngredient)
.map(IngredientEntity::getName)
.map(String::toLowerCase)
.collect(Collectors.toSet());
return Arrays.stream(search).anyMatch(s -> ingredientsNames.contains(s.toLowerCase()));
}
private boolean isEmpty(List<?> value) {
return value == null || value.isEmpty();
}
//todo: попробовать отыграть эту связку каскадами //todo: попробовать отыграть эту связку каскадами
private void editCocktailReceipts(List<ReceiptEntity> old, List<ReceiptResponseDto> actual, CocktailEntity cocktail) { private void editCocktailReceipts(List<ReceiptEntity> old, List<ReceiptResponseDto> actual, CocktailEntity cocktail) {
for (ReceiptResponseDto receipt : actual) { for (ReceiptResponseDto receipt : actual) {
@@ -299,18 +300,65 @@ public class CocktailService {
return sb.toString(); return sb.toString();
} }
public void drink(Long id) {
CocktailEntity cocktail = repository.findById(id).orElseThrow(RuntimeException::new);
int count = cocktail.getCountDrink() + 1;
cocktail.setCountDrink(count);
repository.save(cocktail);
eventService.createEvent(Event.builder() //todo: оставить до написания функции в БД
.type(EventType.DRINK) // private List<CocktailEntity> criteria(CocktailFilterRequestDto dto) {
.date(LocalDateTime.now()) // Instant now = Instant.now();
.oldState(cocktail.getName()) // Session session = entityManager.unwrap(Session.class);
.newState(String.valueOf(count)) // CriteriaBuilder cb = session.getCriteriaBuilder();
.build()); // CriteriaQuery<CocktailEntity> criteriaQuery = cb.createQuery(CocktailEntity.class);
// Root<CocktailEntity> root = criteriaQuery.from(CocktailEntity.class);
// List<Predicate> predicates = new ArrayList<>();
//
// criteriaQuery.distinct(true);
// if (!dto.getAll()) {
// Predicate pr = cb.isTrue(root.get("allowed"));
// predicates.add(pr);
// }
//
// if (!dto.getSearch().isEmpty()) {
// String[] search = dto.getSearch().split(" ");
// List<Predicate> in = new ArrayList<>();
// Join<CocktailEntity, ReceiptEntity> receiptJoin = root.join("receipt", JoinType.LEFT);
// for (String s : search) {
// in.add(cb.like(cb.lower(root.get("name")), "%" + s.toLowerCase() + "%"));
// in.add(cb.like(cb.lower(receiptJoin.get("ingredient").get("name")), "%" + s.toLowerCase() + "%"));
// }
// predicates.add(cb.or(in.toArray(new Predicate[0])));
// }
//
// if (dto.getOnlyFavourite()) {
// predicates.add(cb.isTrue(root.get("isFavorite")));
// }
//
// if (dto.getGlass() != null && !dto.getGlass().isEmpty()) {
// predicates.add(root.get("glass").in(dto.getGlass().stream().map(Glass::findValue).toList()));
// }
//
// if (dto.getCategory() != null && !dto.getCategory().isEmpty()) {
// predicates.add(root.get("category").in(dto.getCategory().stream().map(Category::findValue).toList()));
// }
//
// if (dto.getAlcohol() != null && !dto.getAlcohol().isEmpty()) {
// predicates.add(root.get("alcoholic").in(dto.getAlcohol().stream().map(Alcoholic::findValue).toList()));
// }
} // //todo: доделать другие виды сортировки
// Order order;
// switch (dto.getSort()) {
// case NAME_ASC -> order = cb.asc(root.get("name"));
// case NAME_DESC -> order = cb.desc(root.get("name"));
// default -> order = cb.asc(root.get("name"));
// }
//
// criteriaQuery.where(predicates.toArray(new Predicate[0]))
// .orderBy(order);
// Query<CocktailEntity> query = session.createQuery(criteriaQuery);
// query.setFirstResult(dto.getPage() * dto.getSize());
// query.setMaxResults(dto.getSize());
// List<CocktailEntity> cocktailEntities = query.getResultList();
//
// log.info("Найдено {} коктейлей за {} ms", cocktailEntities.size(), Duration.between(now, Instant.now()).toMillis());
// return cocktailEntities;
// }
} }