Skip to content

Commit

Permalink
Thumbnail, new schema offers, enable changing visibility
Browse files Browse the repository at this point in the history
  • Loading branch information
Vertonowsky committed Jun 16, 2024
1 parent 92af67d commit f6447a9
Show file tree
Hide file tree
Showing 11 changed files with 204 additions and 18 deletions.
2 changes: 2 additions & 0 deletions src/main/java/com/example/backend/common/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
public enum ErrorCode {

APPLICATION_SETTING_NOT_FOUND("APPLICATION_SETTING_NOT_FOUND"),
CAR_IDS_REQUIRED("CAR_IDS_REQUIRED"),
INPUT_DATA_INVALID("INPUT_DATA_INVALID"),
SCHEME_DATA_INVALID("SCHEME_DATA_INVALID"),
SCHEME_DATA_REQUIRED("SCHEME_DATA_REQUIRED"),
SCHEME_NOT_FOUND("SCHEME_NOT_FOUND"),
SCHEME_NAME_REQUIRED("SCHEME_NAME_REQUIRED"),
STATUS_NOT_ALLOWED("STATUS_NOT_ALLOWED"),
USER_NOT_FOUND("USER_NOT_FOUND");

private String message;
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/example/backend/scheme/CarStatus.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

public enum CarStatus {

FIRST_INITIALIZATION, NEW, DISPLAYED;
NEW, SEEN, FIRST_INITIALIZATION;

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,22 @@
import com.example.backend.page.TableDto;
import com.example.backend.exception.exceptions.EntityNotFoundException;
import com.example.backend.exception.exceptions.IllegalInputException;
import com.example.backend.scheme.dto.SchemeDisplayDto;
import com.example.backend.scheme.dto.SchemeDto;
import com.example.backend.scheme.dto.SchemeToCarDto;
import com.example.backend.scheme.serializer.SchemeSerializer;
import com.example.backend.scheme.service.SchemeService;
import com.example.backend.common.UserEmail;
import com.example.backend.scheme.model.Scheme;
import com.example.backend.scheme.service.SchemeToCarService;
import jakarta.validation.Valid;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.example.backend.scheme.serializer.SchemeSerializer.Task.BASE;
import static com.example.backend.scheme.serializer.SchemeSerializer.Task.CARS;
Expand All @@ -25,9 +30,11 @@
public class SchemeController {

private final SchemeService schemeService;
private final SchemeToCarService schemeToCarService;

public SchemeController(SchemeService schemeService) {
public SchemeController(SchemeService schemeService, SchemeToCarService schemeToCarService) {
this.schemeService = schemeService;
this.schemeToCarService = schemeToCarService;
}

@GetMapping
Expand All @@ -37,7 +44,11 @@ public TableDto<List<SchemeDto>> list(@UserEmail String email, Pageable pageable
PageSerializer.fromPageable(pageDto, pageable);
PageSerializer.fromPage(pageDto, schemas);

return new TableDto<>(pageDto, schemas.stream().map((scheme -> SchemeSerializer.serialize(scheme, BASE))).toList());
List<SchemeDto> schemeDtoList = new ArrayList<>(schemas.stream()
.map((scheme -> SchemeSerializer.serialize(scheme, BASE))).toList());
schemeService.checkNewOffersCount(schemeDtoList);

return new TableDto<>(pageDto, schemeDtoList);
}

@GetMapping("{id}")
Expand Down Expand Up @@ -65,4 +76,9 @@ public void delete(@UserEmail String email, @PathVariable("id") Long id) throws
schemeService.delete(id, email);
}

@PutMapping("visibility")
public List<SchemeToCarDto> changeVisibility(@RequestBody @Valid SchemeDisplayDto schemeDisplayDto) throws IllegalInputException {
return schemeToCarService.changeVisibility(schemeDisplayDto).stream().map(SchemeSerializer::schemeToCar).collect(Collectors.toList());
}

}
32 changes: 32 additions & 0 deletions src/main/java/com/example/backend/scheme/dto/SchemeDisplayDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.example.backend.scheme.dto;

import com.example.backend.scheme.CarStatus;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;

import java.util.Set;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class SchemeDisplayDto {

private Set<Long> ids;

private CarStatus status;

public Set<Long> getIds() {
return ids;
}

public void setIds(Set<Long> ids) {
this.ids = ids;
}

public CarStatus getStatus() {
return status;
}

public void setStatus(CarStatus status) {
this.status = status;
}
}
18 changes: 18 additions & 0 deletions src/main/java/com/example/backend/scheme/dto/SchemeDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ public class SchemeDto {
private Set<FilterValueDto> variables;
private UserDto user;
private Boolean notifications;
private String thumbnail;
private Boolean newOffers;
private List<SchemeToCarDto> cars;

public Long getId() {
Expand Down Expand Up @@ -77,4 +79,20 @@ public Boolean getNotifications() {
public void setNotifications(Boolean notifications) {
this.notifications = notifications;
}

public String getThumbnail() {
return thumbnail;
}

public void setThumbnail(String thumbnail) {
this.thumbnail = thumbnail;
}

public Boolean getNewOffers() {
return newOffers;
}

public void setNewOffers(Boolean newOffers) {
this.newOffers = newOffers;
}
}
10 changes: 10 additions & 0 deletions src/main/java/com/example/backend/scheme/model/Scheme.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ public class Scheme {
@Column(nullable = false)
private boolean notifications;

@Column(length = 512)
private String thumbnail;

@ManyToOne
@JoinColumn(name = "user_id")
private User user;
Expand Down Expand Up @@ -77,4 +80,11 @@ public void setNotifications(boolean notifications) {
this.notifications = notifications;
}

public String getThumbnail() {
return thumbnail;
}

public void setThumbnail(String defaultThumbnail) {
this.thumbnail = defaultThumbnail;
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package com.example.backend.scheme.repository;

import com.example.backend.scheme.model.Scheme;
import jakarta.transaction.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;
import java.util.Optional;
Expand All @@ -14,4 +18,15 @@ public interface SchemeRepository extends JpaRepository<Scheme, Long> {

Page<Scheme> findAllByUserEmail(String email, Pageable pageable);

@Transactional
@Modifying
@Query("UPDATE Scheme s SET s.thumbnail = :thumbnail WHERE s.id = :id")
void updateSchemeById(@Param("id") Long id, @Param("thumbnail") String thumbnail);

@Query("SELECT s.id AS schemeId, CASE WHEN COUNT(stc.id) > 0 THEN true ELSE false END AS hasNewCars " +
"FROM Scheme s LEFT JOIN SchemeToCar stc ON s.id = stc.scheme.id " +
"AND stc.status IN(com.example.backend.scheme.CarStatus.NEW, com.example.backend.scheme.CarStatus.FIRST_INITIALIZATION) " +
"WHERE s.id IN :schemaIds GROUP BY s.id")
List<Object[]> haveNewCars(@Param("schemaIds") List<Long> schemaIds);

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.Param;

import java.util.List;
import java.util.Set;

public interface SchemeToCarRepository extends JpaRepository<SchemeToCar, Long> {

List<SchemeToCar> findAllBySchemeId(Long id);

Page<SchemeToCar> findBySchemeId(Long id, Pageable pageable);

Set<SchemeToCar> findAllByIdIn(@Param("ids") Set<Long> ids);

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.example.backend.scheme.dto.SchemeToCarDto;
import com.example.backend.scheme.dto.SchemeDto;
import com.example.backend.scheme.model.Scheme;
import com.example.backend.scheme.model.SchemeToCar;
import com.example.backend.timer.otomoto.request.FilterValueDto;
import com.example.backend.timer.otomoto.request.OtomotoDto;
import com.example.backend.timer.otomoto.request.VariablesDto;
Expand Down Expand Up @@ -43,6 +44,7 @@ private static void base(SchemeDto schemeDto, Scheme scheme) {
schemeDto.setId(scheme.getId());
schemeDto.setName(scheme.getName());
schemeDto.setNotifications(scheme.isNotifications());
schemeDto.setThumbnail(scheme.getThumbnail());
try {
OtomotoDto otomotoDto = OBJECT_MAPPER.readValue(scheme.getData(), OtomotoDto.class);
Set<FilterValueDto> filterList = Optional.ofNullable(otomotoDto).map(OtomotoDto::getVariables)
Expand All @@ -60,21 +62,21 @@ private static void user(SchemeDto schemeDto, Scheme scheme) {
}

private static void cars(SchemeDto schemeDto, Scheme scheme) {
List<SchemeToCarDto> cars = scheme.getSchemeToCars().stream().map((schemeToCar -> {
SchemeToCarDto schemeToCarDto = new SchemeToCarDto();
schemeToCarDto.setId(schemeToCar.getId());
schemeToCarDto.setCarId(schemeToCar.getCarId());
schemeToCarDto.setCreatedAt(schemeToCar.getCreatedAt());
try {
schemeToCarDto.setData(OBJECT_MAPPER.readValue(schemeToCar.getData(), NodeDto.class));
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing SchemeToCar {} data!", schemeToCar.getId());
}
schemeToCarDto.setStatus(schemeToCar.getStatus());
return schemeToCarDto;
})).toList();

schemeDto.setCars(cars);
schemeDto.setCars(scheme.getSchemeToCars().stream().map(SchemeSerializer::schemeToCar).toList());
}

public static SchemeToCarDto schemeToCar(SchemeToCar schemeToCar) {
SchemeToCarDto schemeToCarDto = new SchemeToCarDto();
schemeToCarDto.setId(schemeToCar.getId());
schemeToCarDto.setCarId(schemeToCar.getCarId());
schemeToCarDto.setCreatedAt(schemeToCar.getCreatedAt());
try {
schemeToCarDto.setData(OBJECT_MAPPER.readValue(schemeToCar.getData(), NodeDto.class));
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing SchemeToCar {} data!", schemeToCar.getId());
}
schemeToCarDto.setStatus(schemeToCar.getStatus());
return schemeToCarDto;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,19 @@ public String getTimerQuery() throws EntityNotFoundException {
}
}

public void checkNewOffersCount(List<SchemeDto> schemeDtoList) {
if (schemeDtoList.isEmpty()) return;

List<Object[]> results = schemeRepository.haveNewCars(schemeDtoList.stream().map(SchemeDto::getId).toList());

schemeDtoList.forEach(schemeDto -> {
results.stream()
.filter(result -> result[0] == schemeDto.getId())
.findFirst()
.ifPresent(result -> schemeDto.setNewOffers((Boolean) result[1]));
});
}

/**
* Prepare dto which will be sent to otomoto REST API
* and run loop searching for new cars.
Expand Down Expand Up @@ -274,6 +287,7 @@ private TimerResponse calculatePageWithOtomotoData(Scheme scheme, OtomotoRespons
// Save all new cars into the database
boolean firstInitialization = scheme.getSchemeToCars().isEmpty();
saveNewCarsToDatabase(carIdToNodeDtoMap, scheme, firstInitialization);
updateDefaultThumbnail(scheme);

if (firstInitialization)
return new TimerResponse(true, diff.size());
Expand Down Expand Up @@ -337,6 +351,39 @@ private void sendNotification(Scheme scheme, Integer count) {
}
}

private void updateDefaultThumbnail(Scheme scheme) {
if (!isNullOrEmpty(scheme.getThumbnail())) return;

List<SchemeToCar> schemeToCars = scheme.getSchemeToCars().stream()
.sorted(Comparator.comparing(SchemeToCar::getCreatedAt)).toList();
String defaultThumbnail = null;

for (SchemeToCar schemeToCar : schemeToCars) {
String thumbnail = getThumbnail(schemeToCar);
if (thumbnail != null) {
defaultThumbnail = thumbnail;
break;
}
}

schemeRepository.updateSchemeById(scheme.getId(), defaultThumbnail);
}

private String getThumbnail(SchemeToCar schemeToCar) {
try {
NodeDto schemeData = OBJECT_MAPPER.readValue(schemeToCar.getData(), NodeDto.class);

return Optional.ofNullable(schemeData)
.map(NodeDto::getThumbnail)
.flatMap(thumbnailDto -> Optional.ofNullable(thumbnailDto.getX2()).filter(set -> !set.isEmpty())
.or(() -> Optional.ofNullable(thumbnailDto.getX1())))
.orElse(null);
} catch (JsonProcessingException e) {
LOGGER.error("[{}] There was an error while parsing data.", TIMER_NAME, e);
return null;
}
}

private static class TimerResponse {

private final boolean shouldFinish;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.example.backend.scheme.service;

import com.example.backend.common.ErrorCode;
import com.example.backend.exception.exceptions.IllegalInputException;
import com.example.backend.scheme.CarStatus;
import com.example.backend.scheme.dto.SchemeDisplayDto;
import com.example.backend.scheme.model.SchemeToCar;
import com.example.backend.scheme.repository.SchemeToCarRepository;
import org.springframework.stereotype.Service;

import java.util.Set;

@Service
public class SchemeToCarService {

private final SchemeToCarRepository schemeToCarRepository;

public SchemeToCarService(SchemeToCarRepository schemeToCarRepository) {
this.schemeToCarRepository = schemeToCarRepository;
}

public Set<SchemeToCar> changeVisibility(SchemeDisplayDto schemeDisplayDto) throws IllegalInputException {
CarStatus status = schemeDisplayDto.getStatus();
Set<Long> schemeToCarIds = schemeDisplayDto.getIds();

if (status == null || CarStatus.FIRST_INITIALIZATION.equals(status))
throw new IllegalInputException(ErrorCode.STATUS_NOT_ALLOWED);

if (schemeToCarIds == null || schemeToCarIds.isEmpty())
throw new IllegalInputException(ErrorCode.CAR_IDS_REQUIRED);

Set<SchemeToCar> schemeToCars = schemeToCarRepository.findAllByIdIn(schemeToCarIds);
for (SchemeToCar schemeToCar : schemeToCars)
schemeToCar.setStatus(status);

schemeToCarRepository.saveAll(schemeToCars);
return schemeToCars;
}

}

0 comments on commit f6447a9

Please sign in to comment.