diff --git a/backend/src/main/java/com/petshop/backend/service/AppointmentService.java b/backend/src/main/java/com/petshop/backend/service/AppointmentService.java index 999568a8..9c63733a 100644 --- a/backend/src/main/java/com/petshop/backend/service/AppointmentService.java +++ b/backend/src/main/java/com/petshop/backend/service/AppointmentService.java @@ -127,8 +127,6 @@ public class AppointmentService { } } - validateSpeciesServiceCompatibility(pet, service); - validateStoreAccess(store.getStoreId(), authenticatedUser); validatePetServiceCompatibility(pet, service); validateAvailability(employee, service, request.getAppointmentDate(), request.getAppointmentTime(), null); @@ -387,32 +385,6 @@ public class AppointmentService { return true; } - private void validateSpeciesServiceCompatibility(Pet pet, com.petshop.backend.entity.Service service) { - if (pet == null || service == null) return; - String species = pet.getPetSpecies(); - if (species == null) return; - String serviceName = service.getServiceName().toLowerCase(); - - switch (species.toLowerCase()) { - case "bird": - if (!serviceName.contains("wing clipping") && !serviceName.contains("beak and nail")) { - throw new IllegalArgumentException( - "Service '" + service.getServiceName() + "' is not available for birds. " + - "Allowed services: Wing Clipping, Beak and Nail Care."); - } - break; - case "fish": - if (!serviceName.contains("aquarium health")) { - throw new IllegalArgumentException( - "Service '" + service.getServiceName() + "' is not available for fish. " + - "Allowed service: Aquarium Health Check."); - } - break; - default: - break; - } - } - private void validateStoreAccess(Long requestedStoreId, User user) { if (user.getRole() != User.Role.STAFF) { return; diff --git a/backend/src/main/resources/db/migration/V7__fix_service_species.sql b/backend/src/main/resources/db/migration/V7__fix_service_species.sql new file mode 100644 index 00000000..4c22a1b0 --- /dev/null +++ b/backend/src/main/resources/db/migration/V7__fix_service_species.sql @@ -0,0 +1,14 @@ +DELETE FROM service_species WHERE serviceId = 2 AND species = 'Bird'; + +INSERT INTO service_species (serviceId, species) VALUES +(1, 'Guinea Pig'), +(1, 'Hamster'), +(1, 'Other'), +(2, 'Reptile'), +(2, 'Other'), +(3, 'Reptile'), +(3, 'Other'), +(4, 'Reptile'), +(4, 'Other'), +(5, 'Reptile'), +(5, 'Other'); diff --git a/web/app/appointments/page.js b/web/app/appointments/page.js index 58b741f9..876981c6 100644 --- a/web/app/appointments/page.js +++ b/web/app/appointments/page.js @@ -20,20 +20,22 @@ const SPECIES_BREEDS = { Other: ["Other"], }; -// Explicit allowlists for species with restricted service availability. -// Species not listed here may use all services. -const SPECIES_SERVICE_ALLOWLIST = { +const SPECIES_EXCLUSIVE_SERVICES = { Bird: ["wing clipping", "beak and nail"], Fish: ["aquarium health"], }; function getAvailableServices(services, species) { if (!species) return services; - const allowlist = SPECIES_SERVICE_ALLOWLIST[species]; - if (!allowlist) return services; - return services.filter((s) => - allowlist.some((kw) => s.serviceName.toLowerCase().includes(kw)) - ); + return services.filter((s) => { + const name = s.serviceName.toLowerCase(); + for (const [exclusiveSpecies, keywords] of Object.entries(SPECIES_EXCLUSIVE_SERVICES)) { + if (exclusiveSpecies !== species && keywords.some((kw) => name.includes(kw))) { + return false; + } + } + return true; + }); } const DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];