WIP: Update morefiles #152
@@ -0,0 +1,76 @@
|
||||
package com.petshop.backend.controller;
|
||||
|
||||
import com.petshop.backend.dto.pet.MyPetRequest;
|
||||
import com.petshop.backend.dto.pet.MyPetResponse;
|
||||
import com.petshop.backend.entity.User;
|
||||
import com.petshop.backend.repository.UserRepository;
|
||||
import com.petshop.backend.service.PetService;
|
||||
import com.petshop.backend.util.AuthenticationHelper;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/my-pets")
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
public class MyPetController {
|
||||
|
||||
private final PetService petService;
|
||||
private final UserRepository userRepository;
|
||||
|
||||
public MyPetController(PetService petService, UserRepository userRepository) {
|
||||
this.petService = petService;
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public ResponseEntity<List<MyPetResponse>> getMyPets() {
|
||||
return ResponseEntity.ok(petService.getMyPets(currentUserId()));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<MyPetResponse> createMyPet(@Valid @RequestBody MyPetRequest request) {
|
||||
return ResponseEntity.ok(petService.createMyPet(currentUserId(), request));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public ResponseEntity<MyPetResponse> updateMyPet(@PathVariable Long id, @Valid @RequestBody MyPetRequest request) {
|
||||
return ResponseEntity.ok(petService.updateMyPet(currentUserId(), id, request));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public ResponseEntity<Void> deleteMyPet(@PathVariable Long id) {
|
||||
petService.deleteMyPet(currentUserId(), id);
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/image")
|
||||
public ResponseEntity<?> uploadMyPetImage(@PathVariable Long id, @RequestParam("image") MultipartFile image) {
|
||||
try {
|
||||
return ResponseEntity.ok(petService.uploadMyPetImage(currentUserId(), id, image));
|
||||
} catch (IllegalArgumentException ex) {
|
||||
return ResponseEntity.badRequest().body(Map.of("message", ex.getMessage()));
|
||||
} catch (IOException ex) {
|
||||
return ResponseEntity.badRequest().body(Map.of("message", "Failed to upload pet image: " + ex.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
private Long currentUserId() {
|
||||
User user = AuthenticationHelper.getAuthenticatedUser(userRepository);
|
||||
return user.getId();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.petshop.backend.dto.pet;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Size;
|
||||
|
||||
public class MyPetRequest {
|
||||
|
||||
@NotBlank(message = "Pet name is required")
|
||||
@Size(max = 50, message = "Pet name must not exceed 50 characters")
|
||||
private String petName;
|
||||
|
||||
@NotBlank(message = "Species is required")
|
||||
@Size(max = 50, message = "Species must not exceed 50 characters")
|
||||
private String species;
|
||||
|
||||
@Size(max = 50, message = "Breed must not exceed 50 characters")
|
||||
private String breed;
|
||||
|
||||
public String getPetName() {
|
||||
return petName;
|
||||
}
|
||||
|
||||
public void setPetName(String petName) {
|
||||
this.petName = petName;
|
||||
}
|
||||
|
||||
public String getSpecies() {
|
||||
return species;
|
||||
}
|
||||
|
||||
public void setSpecies(String species) {
|
||||
this.species = species;
|
||||
}
|
||||
|
||||
public String getBreed() {
|
||||
return breed;
|
||||
}
|
||||
|
||||
public void setBreed(String breed) {
|
||||
this.breed = breed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.petshop.backend.dto.pet;
|
||||
|
||||
public class MyPetResponse {
|
||||
|
||||
private Long customerPetId;
|
||||
private String petName;
|
||||
private String species;
|
||||
private String breed;
|
||||
private String imageUrl;
|
||||
|
||||
public MyPetResponse() {
|
||||
}
|
||||
|
||||
public MyPetResponse(Long customerPetId, String petName, String species, String breed, String imageUrl) {
|
||||
this.customerPetId = customerPetId;
|
||||
this.petName = petName;
|
||||
this.species = species;
|
||||
this.breed = breed;
|
||||
this.imageUrl = imageUrl;
|
||||
}
|
||||
|
||||
public Long getCustomerPetId() {
|
||||
return customerPetId;
|
||||
}
|
||||
|
||||
public void setCustomerPetId(Long customerPetId) {
|
||||
this.customerPetId = customerPetId;
|
||||
}
|
||||
|
||||
public String getPetName() {
|
||||
return petName;
|
||||
}
|
||||
|
||||
public void setPetName(String petName) {
|
||||
this.petName = petName;
|
||||
}
|
||||
|
||||
public String getSpecies() {
|
||||
return species;
|
||||
}
|
||||
|
||||
public void setSpecies(String species) {
|
||||
this.species = species;
|
||||
}
|
||||
|
||||
public String getBreed() {
|
||||
return breed;
|
||||
}
|
||||
|
||||
public void setBreed(String breed) {
|
||||
this.breed = breed;
|
||||
}
|
||||
|
||||
public String getImageUrl() {
|
||||
return imageUrl;
|
||||
}
|
||||
|
||||
public void setImageUrl(String imageUrl) {
|
||||
this.imageUrl = imageUrl;
|
||||
}
|
||||
}
|
||||
@@ -9,11 +9,14 @@ import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface PetRepository extends JpaRepository<Pet, Long> {
|
||||
|
||||
List<Pet> findAllByPetStatusIgnoreCaseOrderByPetNameAsc(String petStatus);
|
||||
List<Pet> findAllByOwner_IdOrderByPetNameAsc(Long ownerId);
|
||||
Optional<Pet> findByIdAndOwner_Id(Long id, Long ownerId);
|
||||
|
||||
@Query("SELECT p FROM Pet p WHERE " +
|
||||
"(:q IS NULL OR LOWER(p.petName) LIKE LOWER(CONCAT('%', :q, '%')) OR LOWER(p.petSpecies) LIKE LOWER(CONCAT('%', :q, '%')) OR LOWER(COALESCE(p.petBreed, '')) LIKE LOWER(CONCAT('%', :q, '%'))) AND " +
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.petshop.backend.service;
|
||||
|
||||
import com.petshop.backend.dto.common.BulkDeleteRequest;
|
||||
import com.petshop.backend.dto.pet.MyPetRequest;
|
||||
import com.petshop.backend.dto.pet.MyPetResponse;
|
||||
import com.petshop.backend.dto.pet.PetRequest;
|
||||
import com.petshop.backend.dto.pet.PetResponse;
|
||||
import com.petshop.backend.entity.Adoption;
|
||||
@@ -25,6 +27,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
@Service
|
||||
@@ -82,6 +85,50 @@ public class PetService {
|
||||
return mapToResponse(pet);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<MyPetResponse> getMyPets(Long ownerUserId) {
|
||||
return petRepository.findAllByOwner_IdOrderByPetNameAsc(ownerUserId).stream()
|
||||
.map(this::mapToMyPetResponse)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public MyPetResponse createMyPet(Long ownerUserId, MyPetRequest request) {
|
||||
User owner = userRepository.findById(ownerUserId)
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Customer not found with id: " + ownerUserId));
|
||||
Pet pet = new Pet();
|
||||
pet.setOwner(owner);
|
||||
pet.setStore(null);
|
||||
pet.setPetStatus("Owned");
|
||||
applyMyPetRequest(pet, request);
|
||||
return mapToMyPetResponse(petRepository.save(pet));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public MyPetResponse updateMyPet(Long ownerUserId, Long petId, MyPetRequest request) {
|
||||
Pet pet = findOwnedPet(ownerUserId, petId);
|
||||
pet.setPetStatus("Owned");
|
||||
pet.setStore(null);
|
||||
applyMyPetRequest(pet, request);
|
||||
return mapToMyPetResponse(petRepository.save(pet));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteMyPet(Long ownerUserId, Long petId) {
|
||||
Pet pet = findOwnedPet(ownerUserId, petId);
|
||||
deleteStoredImageIfPresent(pet.getImageUrl());
|
||||
petRepository.delete(pet);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public MyPetResponse uploadMyPetImage(Long ownerUserId, Long petId, MultipartFile file) throws IOException {
|
||||
validateImageFile(file);
|
||||
Pet pet = findOwnedPet(ownerUserId, petId);
|
||||
deleteStoredImageIfPresent(pet.getImageUrl());
|
||||
pet.setImageUrl(catalogImageStorageService.storePetImage(file));
|
||||
return mapToMyPetResponse(petRepository.save(pet));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public PetResponse createPet(PetRequest request) {
|
||||
Pet pet = new Pet();
|
||||
@@ -225,6 +272,11 @@ public class PetService {
|
||||
}
|
||||
}
|
||||
|
||||
private Pet findOwnedPet(Long ownerUserId, Long petId) {
|
||||
return petRepository.findByIdAndOwner_Id(petId, ownerUserId)
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Pet not found with id: " + petId));
|
||||
}
|
||||
|
||||
private void deleteStoredImageIfPresent(String storedImagePath) {
|
||||
if (storedImagePath == null || storedImagePath.isBlank()) {
|
||||
return;
|
||||
@@ -276,6 +328,32 @@ public class PetService {
|
||||
);
|
||||
}
|
||||
|
||||
private MyPetResponse mapToMyPetResponse(Pet pet) {
|
||||
return new MyPetResponse(
|
||||
pet.getPetId(),
|
||||
pet.getPetName(),
|
||||
pet.getPetSpecies(),
|
||||
pet.getPetBreed(),
|
||||
pet.getImageUrl() != null && !pet.getImageUrl().isBlank() ? "/api/v1/pets/" + pet.getPetId() + "/image" : null
|
||||
);
|
||||
}
|
||||
|
||||
private void applyMyPetRequest(Pet pet, MyPetRequest request) {
|
||||
pet.setPetName(request.getPetName().trim());
|
||||
pet.setPetSpecies(request.getSpecies().trim());
|
||||
pet.setPetBreed(normalizeOptional(request.getBreed()));
|
||||
pet.setPetAge(null);
|
||||
pet.setPetPrice(null);
|
||||
}
|
||||
|
||||
private String normalizeOptional(String value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
String trimmed = value.trim();
|
||||
return trimmed.isEmpty() ? null : trimmed;
|
||||
}
|
||||
|
||||
private void applyOwnerAndStore(Pet pet, PetRequest request) {
|
||||
if ("owned".equalsIgnoreCase(request.getPetStatus())) {
|
||||
if (request.getCustomerId() != null) {
|
||||
|
||||
Reference in New Issue
Block a user