diff --git a/src/main/java/de/avatic/lcc/controller/MaterialController.java b/src/main/java/de/avatic/lcc/controller/MaterialController.java index 0128d21..becf544 100644 --- a/src/main/java/de/avatic/lcc/controller/MaterialController.java +++ b/src/main/java/de/avatic/lcc/controller/MaterialController.java @@ -2,9 +2,8 @@ package de.avatic.lcc.controller; import de.avatic.lcc.model.materials.Material; import de.avatic.lcc.model.materials.MaterialListEntry; -import de.avatic.lcc.repositories.MaterialRepository; -import de.avatic.lcc.repositories.utils.SearchQueryPagination; import de.avatic.lcc.repositories.utils.SearchQueryResult; +import de.avatic.lcc.service.MaterialService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -16,11 +15,11 @@ import java.util.List; public class MaterialController { - private final MaterialRepository materialRepository; + private final MaterialService materialService; @Autowired - public MaterialController(MaterialRepository materialRepository) { - this.materialRepository = materialRepository; + public MaterialController(MaterialService materialService) { + this.materialService = materialService; } /** @@ -38,7 +37,7 @@ public class MaterialController { @RequestParam(defaultValue = "0") int page, @RequestParam(required = false, defaultValue = "") String filter) { - SearchQueryResult materials = materialRepository.listMaterials(filter, new SearchQueryPagination(page, limit)); + SearchQueryResult materials = materialService.listMaterials(filter, page, limit); return ResponseEntity.ok() .header("X-Total-Count", String.valueOf(materials.getTotalElements())) @@ -56,7 +55,7 @@ public class MaterialController { */ @GetMapping("/{id}") public ResponseEntity getMaterialDetails(@PathVariable Integer id) { - return ResponseEntity.ok(materialRepository.getMaterialDetails(id).orElseThrow(() -> new RuntimeException("Material not found with id " + id))); + return ResponseEntity.ok(materialService.getMaterial(id)); } /** @@ -66,15 +65,11 @@ public class MaterialController { * @param material The updated material details * @return The updated material */ - @PutMapping("/{id}") public ResponseEntity updateMaterial( @PathVariable Integer id, @RequestBody Material material) { - - material.setId(id); - Material updatedMaterial = materialRepository.update(material); - return ResponseEntity.ok(updatedMaterial); + return ResponseEntity.ok(materialService.updateMaterial(id, material)); } /** @@ -86,7 +81,12 @@ public class MaterialController { */ @DeleteMapping("/{id}") public ResponseEntity deleteMaterial(@PathVariable Integer id) { - materialRepository.deleteById(id); + materialService.deleteMaterial(id); return ResponseEntity.noContent().build(); } + + @PostMapping("/") + public ResponseEntity createMaterial(@RequestBody Material material) { + return ResponseEntity.ok(materialService.createMaterial(material)); + } } \ No newline at end of file diff --git a/src/main/java/de/avatic/lcc/repositories/MaterialRepository.java b/src/main/java/de/avatic/lcc/repositories/MaterialRepository.java index 63f2991..33add49 100644 --- a/src/main/java/de/avatic/lcc/repositories/MaterialRepository.java +++ b/src/main/java/de/avatic/lcc/repositories/MaterialRepository.java @@ -10,9 +10,14 @@ import de.avatic.lcc.repositories.utils.SearchQueryResult; import de.avatic.lcc.repositories.utils.UnitConverter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; +import java.sql.PreparedStatement; +import java.sql.Statement; +import java.util.Objects; import java.util.Optional; @Repository @@ -46,7 +51,7 @@ public class MaterialRepository { } @Transactional - public Optional getMaterialDetails(Integer id) { + public Optional getById(Integer id) { String query = "SELECT * FROM material WHERE id = ? AND is_deprecated = FALSE"; Material material = jdbcTemplate.queryForObject(query, (rs, rowNum) -> { @@ -134,4 +139,26 @@ public class MaterialRepository { jdbcTemplate.update(updateQuery, material.getName(), material.getPartNumber(), material.getNormalizedPartNumber(), material.getHsCode(), material.getId()); return material; } + + @Transactional + public Optional create(Material material) { + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + jdbcTemplate.update(connection -> { + PreparedStatement ps = connection + .prepareStatement("INSERT INTO material (name, part_number, normalized_part_number, hs_code) VALUES (?, ?, ?, ?)", + Statement.RETURN_GENERATED_KEYS); + ps.setString(1, material.getName()); // + ps.setString(2, material.getPartNumber()); + ps.setString(3, material.getNormalizedPartNumber()); + ps.setString(4, material.getHsCode()); + return ps; + }, keyHolder); + + + return Optional.ofNullable(!Objects.requireNonNull(keyHolder.getKeys()).isEmpty() ? ((Integer) keyHolder.getKeys().values().iterator().next()) + : null); + + } } diff --git a/src/main/java/de/avatic/lcc/service/MaterialService.java b/src/main/java/de/avatic/lcc/service/MaterialService.java new file mode 100644 index 0000000..d09e37e --- /dev/null +++ b/src/main/java/de/avatic/lcc/service/MaterialService.java @@ -0,0 +1,46 @@ +package de.avatic.lcc.service; + +import de.avatic.lcc.model.materials.Material; +import de.avatic.lcc.model.materials.MaterialListEntry; +import de.avatic.lcc.repositories.MaterialRepository; +import de.avatic.lcc.repositories.utils.SearchQueryPagination; +import de.avatic.lcc.repositories.utils.SearchQueryResult; +import org.springframework.stereotype.Service; + +@Service +public class MaterialService { + + MaterialRepository materialRepository; + + public MaterialService(MaterialRepository materialRepository) { + this.materialRepository = materialRepository; + } + + public Material updateMaterial(Integer id, Material material) { + material.setId(id); + material.setNormalizedPartNumber(normalizePartNumber(material.getPartNumber())); + return materialRepository.update(material); + } + + private String normalizePartNumber(String partNumber) { + if(partNumber.length() > 12) throw new IllegalArgumentException("Part number must be less than 12 characters"); + return "000000000000".concat(partNumber).substring(partNumber.length()); + } + + public Material getMaterial(Integer id) { + return materialRepository.getById(id).orElseThrow(() -> new RuntimeException("Material not found with id " + id)); + } + + public Integer createMaterial(Material material) { + material.setNormalizedPartNumber(normalizePartNumber(material.getPartNumber())); + return materialRepository.create(material).orElseThrow(() -> new RuntimeException("Unable to create Material " + material)); + } + + public SearchQueryResult listMaterials(String filter, int page, int limit) { + return materialRepository.listMaterials(filter, new SearchQueryPagination(page, limit)); + } + + public void deleteMaterial(Integer id) { + materialRepository.deleteById(id); + } +}