временные изменения

This commit is contained in:
Kayashov.SM
2025-04-30 13:06:20 +04:00
parent 56ffb21b91
commit badd71545e
13 changed files with 196 additions and 201 deletions

View File

@@ -191,23 +191,13 @@ const CocktailsPageContent = () => {
const handleSelectCocktail = (row) => { const handleSelectCocktail = (row) => {
selectCocktail(row.id) selectCocktail(row.id)
} }
const handleEditMenu = (row, value) => { const deleteHandle = (row) => {
const newState = rows.map((r) => { api().delete(requests.cocktails.cocktail + row.id)
if (r.id !== row.id) { .then(() => {
return r; setRows(rows.filter((r) => r.id !== row.id))
} createSuccess("Коктейль удален")
if (filter.all) { })
return { .catch(() => createError("Ошибка удаления коктейля"))
...r,
inMenu: value
}
}
return null
}).filter((r) => r !== null);
api().post(`${requests.cocktails.menu}?id=${row.id}&value=${value}`)
.then(() => setRows(newState))
.catch(() => createError("Ошибка сохранения данных"))
} }
return ( return (
@@ -242,6 +232,7 @@ const CocktailsPageContent = () => {
<Cocktail key={row.id} row={row} handleFavourite={handleFavourite} <Cocktail key={row.id} row={row} handleFavourite={handleFavourite}
handleChangeRating={handleChangeRating} handleChangeRating={handleChangeRating}
handleSelect={handleSelectCocktail} handleSelect={handleSelectCocktail}
deleteHandler={deleteHandle}
/> />
) )
})} })}

View File

@@ -1,22 +1,22 @@
import {CardActions, CardContent, CardMedia, Rating} from "@mui/material"; import {CardActions, CardContent, CardMedia, Rating} from "@mui/material";
import {useAlert} from "../../hooks/useAlert";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import Grid from "@mui/material/Grid"; import Grid from "@mui/material/Grid";
import {requests} from "../../requests";
import {CocktailItemStyled} from "./CocktailItemStyled"; import {CocktailItemStyled} from "./CocktailItemStyled";
import IconButton from "@mui/material/IconButton"; import IconButton from "@mui/material/IconButton";
import FavoriteBorderIcon from '@mui/icons-material/FavoriteTwoTone'; import FavoriteBorderIcon from '@mui/icons-material/FavoriteTwoTone';
import FavoriteIcon from '@mui/icons-material/Favorite'; import FavoriteIcon from '@mui/icons-material/Favorite';
import {api} from "../../lib/clients/api";
import Box from "@mui/material/Box"; import Box from "@mui/material/Box";
import {useUser} from "../../hooks/useUser";
import {CocktailDescription} from "./CocktailDescription"; import {CocktailDescription} from "./CocktailDescription";
import EditIcon from '@mui/icons-material/Edit';
import DeleteIcon from '@mui/icons-material/Delete';
import LocalBarIcon from '@mui/icons-material/LocalBar';
import {paths} from "../../path";
function renderFavouriteBadge(handleFavourite, row) { function renderFavouriteBadge(handleFavourite, row) {
const childIcon = row.rating.favourite ? <FavoriteIcon color='error'/> : <FavoriteBorderIcon color={'warning'}/>; const childIcon = row.rating.favourite ? <FavoriteIcon/> : <FavoriteBorderIcon/>;
return ( return (
<IconButton sx={{position: 'absolute', top: "15px", right: "15px"}} onClick={() => handleFavourite(row)}> <IconButton size={'small'}
onClick={() => handleFavourite(row)}>
{childIcon} {childIcon}
</IconButton> </IconButton>
) )
@@ -25,16 +25,14 @@ function renderFavouriteBadge(handleFavourite, row) {
function renderRating(handleChangeRating, row) { function renderRating(handleChangeRating, row) {
return ( return (
<Rating <Rating
sx={{position: 'absolute', top: '310px', right: '85px'}}
name="simple-controlled" name="simple-controlled"
size="large"
value={row.rating.rating} value={row.rating.rating}
onChange={(event, newValue) => handleChangeRating(row, newValue)} onChange={(event, newValue) => handleChangeRating(row, newValue)}
/> />
) )
} }
export function Cocktail({row, handleFavourite, handleChangeRating, handleSelect}) { export function Cocktail({row, handleFavourite, handleChangeRating, handleSelect, deleteHandler}) {
return ( return (
<Grid item sx={{pr: 2}}> <Grid item sx={{pr: 2}}>
<CocktailItemStyled> <CocktailItemStyled>
@@ -56,15 +54,25 @@ export function Cocktail({row, handleFavourite, handleChangeRating, handleSelect
image={row.image.includes("thecocktaildb") ? (row.image + "/preview") : row.image} image={row.image.includes("thecocktaildb") ? (row.image + "/preview") : row.image}
/> />
<CardActions>
<IconButton sx={{m: 0}} size='small'>
<LocalBarIcon fontSize='small'/>
</IconButton>
{renderFavouriteBadge(handleFavourite, row)} {renderFavouriteBadge(handleFavourite, row)}
{renderRating(handleChangeRating, row)} {renderRating(handleChangeRating, row)}
<CardContent sx={{pb: '4px', pl: 2}}>
<IconButton size={'small'} href={`${paths.bar.cocktailEdit}?id=${row.id}`}>
<EditIcon fontSize={'small'}/>
</IconButton>
<IconButton size={'small'} onClick={() => deleteHandler(row)}>
<DeleteIcon fontSize={'small'}/>
</IconButton>
</CardActions>
<CardContent sx={{pb: 0, pl: 2, pt: 0}}>
<Typography variant="h5" minHeight={'50px'} mt={2}>{row.name} </Typography> <Typography variant="h5" minHeight={'50px'} mt={2}>{row.name} </Typography>
<CocktailDescription row={row}/> <CocktailDescription row={row}/>
</CardContent> </CardContent>
<CardActions>
<Button variant={'contained'} color={"error"}>Удалить</Button>
</CardActions>
</Box> </Box>
</CocktailItemStyled> </CocktailItemStyled>
</Grid> </Grid>

View File

@@ -19,36 +19,9 @@ export function FilterBlock({filter, handleFilterChange, handleClearFilter, barm
const {createError} = useAlert(); const {createError} = useAlert();
const [glass, setGlass] = useState([]); const [glass, setGlass] = useState([]);
const [category, setCategory] = useState([]); const [category, setCategory] = useState([]);
const alcohol = [ const alcohol = ['Алкогольный', 'Безалкогольный'];
{ const ingredientCount = [1,2,3,4,5];
name: "Алкогольный", const sort = ['Название по возрастанию', 'Название по убыванию'];
id: "alcohol1"
},
{
name: "Безалкогольный",
id: "alcohol2"
}];
const ingredientCount = [
{
id: "1IngredientCount",
name: 1
},
{
id: "2IngredientCount",
name: 2
},
{
id: "3IngredientCount",
name: 3
},
{
id: "4IngredientCount",
name: 4
},
{
id: "5IngredientCount",
name: 5
}]
useEffect(() => { useEffect(() => {
api().get(requests.bar.category) api().get(requests.bar.category)
@@ -88,8 +61,8 @@ export function FilterBlock({filter, handleFilterChange, handleClearFilter, barm
<Box hidden={filter.hidden}> <Box hidden={filter.hidden}>
<Grid container> <Grid container>
{/*Фильтр по алкогольности*/} {/*Фильтр по алкогольности*/}
<CheckMarks rows={sortList} name={"Сортировать по..."} handleChange={handleFilterChange} <CheckMarks rows={sort} name={"Сортировать по..."} handleChange={handleFilterChange}
filterValue={filter.sorting} filterName={"sorting"} nonMulti/> filterValue={filter.sorting} filterName={"sorting"} nonMulti identity/>
</Grid> </Grid>
</Box> </Box>
{/*Блок фильтров*/} {/*Блок фильтров*/}
@@ -117,18 +90,18 @@ export function FilterBlock({filter, handleFilterChange, handleClearFilter, barm
/> />
{/*Фильтр по алкогольности*/} {/*Фильтр по алкогольности*/}
<CheckMarks rows={alcohol} name={"Алкогольность"} handleChange={handleFilterChange} <CheckMarks rows={alcohol} name={"Алкогольность"} handleChange={handleFilterChange}
filterValue={filter.alcohol} filterName={"alcohol"}/> filterValue={filter.alcohol} filterName={"alcohol"} identity/>
{/*Фильтр по категории*/} {/*Фильтр по категории*/}
{category.length > 0 && ( {category.length > 0 && (
<CheckMarks rows={category} name={"Категории"} filterValue={filter.category} <CheckMarks rows={category} name={"Категории"} filterValue={filter.category}
filterName={"category"} handleChange={handleFilterChange}/>)} filterName={"category"} handleChange={handleFilterChange} identity/>)}
{/*Фильтр по посуде*/} {/*Фильтр по посуде*/}
{glass.length > 0 && (<CheckMarks rows={glass} name={"Подача"} handleChange={handleFilterChange} {glass.length > 0 && (<CheckMarks rows={glass} name={"Подача"} handleChange={handleFilterChange}
filterValue={filter.glass} filterName={"glass"}/>)} filterValue={filter.glass} filterName={"glass"} identity/>)}
{/*Фильтр по нехватке ингредиентов*/} {/*Фильтр по нехватке ингредиентов*/}
{(barmen && filter.all) && (<CheckMarks rows={ingredientCount} name={"Не хватает ингредиентов"} {(barmen && filter.all) && (<CheckMarks rows={ingredientCount} name={"Не хватает ингредиентов"}
handleChange={handleFilterChange} handleChange={handleFilterChange}
nonMulti nullValue nonMulti nullValue identity
filterValue={filter.iCount} filterName={"iCount"}/>)} filterValue={filter.iCount} filterName={"iCount"}/>)}
<Button onClick={() => handleClearFilter()}>Сбросить</Button> <Button onClick={() => handleClearFilter()}>Сбросить</Button>
</Grid> </Grid>

View File

@@ -10,10 +10,12 @@ import ru.kayashov.bar.controller.dto.cocktail.CocktailModalDto;
import ru.kayashov.bar.controller.dto.cocktail.RatingResponseDto; import ru.kayashov.bar.controller.dto.cocktail.RatingResponseDto;
import ru.kayashov.bar.controller.dto.cocktail.ReceiptResponseDto; import ru.kayashov.bar.controller.dto.cocktail.ReceiptResponseDto;
import ru.kayashov.bar.controller.dto.ingredient.IngredientSimpleResponseDto; import ru.kayashov.bar.controller.dto.ingredient.IngredientSimpleResponseDto;
import ru.kayashov.bar.model.entity.BarEntity;
import ru.kayashov.bar.model.entity.CocktailEntity; import ru.kayashov.bar.model.entity.CocktailEntity;
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.model.entity.Visitor; import ru.kayashov.bar.model.entity.Visitor;
import ru.kayashov.bar.repository.BarEntityRepository;
import ru.kayashov.bar.repository.VisitorsRepository; import ru.kayashov.bar.repository.VisitorsRepository;
import java.util.ArrayList; import java.util.ArrayList;
@@ -25,6 +27,7 @@ import java.util.stream.Collectors;
public class CocktailMapper { public class CocktailMapper {
private final VisitorsRepository visitorsRepository; private final VisitorsRepository visitorsRepository;
private final BarEntityRepository barRepository;
@Transactional @Transactional
public List<CocktailForListResponseDto> cocktailsToDtoList(List<CocktailEntity> cocktails, Boolean all) { public List<CocktailForListResponseDto> cocktailsToDtoList(List<CocktailEntity> cocktails, Boolean all) {
@@ -33,7 +36,7 @@ public class CocktailMapper {
// return new ArrayList<>(); // return new ArrayList<>();
// } // }
List<Long> barStopList = new ArrayList<>(); List<Long> barStopList = new ArrayList<>();
List<Long> allowedIngredients = getAllowedIngredients(visitor); List<Long> allowedIngredients = getAllowedIngredients();
return cocktails.stream() return cocktails.stream()
.map(c -> cocktailToDto(c, visitor, allowedIngredients, barStopList)) .map(c -> cocktailToDto(c, visitor, allowedIngredients, barStopList))
// .filter(c -> all || c.getIsAllowed()) // .filter(c -> all || c.getIsAllowed())
@@ -42,7 +45,7 @@ public class CocktailMapper {
} }
public CocktailForListResponseDto cocktailToFullDto(CocktailEntity e) { public CocktailForListResponseDto cocktailToFullDto(CocktailEntity e) {
List<Long> allowed = getAllowedIngredients(getCurrentVisitor()); List<Long> allowed = getAllowedIngredients();
return CocktailForListResponseDto.builder() return CocktailForListResponseDto.builder()
.id(e.getId()) .id(e.getId())
.name(e.getName()) .name(e.getName())
@@ -107,8 +110,13 @@ public class CocktailMapper {
// d.setReceipt(e.getReceipt().stream().map(ReceiptResponseDto::mapToDto).toList()); // d.setReceipt(e.getReceipt().stream().map(ReceiptResponseDto::mapToDto).toList());
} }
private List<Long> getAllowedIngredients(Visitor visitor) { private List<Long> getAllowedIngredients() {
return new ArrayList<>(); return barRepository.findByActiveTrue()
.map(BarEntity::getIngredients)
.orElseThrow()
.stream()
.map(IngredientEntity::getId)
.toList();
// return visitor.getResidents().stream() // return visitor.getResidents().stream()
// .filter(BarResident::getActive) // .filter(BarResident::getActive)
// .map(BarResident::getBar) // .map(BarResident::getBar)
@@ -145,8 +153,7 @@ public class CocktailMapper {
} }
public CocktailModalDto cocktailToModalDto(CocktailEntity e) { public CocktailModalDto cocktailToModalDto(CocktailEntity e) {
Visitor visitor = getCurrentVisitor(); List<Long> allowedIngredients = getAllowedIngredients();
List<Long> allowedIngredients = getAllowedIngredients(visitor);
return CocktailModalDto.builder() return CocktailModalDto.builder()
.id(e.getId()) .id(e.getId())
.name(e.getName()) .name(e.getName())

View File

@@ -4,8 +4,9 @@ import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import ru.kayashov.bar.controller.dto.ingredient.IngredientResponseDto; import ru.kayashov.bar.controller.dto.ingredient.IngredientResponseDto;
import ru.kayashov.bar.controller.dto.ingredient.IngredientSimpleResponseDto; import ru.kayashov.bar.controller.dto.ingredient.IngredientSimpleResponseDto;
import ru.kayashov.bar.model.entity.BarEntity;
import ru.kayashov.bar.model.entity.IngredientEntity; import ru.kayashov.bar.model.entity.IngredientEntity;
import ru.kayashov.bar.service.VisitorService; import ru.kayashov.bar.repository.BarEntityRepository;
import java.util.List; import java.util.List;
@@ -13,15 +14,24 @@ import java.util.List;
@RequiredArgsConstructor @RequiredArgsConstructor
public class IngredientMapper { public class IngredientMapper {
private final VisitorService visitorService; private final BarEntityRepository barRepository;
public List<IngredientResponseDto> mapIngredientsToDtoList(List<IngredientEntity> ingredients) { public List<IngredientResponseDto> mapIngredientsToDtoList(List<IngredientEntity> ingredients) {
List<Long> allowedIngredients = visitorService.getAllowedIngredients(); List<Long> allowedIngredients = getAllowedIngredients();
return ingredients.stream() return ingredients.stream()
.map(i -> mapIngredientToDto(i, allowedIngredients)) .map(i -> mapIngredientToDto(i, allowedIngredients))
.toList(); .toList();
} }
private List<Long> getAllowedIngredients() {
return barRepository.findByActiveTrue()
.map(BarEntity::getIngredients)
.orElseThrow()
.stream()
.map(IngredientEntity::getId)
.toList();
}
private IngredientResponseDto mapIngredientToDto(IngredientEntity i, List<Long> allowedIngredients) { private IngredientResponseDto mapIngredientToDto(IngredientEntity i, List<Long> allowedIngredients) {
return IngredientResponseDto return IngredientResponseDto
.builder() .builder()
@@ -37,7 +47,7 @@ public class IngredientMapper {
} }
public List<IngredientSimpleResponseDto> mapIngredientsToSimpleDtoList(List<IngredientEntity> ingredients) { public List<IngredientSimpleResponseDto> mapIngredientsToSimpleDtoList(List<IngredientEntity> ingredients) {
List<Long> allowedIngredients = visitorService.getAllowedIngredients(); List<Long> allowedIngredients = getAllowedIngredients();
return ingredients.stream() return ingredients.stream()
.map(i -> mapIngredientToSimpleDto(i, allowedIngredients)) .map(i -> mapIngredientToSimpleDto(i, allowedIngredients))
.toList(); .toList();

View File

@@ -7,6 +7,9 @@ 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.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany; import javax.persistence.OneToMany;
import javax.persistence.Table; import javax.persistence.Table;
import java.util.List; import java.util.List;
@@ -20,7 +23,13 @@ public class BarEntity {
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; private Long id;
private String name; private String name;
private Boolean active;
@OneToMany(mappedBy = "bar") @ManyToMany
private List<BarIngredientStorage> ingredients; @JoinTable(
name = "bar_ingredient",
joinColumns = @JoinColumn(name = "bar"),
inverseJoinColumns = @JoinColumn(name = "ingredient")
)
private List<IngredientEntity> ingredients;
} }

View File

@@ -1,25 +0,0 @@
package ru.kayashov.bar.model.entity;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
@Entity
@Getter
@Setter
public class BarIngredientStorage {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
private IngredientEntity ingredient;
@ManyToOne
private BarEntity bar;
}

View File

@@ -10,6 +10,8 @@ import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne; import javax.persistence.ManyToOne;
import javax.persistence.OneToMany; import javax.persistence.OneToMany;
import javax.persistence.Table; import javax.persistence.Table;
@@ -40,6 +42,11 @@ public class IngredientEntity {
@JoinColumn(name = "type") @JoinColumn(name = "type")
private TypeEntity type; private TypeEntity type;
@OneToMany(mappedBy = "ingredient") @ManyToMany
private List<BarIngredientStorage> barIngredients; @JoinTable(
name = "bar_ingredient",
joinColumns = @JoinColumn(name = "ingredient"),
inverseJoinColumns = @JoinColumn(name = "bar")
)
private List<BarEntity> bars;
} }

View File

@@ -3,5 +3,9 @@ package ru.kayashov.bar.repository;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import ru.kayashov.bar.model.entity.BarEntity; import ru.kayashov.bar.model.entity.BarEntity;
import java.util.List;
import java.util.Optional;
public interface BarEntityRepository extends JpaRepository<BarEntity, Long> { public interface BarEntityRepository extends JpaRepository<BarEntity, Long> {
Optional<BarEntity> findByActiveTrue();
} }

View File

@@ -1,7 +0,0 @@
package ru.kayashov.bar.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import ru.kayashov.bar.model.entity.BarIngredientStorage;
public interface BarIngredientStorageRepository extends JpaRepository<BarIngredientStorage, Long> {
}

View File

@@ -15,8 +15,8 @@ import ru.kayashov.bar.controller.dto.cocktail.CocktailModalDto;
import ru.kayashov.bar.controller.dto.cocktail.CocktailSimpleResponseDto; import ru.kayashov.bar.controller.dto.cocktail.CocktailSimpleResponseDto;
import ru.kayashov.bar.controller.dto.cocktail.ReceiptResponseDto; import ru.kayashov.bar.controller.dto.cocktail.ReceiptResponseDto;
import ru.kayashov.bar.mapper.CocktailMapper; import ru.kayashov.bar.mapper.CocktailMapper;
import ru.kayashov.bar.model.Ingredient;
import ru.kayashov.bar.model.entity.Alcoholic; import ru.kayashov.bar.model.entity.Alcoholic;
import ru.kayashov.bar.model.entity.BarIngredientStorage;
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.Glass; import ru.kayashov.bar.model.entity.Glass;
@@ -30,12 +30,14 @@ import ru.kayashov.bar.repository.ReceiptRepository;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Join; import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType; import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Order; import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root; import javax.persistence.criteria.Root;
import javax.persistence.criteria.Subquery; import javax.persistence.criteria.Subquery;
import javax.print.attribute.standard.MediaSize;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
@@ -72,8 +74,6 @@ public class CocktailService {
} }
private List<CocktailEntity> criteria(CocktailFilterRequestDto dto) { private List<CocktailEntity> criteria(CocktailFilterRequestDto dto) {
Visitor visitor = visitorService.getCurrentVisitor();
Session session = entityManager.unwrap(Session.class); Session session = entityManager.unwrap(Session.class);
CriteriaBuilder cb = session.getCriteriaBuilder(); CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<CocktailEntity> criteriaQuery = cb.createQuery(CocktailEntity.class); CriteriaQuery<CocktailEntity> criteriaQuery = cb.createQuery(CocktailEntity.class);
@@ -82,14 +82,7 @@ public class CocktailService {
criteriaQuery.distinct(true); criteriaQuery.distinct(true);
if (!dto.getAll()) { if (!dto.getAll()) {
// Long barId = visitor.getResidents().stream() List<Long> cocktailIds = findICountCocktailIds(0, new ArrayList<>());
// .filter(BarResident::getActive)
// .map(BarResident::getBar)
// .map(BarEntity::getId)
// .toList()
// .get(0);
Long barId = 1L;
List<Long> cocktailIds = getAllowedCocktailIds(barId);
Predicate pr = root.get("id").in(cocktailIds); Predicate pr = root.get("id").in(cocktailIds);
predicates.add(pr); predicates.add(pr);
} }
@@ -110,19 +103,19 @@ public class CocktailService {
} }
if (dto.getGlass() != null && !dto.getGlass().isEmpty()) { if (dto.getGlass() != null && !dto.getGlass().isEmpty()) {
predicates.add(root.get("glassEntity").get("name").in(dto.getGlass())); predicates.add(root.get("glass").in(dto.getGlass().stream().map(Glass::findValue).toList()));
} }
if (dto.getCategory() != null && !dto.getCategory().isEmpty()) { if (dto.getCategory() != null && !dto.getCategory().isEmpty()) {
predicates.add(root.get("categoryEntity").get("name").in(dto.getCategory())); predicates.add(root.get("category").in(dto.getCategory().stream().map(Category::findValue).toList()));
} }
if (dto.getAlcohol() != null && !dto.getAlcohol().isEmpty()) { if (dto.getAlcohol() != null && !dto.getAlcohol().isEmpty()) {
predicates.add(root.get("alcoholicEntity").get("name").in(dto.getAlcohol())); predicates.add(root.get("alcoholic").in(dto.getAlcohol().stream().map(Alcoholic::findValue).toList()));
} }
if (dto.getNotHaveCount() != null) { if (dto.getNotHaveCount() != null) {
List<Long> approveCocktail = findICountCocktailIds(dto.getNotHaveCount(), visitor, dto.getIngredient()); List<Long> approveCocktail = findICountCocktailIds(dto.getNotHaveCount(), dto.getIngredient());
predicates.add(root.get("id").in(approveCocktail)); predicates.add(root.get("id").in(approveCocktail));
} }
// //
@@ -152,8 +145,8 @@ public class CocktailService {
return cocktailEntities; return cocktailEntities;
} }
private List<Long> findICountCocktailIds(Integer iCount, Visitor visitor, List<String> ingredientFilter) { private List<Long> findICountCocktailIds(Integer iCount, List<String> ingredientFilter) {
List<Long> allowedIngredient = new ArrayList<>(); List<Long> allowedIngredient = visitorService.getAllowedIngredients();
Stream<List<ReceiptEntity>> receiptStream = receiptRepository.findAll() Stream<List<ReceiptEntity>> receiptStream = receiptRepository.findAll()
.stream() .stream()
@@ -182,46 +175,85 @@ public class CocktailService {
.count()); .count());
} }
private List<Long> getAllowedCocktailIds(Long barId) { // private List<Long> getAllowedCocktailIds(Long barId) {
// CriteriaBuilder cb = entityManager.getCriteriaBuilder();
// CriteriaQuery<Long> query = cb.createQuery(Long.class);
//
// Root<ReceiptEntity> receiptRoot = query.from(ReceiptEntity.class);
// Join<ReceiptEntity, IngredientEntity> ingredientJoin = receiptRoot.join("ingredient", JoinType.LEFT);
// Join<IngredientEntity, BarEntity> barIngredientStorageJoin = ingredientJoin.join("bars", JoinType.LEFT);
//
// // Внешний подзапрос с NOT EXISTS
// Subquery<Long> subquery = query.subquery(Long.class);
// Root<ReceiptEntity> receiptSubRoot = subquery.from(ReceiptEntity.class);
// Join<ReceiptEntity, IngredientEntity> ingredientSubJoin = receiptSubRoot.join("ingredient", JoinType.LEFT);
//
// // Внутренний подзапрос с NOT EXISTS
// Subquery<Long> innerSubquery = subquery.subquery(Long.class);
// Root<BarIngredientStorage> barIngredientStorageInnerRoot = innerSubquery.from(BarIngredientStorage.class);
//
// // Условия внутреннего подзапроса
// innerSubquery.select(barIngredientStorageInnerRoot.get("id"))
// .where(
// cb.equal(barIngredientStorageInnerRoot.get("ingredient"), ingredientSubJoin.get("id")),
// cb.equal(barIngredientStorageInnerRoot.get("bar").get("id"), barId)
// );
//
// // Условия внешнего подзапроса
// subquery.select(receiptSubRoot.get("id"))
// .where(
// cb.equal(receiptSubRoot.get("cocktail").get("id"), receiptRoot.get("cocktail").get("id")),
// cb.not(cb.exists(innerSubquery))
// );
//
// // Основной запрос
// query.select(receiptRoot.get("cocktail").get("id"))
// .distinct(true)
// .where(
// cb.equal(barIngredientStorageJoin.get("bar").get("id"), barId),
// cb.not(cb.exists(subquery))
// );
//
// return entityManager.createQuery(query).getResultList();
// }
/*
select cifc.cocktail_id
from (select r.cocktail_id, COUNT(CASE WHEN i.is_have THEN 0 END) as false_count
from receipt r
left join public.ingredient i on i.id = r.ingredient_id
group by r.cocktail_id) as cifc
where false_count = 0
*/
private List<Long> findCocktailByCountNotHaveIngredient(Integer notHaveCount, List<Long> currentIngredient) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> query = cb.createQuery(Long.class); List<Predicate> predicates = new ArrayList<>();
CriteriaQuery<Long> mainQuery = cb.createQuery(Long.class);
Root<ReceiptEntity> receiptRoot = query.from(ReceiptEntity.class); // Создаем корневые сущности
Join<ReceiptEntity, IngredientEntity> ingredientJoin = receiptRoot.join("ingredient", JoinType.LEFT); Subquery<Long> sq = mainQuery.subquery(Long.class);
Join<IngredientEntity, BarIngredientStorage> barIngredientStorageJoin = ingredientJoin.join("barIngredients", JoinType.LEFT); Root<ReceiptEntity> rsq = sq.from(ReceiptEntity.class);
Join<ReceiptEntity, IngredientEntity> ingredientJoin = rsq.join("ingredient", JoinType.LEFT);
// Создаем подзапрос
sq.select(cb.count(cb.selectCase(cb.isFalse(ingredientJoin.get("isHave")))))
.groupBy(rsq.get("cocktail"))
.having(cb.equal(sq.getSelection(), notHaveCount));
// Внешний подзапрос с NOT EXISTS // Создаем внешний запрос
Subquery<Long> subquery = query.subquery(Long.class); mainQuery.select(rsq.get("cocktail"));
Root<ReceiptEntity> receiptSubRoot = subquery.from(ReceiptEntity.class); Predicate predicate = cb.exists(sq);
Join<ReceiptEntity, IngredientEntity> ingredientSubJoin = receiptSubRoot.join("ingredient", JoinType.LEFT); predicates.add(predicate);
// mainQuery.where(cb.exists(sq));
// Внутренний подзапрос с NOT EXISTS if(!currentIngredient.isEmpty()) {
Subquery<Long> innerSubquery = subquery.subquery(Long.class); predicates.add(rsq.get("ingredient").in(currentIngredient));
Root<BarIngredientStorage> barIngredientStorageInnerRoot = innerSubquery.from(BarIngredientStorage.class); }
// Условия внутреннего подзапроса mainQuery.where(predicates.toArray(new Predicate[0]));
innerSubquery.select(barIngredientStorageInnerRoot.get("id"))
.where(
cb.equal(barIngredientStorageInnerRoot.get("ingredient"), ingredientSubJoin.get("id")),
cb.equal(barIngredientStorageInnerRoot.get("bar").get("id"), barId)
);
// Условия внешнего подзапроса // Выполняем запрос
subquery.select(receiptSubRoot.get("id")) return entityManager.createQuery(mainQuery)
.where( .getResultList();
cb.equal(receiptSubRoot.get("cocktail").get("id"), receiptRoot.get("cocktail").get("id")),
cb.not(cb.exists(innerSubquery))
);
// Основной запрос
query.select(receiptRoot.get("cocktail").get("id"))
.distinct(true)
.where(
cb.equal(barIngredientStorageJoin.get("bar").get("id"), barId),
cb.not(cb.exists(subquery))
);
return entityManager.createQuery(query).getResultList();
} }
public CocktailForListResponseDto findById(Long id) { public CocktailForListResponseDto findById(Long id) {
@@ -307,7 +339,6 @@ public class CocktailService {
receiptEntity.setIngredient(ingredient); receiptEntity.setIngredient(ingredient);
receiptEntity.setCount(receipt.getCount()); receiptEntity.setCount(receipt.getCount());
receiptEntity.setUnit(receipt.getUnit()); receiptEntity.setUnit(receipt.getUnit());
// receiptEntity.setMeasure(receipt.getMeasure());
receiptEntity.setCocktail(cocktail); receiptEntity.setCocktail(cocktail);
receiptRepository.save(receiptEntity); receiptRepository.save(receiptEntity);
} }

View File

@@ -6,12 +6,14 @@ import org.springframework.stereotype.Service;
import ru.kayashov.bar.controller.dto.ingredient.IngredientResponseDto; import ru.kayashov.bar.controller.dto.ingredient.IngredientResponseDto;
import ru.kayashov.bar.controller.dto.ingredient.IngredientSimpleResponseDto; import ru.kayashov.bar.controller.dto.ingredient.IngredientSimpleResponseDto;
import ru.kayashov.bar.mapper.IngredientMapper; import ru.kayashov.bar.mapper.IngredientMapper;
import ru.kayashov.bar.repository.BarIngredientStorageRepository; import ru.kayashov.bar.model.entity.BarEntity;
import ru.kayashov.bar.model.entity.IngredientEntity; import ru.kayashov.bar.model.entity.IngredientEntity;
import ru.kayashov.bar.model.entity.TypeEntity; import ru.kayashov.bar.model.entity.TypeEntity;
import ru.kayashov.bar.repository.BarEntityRepository;
import ru.kayashov.bar.repository.IngredientRepository; import ru.kayashov.bar.repository.IngredientRepository;
import ru.kayashov.bar.repository.TypeRepository; import ru.kayashov.bar.repository.TypeRepository;
import java.util.ArrayList;
import java.util.List; import java.util.List;
@Slf4j @Slf4j
@@ -19,16 +21,10 @@ import java.util.List;
@RequiredArgsConstructor @RequiredArgsConstructor
public class IngredientService { public class IngredientService {
private final VisitorService visitorService;
private final TypeRepository typeRepository; private final TypeRepository typeRepository;
private final IngredientRepository repository; private final IngredientRepository repository;
private final IngredientMapper mapper; private final IngredientMapper mapper;
private final BarIngredientStorageRepository barIngredientStorageRepository; private final BarEntityRepository barEntityRepository;
public IngredientEntity findIngredientByName(String name) {
return repository.findByEnNameIgnoreCase(name)
.orElseThrow(() -> new RuntimeException("Не удалось найти ингредиент с названием " + name));
}
private TypeEntity findTypeByName(String name) { private TypeEntity findTypeByName(String name) {
return typeRepository.findByName(name) return typeRepository.findByName(name)
@@ -53,20 +49,15 @@ public class IngredientService {
} }
public void changeBarIngredient(Long id, boolean isHave) { public void changeBarIngredient(Long id, boolean isHave) {
// Visitor visitor = visitorService.getCurrentVisitor(); BarEntity bar = barEntityRepository.findByActiveTrue().orElseThrow();
// List<BarIngredientStorage> storage = bar.getIngredients(); IngredientEntity ingredientEntity = getIngredientById(id);
// IngredientEntity ingredientEntity = getIngredientById(id);
// if (isHave) { if (isHave) {
// BarIngredientStorage entity = new BarIngredientStorage(); bar.getIngredients().add(ingredientEntity);
// entity.setBar(bar); } else {
// entity.setIngredient(ingredientEntity); bar.getIngredients().remove(ingredientEntity);
// entity = barIngredientStorageRepository.save(entity); }
// storage.add(entity); barEntityRepository.save(bar);
// } else {
// storage.stream()
// .filter(s -> Objects.equals(s.getIngredient().getId(), ingredientEntity.getId()))
// .forEach(s -> barIngredientStorageRepository.deleteById(s.getId()));
// }
} }
public boolean saveChange(IngredientResponseDto dto) { public boolean saveChange(IngredientResponseDto dto) {
@@ -81,8 +72,6 @@ public class IngredientService {
entity.setName(dto.getName()); entity.setName(dto.getName());
entity.setDescription(dto.getDescription()); entity.setDescription(dto.getDescription());
// entity.setEnName(dto.getEnName());
// entity.setIsHave(dto.isHave());
entity.setAbv(dto.getAbv()); entity.setAbv(dto.getAbv());
entity.setAlcohol(dto.getAlcohol()); entity.setAlcohol(dto.getAlcohol());

View File

@@ -3,7 +3,9 @@ package ru.kayashov.bar.service;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ru.kayashov.bar.model.entity.IngredientEntity;
import ru.kayashov.bar.model.entity.Visitor; import ru.kayashov.bar.model.entity.Visitor;
import ru.kayashov.bar.repository.BarEntityRepository;
import ru.kayashov.bar.repository.VisitorsRepository; import ru.kayashov.bar.repository.VisitorsRepository;
import java.util.ArrayList; import java.util.ArrayList;
@@ -14,6 +16,7 @@ import java.util.List;
public class VisitorService { public class VisitorService {
private final VisitorsRepository visitorsRepository; private final VisitorsRepository visitorsRepository;
private final BarEntityRepository barRepository;
public Visitor getCurrentVisitor() { public Visitor getCurrentVisitor() {
Long id = ((Visitor) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getId(); Long id = ((Visitor) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getId();
@@ -25,15 +28,10 @@ public class VisitorService {
} }
public List<Long> getAllowedIngredients() { public List<Long> getAllowedIngredients() {
return new ArrayList<>(); return barRepository.findByActiveTrue().orElseThrow()
// return getCurrentVisitor().getResidents() .getIngredients()
// .stream() .stream()
// .filter(BarResident::getActive) .map(IngredientEntity::getId)
// .map(BarResident::getBar) .toList();
// .map(BarEntity::getIngredients)
// .flatMap(List::stream)
// .map(BarIngredientStorage::getIngredient)
// .map(IngredientEntity::getId)
// .toList();
} }
} }