Added bulk material update endpoint and support for deprecation handling logic:
- **Controller**: Introduced `updateMaterial` method in `MaterialController` for batch material updates. - **Service**: Implemented update logic in `MaterialService` to handle both updates and deprecations based on the new `MaterialUpdateDTO`. - **Transformer**: Updated `MaterialUpdateDTOTransformer` to map deprecation status and remove unused fields. - **Repository**: Added `updateByPartNumber` and `deleteByIds` methods in `MaterialRepository` for efficient updates and deprecations.
This commit is contained in:
parent
6ab0f4d630
commit
ae10417c44
5 changed files with 67 additions and 51 deletions
|
|
@ -1,10 +1,12 @@
|
||||||
package de.avatic.lcc.controller.configuration;
|
package de.avatic.lcc.controller.configuration;
|
||||||
|
|
||||||
|
import de.avatic.lcc.dto.configuration.material.update.MaterialUpdateDTO;
|
||||||
import de.avatic.lcc.dto.configuration.material.view.MaterialDetailDTO;
|
import de.avatic.lcc.dto.configuration.material.view.MaterialDetailDTO;
|
||||||
import de.avatic.lcc.dto.generic.MaterialDTO;
|
import de.avatic.lcc.dto.generic.MaterialDTO;
|
||||||
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
||||||
import de.avatic.lcc.service.access.MaterialService;
|
import de.avatic.lcc.service.access.MaterialService;
|
||||||
import jakarta.validation.constraints.Min;
|
import jakarta.validation.constraints.Min;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
|
@ -44,7 +46,7 @@ public class MaterialController {
|
||||||
@RequestParam(defaultValue = "1") @Min(1) int page,
|
@RequestParam(defaultValue = "1") @Min(1) int page,
|
||||||
@RequestParam(required = false) Optional<String> filter) {
|
@RequestParam(required = false) Optional<String> filter) {
|
||||||
|
|
||||||
SearchQueryResult<MaterialDTO> materials = materialService.listMaterial(filter, page, limit,Boolean.parseBoolean(excludeDeprecated));
|
SearchQueryResult<MaterialDTO> materials = materialService.listMaterial(filter, page, limit, Boolean.parseBoolean(excludeDeprecated));
|
||||||
|
|
||||||
return ResponseEntity.ok()
|
return ResponseEntity.ok()
|
||||||
.header("X-Total-Count", String.valueOf(materials.getTotalElements()))
|
.header("X-Total-Count", String.valueOf(materials.getTotalElements()))
|
||||||
|
|
@ -65,4 +67,11 @@ public class MaterialController {
|
||||||
public ResponseEntity<MaterialDetailDTO> getMaterialDetails(@PathVariable Integer id) {
|
public ResponseEntity<MaterialDetailDTO> getMaterialDetails(@PathVariable Integer id) {
|
||||||
return ResponseEntity.ok(materialService.getMaterial(id));
|
return ResponseEntity.ok(materialService.getMaterial(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PutMapping({"/", ""})
|
||||||
|
@PreAuthorize("hasRole('MATERIAL')")
|
||||||
|
public ResponseEntity<Void> updateMaterial(List<@Size(max = 100, min = 1) MaterialUpdateDTO> materials) {
|
||||||
|
materialService.updateMaterial(materials);
|
||||||
|
return ResponseEntity.ok().build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5,38 +5,20 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class MaterialUpdateDTO {
|
public class MaterialUpdateDTO {
|
||||||
private Integer id;
|
|
||||||
@JsonProperty("part_number")
|
@JsonProperty("part_number")
|
||||||
private String partNumber;
|
private String partNumber;
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
@JsonProperty("hs_code")
|
||||||
private String hsCode;
|
private String hsCode;
|
||||||
|
|
||||||
|
private boolean delete;
|
||||||
|
|
||||||
public MaterialUpdateDTO() {
|
public MaterialUpdateDTO() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public MaterialUpdateDTO(Integer id, String partNumber, String name, String hsCode) {
|
|
||||||
this.id = id;
|
|
||||||
this.partNumber = partNumber;
|
|
||||||
this.name = name;
|
|
||||||
this.hsCode = hsCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHsCode() {
|
|
||||||
return hsCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHsCode(String hsCode) {
|
|
||||||
this.hsCode = hsCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(Integer id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPartNumber() {
|
public String getPartNumber() {
|
||||||
return partNumber;
|
return partNumber;
|
||||||
}
|
}
|
||||||
|
|
@ -53,28 +35,19 @@ public class MaterialUpdateDTO {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public String getHsCode() {
|
||||||
public String toString() {
|
return hsCode;
|
||||||
return "MaterialSummaryDTO{" +
|
|
||||||
"id='" + id + '\'' +
|
|
||||||
", partNumber='" + partNumber + '\'' +
|
|
||||||
", name='" + name + '\'' +
|
|
||||||
'}';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setHsCode(String hsCode) {
|
||||||
public boolean equals(Object o) {
|
this.hsCode = hsCode;
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
MaterialUpdateDTO that = (MaterialUpdateDTO) o;
|
|
||||||
return Objects.equals(id, that.id) &&
|
|
||||||
Objects.equals(partNumber, that.partNumber) &&
|
|
||||||
Objects.equals(name, that.name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public boolean isDelete() {
|
||||||
public int hashCode() {
|
return delete;
|
||||||
return Objects.hash(id, partNumber, name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDelete(boolean delete) {
|
||||||
|
this.delete = delete;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,12 @@ public class MaterialRepository {
|
||||||
return Optional.ofNullable(jdbcTemplate.update(updateQuery, material.getName(), material.getPartNumber(), material.getNormalizedPartNumber(), material.getHsCode(), material.getId()) == 0 ? null : material.getId());
|
return Optional.ofNullable(jdbcTemplate.update(updateQuery, material.getName(), material.getPartNumber(), material.getNormalizedPartNumber(), material.getHsCode(), material.getId()) == 0 ? null : material.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void updateByPartNumber(Material material) {
|
||||||
|
String updateQuery = "UPDATE material SET name = ?, part_number = ?, normalized_part_number = ?, hs_code = ? WHERE normalized_part_number = ?";
|
||||||
|
jdbcTemplate.update(updateQuery, material.getName(), material.getPartNumber(), material.getNormalizedPartNumber(), material.getHsCode(), material.getNormalizedPartNumber());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all IDs from the input list that don't exist in the material table
|
* Returns all IDs from the input list that don't exist in the material table
|
||||||
* @param ids List of integers to check
|
* @param ids List of integers to check
|
||||||
|
|
@ -198,6 +204,16 @@ public class MaterialRepository {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void deleteByIds(List<Integer> ids) {
|
||||||
|
String placeholders = ids.stream()
|
||||||
|
.map(id -> "?")
|
||||||
|
.collect(Collectors.joining(","));
|
||||||
|
|
||||||
|
String sql = "UPDATE material SET is_deprecated = TRUE WHERE id IN ("+placeholders+")";
|
||||||
|
|
||||||
|
jdbcTemplate.update(sql, ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class MaterialMapper implements RowMapper<Material> {
|
private static class MaterialMapper implements RowMapper<Material> {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package de.avatic.lcc.service.access;
|
package de.avatic.lcc.service.access;
|
||||||
|
|
||||||
|
import de.avatic.lcc.dto.configuration.material.update.MaterialUpdateDTO;
|
||||||
import de.avatic.lcc.dto.configuration.material.view.MaterialDetailDTO;
|
import de.avatic.lcc.dto.configuration.material.view.MaterialDetailDTO;
|
||||||
import de.avatic.lcc.dto.generic.MaterialDTO;
|
import de.avatic.lcc.dto.generic.MaterialDTO;
|
||||||
import de.avatic.lcc.model.db.materials.Material;
|
import de.avatic.lcc.model.db.materials.Material;
|
||||||
|
|
@ -8,10 +9,13 @@ import de.avatic.lcc.repositories.pagination.SearchQueryPagination;
|
||||||
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
||||||
import de.avatic.lcc.service.transformer.generic.MaterialTransformer;
|
import de.avatic.lcc.service.transformer.generic.MaterialTransformer;
|
||||||
import de.avatic.lcc.service.transformer.material.MaterialDetailTransformer;
|
import de.avatic.lcc.service.transformer.material.MaterialDetailTransformer;
|
||||||
|
import de.avatic.lcc.service.transformer.material.MaterialUpdateDTOTransformer;
|
||||||
import de.avatic.lcc.util.exception.badrequest.MaterialNotFoundException;
|
import de.avatic.lcc.util.exception.badrequest.MaterialNotFoundException;
|
||||||
import de.avatic.lcc.util.exception.badrequest.NotFoundException;
|
import de.avatic.lcc.util.exception.badrequest.NotFoundException;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -25,6 +29,7 @@ public class MaterialService {
|
||||||
private final MaterialRepository materialRepository;
|
private final MaterialRepository materialRepository;
|
||||||
private final MaterialTransformer materialTransformer;
|
private final MaterialTransformer materialTransformer;
|
||||||
private final MaterialDetailTransformer materialDetailTransformer;
|
private final MaterialDetailTransformer materialDetailTransformer;
|
||||||
|
private final MaterialUpdateDTOTransformer materialUpdateDTOTransformer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for MaterialService.
|
* Constructor for MaterialService.
|
||||||
|
|
@ -33,10 +38,11 @@ public class MaterialService {
|
||||||
* @param materialTransformer transformer to convert material entities to DTOs
|
* @param materialTransformer transformer to convert material entities to DTOs
|
||||||
* @param materialDetailTransformer transformer to convert material entities to detail DTOs
|
* @param materialDetailTransformer transformer to convert material entities to detail DTOs
|
||||||
*/
|
*/
|
||||||
public MaterialService(MaterialRepository materialRepository, MaterialTransformer materialTransformer, MaterialDetailTransformer materialDetailTransformer) {
|
public MaterialService(MaterialRepository materialRepository, MaterialTransformer materialTransformer, MaterialDetailTransformer materialDetailTransformer, MaterialUpdateDTOTransformer materialUpdateDTOTransformer) {
|
||||||
this.materialRepository = materialRepository;
|
this.materialRepository = materialRepository;
|
||||||
this.materialTransformer = materialTransformer;
|
this.materialTransformer = materialTransformer;
|
||||||
this.materialDetailTransformer = materialDetailTransformer;
|
this.materialDetailTransformer = materialDetailTransformer;
|
||||||
|
this.materialUpdateDTOTransformer = materialUpdateDTOTransformer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -62,7 +68,20 @@ public class MaterialService {
|
||||||
* @throws MaterialNotFoundException if no material with the given ID is found
|
* @throws MaterialNotFoundException if no material with the given ID is found
|
||||||
*/
|
*/
|
||||||
public MaterialDetailDTO getMaterial(Integer id) {
|
public MaterialDetailDTO getMaterial(Integer id) {
|
||||||
return materialDetailTransformer.toMaterialDetailDTO(materialRepository.getByIdIncludeDeprecated(id).orElseThrow(() -> new NotFoundException(NotFoundException.NotFoundType.MATERIAL,id.toString())));
|
return materialDetailTransformer.toMaterialDetailDTO(materialRepository.getByIdIncludeDeprecated(id).orElseThrow(() -> new NotFoundException(NotFoundException.NotFoundType.MATERIAL, id.toString())));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateMaterial(List<@Size(max = 100, min = 1) MaterialUpdateDTO> dtos) {
|
||||||
|
var materials = dtos.stream().map(materialUpdateDTOTransformer::fromMaterialUpdateDTO).toList();
|
||||||
|
var toBeDeleted = materials.stream().filter(m -> m.getDeprecated() != null && m.getDeprecated()).map(Material::getId).toList();
|
||||||
|
var toBeUpdated = materials.stream().filter(m -> m.getDeprecated() != null && m.getDeprecated()).toList();
|
||||||
|
|
||||||
|
if (!toBeDeleted.isEmpty())
|
||||||
|
toBeDeleted.forEach(materialRepository::setDeprecatedById);
|
||||||
|
|
||||||
|
if (!toBeUpdated.isEmpty())
|
||||||
|
toBeUpdated.forEach(materialRepository::updateByPartNumber);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import de.avatic.lcc.dto.configuration.material.update.MaterialUpdateDTO;
|
||||||
import de.avatic.lcc.model.db.materials.Material;
|
import de.avatic.lcc.model.db.materials.Material;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
@Service
|
@Service
|
||||||
public class MaterialUpdateDTOTransformer {
|
public class MaterialUpdateDTOTransformer {
|
||||||
|
|
||||||
|
|
@ -15,8 +15,7 @@ public class MaterialUpdateDTOTransformer {
|
||||||
entity.setNormalizedPartNumber(normalizePartNumber(dto.getPartNumber()));
|
entity.setNormalizedPartNumber(normalizePartNumber(dto.getPartNumber()));
|
||||||
entity.setPartNumber(dto.getPartNumber());
|
entity.setPartNumber(dto.getPartNumber());
|
||||||
entity.setName(dto.getName());
|
entity.setName(dto.getName());
|
||||||
entity.setDeprecated(false);
|
entity.setDeprecated(!dto.isDelete());
|
||||||
entity.setId(dto.getId());
|
|
||||||
entity.setHsCode(dto.getHsCode());
|
entity.setHsCode(dto.getHsCode());
|
||||||
|
|
||||||
return entity;
|
return entity;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue