diff --git a/backend/src/main/java/com/petshop/backend/config/DataInitializer.java b/backend/src/main/java/com/petshop/backend/config/DataInitializer.java index 4a8c7470..9809ddc6 100644 --- a/backend/src/main/java/com/petshop/backend/config/DataInitializer.java +++ b/backend/src/main/java/com/petshop/backend/config/DataInitializer.java @@ -2,8 +2,6 @@ package com.petshop.backend.config; import com.petshop.backend.entity.User; import com.petshop.backend.repository.UserRepository; -import com.petshop.backend.service.StoreAssignmentService; -import com.petshop.backend.service.UserBusinessLinkageService; import org.springframework.boot.CommandLineRunner; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Component; @@ -13,14 +11,10 @@ public class DataInitializer implements CommandLineRunner { private final UserRepository userRepository; private final PasswordEncoder passwordEncoder; - private final UserBusinessLinkageService userBusinessLinkageService; - private final StoreAssignmentService storeAssignmentService; - public DataInitializer(UserRepository userRepository, PasswordEncoder passwordEncoder, UserBusinessLinkageService userBusinessLinkageService, StoreAssignmentService storeAssignmentService) { + public DataInitializer(UserRepository userRepository, PasswordEncoder passwordEncoder) { this.userRepository = userRepository; this.passwordEncoder = passwordEncoder; - this.userBusinessLinkageService = userBusinessLinkageService; - this.storeAssignmentService = storeAssignmentService; } @Override @@ -34,16 +28,25 @@ public class DataInitializer implements CommandLineRunner { admin.setUsername("admin"); admin.setPassword(passwordEncoder.encode("admin123")); admin.setEmail("admin@petshop.com"); + admin.setFirstName("Admin"); + admin.setLastName("User"); admin.setFullName("Admin User"); admin.setPhone("000-000-1000"); admin.setRole(User.Role.ADMIN); admin.setActive(true); - admin = userRepository.save(admin); + userRepository.save(admin); System.out.println("Admin user created successfully"); } else { System.out.println("Admin user already exists"); - // Normalize missing fields if needed boolean updated = false; + if (admin.getFirstName() == null || admin.getFirstName().isEmpty()) { + admin.setFirstName("Admin"); + updated = true; + } + if (admin.getLastName() == null || admin.getLastName().isEmpty()) { + admin.setLastName("User"); + updated = true; + } if (admin.getFullName() == null || admin.getFullName().isEmpty()) { admin.setFullName("Admin User"); updated = true; @@ -65,12 +68,10 @@ public class DataInitializer implements CommandLineRunner { updated = true; } if (updated) { - admin = userRepository.save(admin); + userRepository.save(admin); System.out.println("Admin user normalized"); } } - // Ensure linked employee - storeAssignmentService.assignStoreIfMissing(userBusinessLinkageService.ensureLinkedEmployee(admin), 1L); User staff = userRepository.findByUsername("staff").orElse(null); if (staff == null) { @@ -79,16 +80,25 @@ public class DataInitializer implements CommandLineRunner { staff.setUsername("staff"); staff.setPassword(passwordEncoder.encode("staff123")); staff.setEmail("staff@petshop.com"); + staff.setFirstName("Staff"); + staff.setLastName("User"); staff.setFullName("Staff User"); staff.setPhone("000-000-1001"); staff.setRole(User.Role.STAFF); staff.setActive(true); - staff = userRepository.save(staff); + userRepository.save(staff); System.out.println("Staff user created successfully"); } else { System.out.println("Staff user already exists"); - // Normalize missing fields if needed boolean updated = false; + if (staff.getFirstName() == null || staff.getFirstName().isEmpty()) { + staff.setFirstName("Staff"); + updated = true; + } + if (staff.getLastName() == null || staff.getLastName().isEmpty()) { + staff.setLastName("User"); + updated = true; + } if (staff.getFullName() == null || staff.getFullName().isEmpty()) { staff.setFullName("Staff User"); updated = true; @@ -110,12 +120,10 @@ public class DataInitializer implements CommandLineRunner { updated = true; } if (updated) { - staff = userRepository.save(staff); + userRepository.save(staff); System.out.println("Staff user normalized"); } } - // Ensure linked employee - storeAssignmentService.assignStoreIfMissing(userBusinessLinkageService.ensureLinkedEmployee(staff), 1L); User customer = userRepository.findByUsername("customer").orElse(null); if (customer == null) { @@ -124,16 +132,25 @@ public class DataInitializer implements CommandLineRunner { customer.setUsername("customer"); customer.setPassword(passwordEncoder.encode("customer123")); customer.setEmail("customer@petshop.com"); + customer.setFirstName("Test"); + customer.setLastName("Customer"); customer.setFullName("Test Customer"); customer.setPhone("000-000-1002"); customer.setRole(User.Role.CUSTOMER); customer.setActive(true); - customer = userRepository.save(customer); + userRepository.save(customer); System.out.println("Customer user created successfully"); } else { System.out.println("Customer user already exists"); - // Normalize missing fields if needed boolean updated = false; + if (customer.getFirstName() == null || customer.getFirstName().isEmpty()) { + customer.setFirstName("Test"); + updated = true; + } + if (customer.getLastName() == null || customer.getLastName().isEmpty()) { + customer.setLastName("Customer"); + updated = true; + } if (customer.getFullName() == null || customer.getFullName().isEmpty()) { customer.setFullName("Test Customer"); updated = true; @@ -155,12 +172,10 @@ public class DataInitializer implements CommandLineRunner { updated = true; } if (updated) { - customer = userRepository.save(customer); + userRepository.save(customer); System.out.println("Customer user normalized"); } } - // Ensure linked customer - userBusinessLinkageService.ensureLinkedCustomer(customer); System.out.println("==== DataInitializer: Completed ===="); } diff --git a/backend/src/main/java/com/petshop/backend/config/LocalAppointmentCustomerSeedInitializer.java b/backend/src/main/java/com/petshop/backend/config/LocalAppointmentCustomerSeedInitializer.java deleted file mode 100644 index 36b78fb4..00000000 --- a/backend/src/main/java/com/petshop/backend/config/LocalAppointmentCustomerSeedInitializer.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.petshop.backend.config; - -import com.petshop.backend.repository.CustomerPetRepository; -import org.springframework.boot.CommandLineRunner; -import org.springframework.context.annotation.Profile; -import org.springframework.core.io.ClassPathResource; -import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; -import org.springframework.stereotype.Component; - -import javax.sql.DataSource; - -@Component -@Profile("local") -public class LocalAppointmentCustomerSeedInitializer implements CommandLineRunner { - - private final DataSource dataSource; - private final CustomerPetRepository customerPetRepository; - - public LocalAppointmentCustomerSeedInitializer(DataSource dataSource, CustomerPetRepository customerPetRepository) { - this.dataSource = dataSource; - this.customerPetRepository = customerPetRepository; - } - - @Override - public void run(String... args) { - if (customerPetRepository.count() > 0) { - return; - } - - ResourceDatabasePopulator populator = new ResourceDatabasePopulator(false, false, "UTF-8", - new ClassPathResource("dev/seed_demo_customer_pets.sql")); - populator.execute(dataSource); - } -} diff --git a/backend/src/main/java/com/petshop/backend/controller/AdoptionController.java b/backend/src/main/java/com/petshop/backend/controller/AdoptionController.java index 41a2e815..bcb61db4 100644 --- a/backend/src/main/java/com/petshop/backend/controller/AdoptionController.java +++ b/backend/src/main/java/com/petshop/backend/controller/AdoptionController.java @@ -3,8 +3,7 @@ package com.petshop.backend.controller; import com.petshop.backend.dto.adoption.AdoptionRequest; import com.petshop.backend.dto.adoption.AdoptionResponse; import com.petshop.backend.dto.common.BulkDeleteRequest; -import com.petshop.backend.entity.Customer; -import com.petshop.backend.repository.CustomerRepository; +import com.petshop.backend.entity.User; import com.petshop.backend.repository.UserRepository; import com.petshop.backend.service.AdoptionService; import com.petshop.backend.util.AuthenticationHelper; @@ -24,12 +23,10 @@ public class AdoptionController { private final AdoptionService adoptionService; private final UserRepository userRepository; - private final CustomerRepository customerRepository; - public AdoptionController(AdoptionService adoptionService, UserRepository userRepository, CustomerRepository customerRepository) { + public AdoptionController(AdoptionService adoptionService, UserRepository userRepository) { this.adoptionService = adoptionService; this.userRepository = userRepository; - this.customerRepository = customerRepository; } @GetMapping @@ -45,8 +42,8 @@ public class AdoptionController { Long customerId = null; if (role != null && role.equals("CUSTOMER")) { - Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository); - customerId = customer.getCustomerId(); + User user = AuthenticationHelper.getAuthenticatedUser(userRepository); + customerId = user.getId(); } return ResponseEntity.ok(adoptionService.getAllAdoptions(q, pageable, customerId)); @@ -63,8 +60,8 @@ public class AdoptionController { Long customerId = null; if (role != null && role.equals("CUSTOMER")) { - Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository); - customerId = customer.getCustomerId(); + User user = AuthenticationHelper.getAuthenticatedUser(userRepository); + customerId = user.getId(); } return ResponseEntity.ok(adoptionService.getAdoptionById(id, customerId)); diff --git a/backend/src/main/java/com/petshop/backend/controller/AppointmentController.java b/backend/src/main/java/com/petshop/backend/controller/AppointmentController.java index 35246e05..cf04f041 100644 --- a/backend/src/main/java/com/petshop/backend/controller/AppointmentController.java +++ b/backend/src/main/java/com/petshop/backend/controller/AppointmentController.java @@ -3,8 +3,7 @@ package com.petshop.backend.controller; import com.petshop.backend.dto.appointment.AppointmentRequest; import com.petshop.backend.dto.appointment.AppointmentResponse; import com.petshop.backend.dto.common.BulkDeleteRequest; -import com.petshop.backend.entity.Customer; -import com.petshop.backend.repository.CustomerRepository; +import com.petshop.backend.entity.User; import com.petshop.backend.repository.UserRepository; import com.petshop.backend.service.AppointmentService; import com.petshop.backend.util.AuthenticationHelper; @@ -27,12 +26,10 @@ public class AppointmentController { private final AppointmentService appointmentService; private final UserRepository userRepository; - private final CustomerRepository customerRepository; - public AppointmentController(AppointmentService appointmentService, UserRepository userRepository, CustomerRepository customerRepository) { + public AppointmentController(AppointmentService appointmentService, UserRepository userRepository) { this.appointmentService = appointmentService; this.userRepository = userRepository; - this.customerRepository = customerRepository; } @GetMapping @@ -48,8 +45,8 @@ public class AppointmentController { Long customerId = null; if (role != null && role.equals("CUSTOMER")) { - Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository); - customerId = customer.getCustomerId(); + User user = AuthenticationHelper.getAuthenticatedUser(userRepository); + customerId = user.getId(); } return ResponseEntity.ok(appointmentService.getAllAppointments(q, pageable, customerId)); @@ -66,8 +63,8 @@ public class AppointmentController { Long customerId = null; if (role != null && role.equals("CUSTOMER")) { - Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository); - customerId = customer.getCustomerId(); + User user = AuthenticationHelper.getAuthenticatedUser(userRepository); + customerId = user.getId(); } return ResponseEntity.ok(appointmentService.getAppointmentById(id, customerId)); @@ -83,8 +80,8 @@ public class AppointmentController { .orElse(null); if (role != null && role.equals("CUSTOMER")) { - Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository); - if (!request.getCustomerId().equals(customer.getCustomerId())) { + User user = AuthenticationHelper.getAuthenticatedUser(userRepository); + if (!request.getCustomerId().equals(user.getId())) { throw new org.springframework.security.access.AccessDeniedException("You can only create appointments for yourself"); } } diff --git a/backend/src/main/java/com/petshop/backend/controller/AuthController.java b/backend/src/main/java/com/petshop/backend/controller/AuthController.java index 106ea66f..641c7a6b 100644 --- a/backend/src/main/java/com/petshop/backend/controller/AuthController.java +++ b/backend/src/main/java/com/petshop/backend/controller/AuthController.java @@ -7,15 +7,11 @@ import com.petshop.backend.dto.auth.ProfileUpdateRequest; import com.petshop.backend.dto.auth.RegisterRequest; import com.petshop.backend.dto.auth.RegisterResponse; import com.petshop.backend.dto.auth.UserInfoResponse; -import com.petshop.backend.entity.EmployeeStore; +import com.petshop.backend.entity.StoreLocation; import com.petshop.backend.entity.User; -import com.petshop.backend.repository.CustomerRepository; -import com.petshop.backend.repository.EmployeeRepository; -import com.petshop.backend.repository.EmployeeStoreRepository; import com.petshop.backend.repository.UserRepository; import com.petshop.backend.security.JwtUtil; import com.petshop.backend.service.AvatarStorageService; -import com.petshop.backend.service.UserBusinessLinkageService; import com.petshop.backend.util.AuthenticationHelper; import jakarta.validation.Valid; import org.springframework.core.io.Resource; @@ -44,22 +40,14 @@ public class AuthController { private final UserRepository userRepository; private final JwtUtil jwtUtil; private final PasswordEncoder passwordEncoder; - private final UserBusinessLinkageService userBusinessLinkageService; - private final EmployeeRepository employeeRepository; - private final EmployeeStoreRepository employeeStoreRepository; private final AvatarStorageService avatarStorageService; - private final CustomerRepository customerRepository; - public AuthController(AuthenticationManager authenticationManager, UserRepository userRepository, JwtUtil jwtUtil, PasswordEncoder passwordEncoder, UserBusinessLinkageService userBusinessLinkageService, EmployeeRepository employeeRepository, EmployeeStoreRepository employeeStoreRepository, AvatarStorageService avatarStorageService, CustomerRepository customerRepository) { + public AuthController(AuthenticationManager authenticationManager, UserRepository userRepository, JwtUtil jwtUtil, PasswordEncoder passwordEncoder, AvatarStorageService avatarStorageService) { this.authenticationManager = authenticationManager; this.userRepository = userRepository; this.jwtUtil = jwtUtil; this.passwordEncoder = passwordEncoder; - this.userBusinessLinkageService = userBusinessLinkageService; - this.employeeRepository = employeeRepository; - this.employeeStoreRepository = employeeStoreRepository; this.avatarStorageService = avatarStorageService; - this.customerRepository = customerRepository; } @PostMapping("/register") @@ -94,9 +82,6 @@ public class AuthController { User savedUser = userRepository.save(user); - // Create or link customer record - userBusinessLinkageService.ensureLinkedCustomer(savedUser); - String token = jwtUtil.generateToken(savedUser); return ResponseEntity.status(HttpStatus.CREATED).body(new RegisterResponse( @@ -148,22 +133,7 @@ public class AuthController { @GetMapping("/me") public ResponseEntity getCurrentUser() { User user = getAuthenticatedUser(); - - EmployeeStore employeeStore = resolveEmployeeStore(user); - Long customerId = resolveCustomerId(user); - - return ResponseEntity.ok(new UserInfoResponse( - user.getId(), - user.getUsername(), - user.getEmail(), - user.getFullName(), - user.getPhone(), - avatarStorageService.toOwnerAvatarUrl(user), - user.getRole().name(), - customerId, - employeeStore != null ? employeeStore.getStore().getStoreId() : null, - employeeStore != null ? employeeStore.getStore().getStoreName() : null - )); + return ResponseEntity.ok(toUserInfoResponse(user)); } @PutMapping("/me") @@ -218,39 +188,24 @@ public class AuthController { } User updatedUser = userRepository.save(user); - userBusinessLinkageService.syncLinkedRecords(updatedUser); + return ResponseEntity.ok(toUserInfoResponse(updatedUser)); + } - EmployeeStore employeeStore = resolveEmployeeStore(updatedUser); - Long customerId = resolveCustomerId(updatedUser); - - return ResponseEntity.ok(new UserInfoResponse( - updatedUser.getId(), - updatedUser.getUsername(), - updatedUser.getEmail(), - updatedUser.getFullName(), - updatedUser.getPhone(), - avatarStorageService.toOwnerAvatarUrl(updatedUser), - updatedUser.getRole().name(), + private UserInfoResponse toUserInfoResponse(User user) { + StoreLocation primaryStore = user.getPrimaryStore(); + Long customerId = user.getRole() == User.Role.CUSTOMER ? user.getId() : null; + return new UserInfoResponse( + user.getId(), + user.getUsername(), + user.getEmail(), + user.getFullName(), + user.getPhone(), + avatarStorageService.toOwnerAvatarUrl(user), + user.getRole().name(), customerId, - employeeStore != null ? employeeStore.getStore().getStoreId() : null, - employeeStore != null ? employeeStore.getStore().getStoreName() : null - )); - } - - private EmployeeStore resolveEmployeeStore(User user) { - if (user.getRole() == User.Role.CUSTOMER) { - return null; - } - - return employeeRepository.findByUserId(user.getId()) - .flatMap(employee -> employeeStoreRepository.findByEmployeeEmployeeId(employee.getEmployeeId())) - .orElse(null); - } - - private Long resolveCustomerId(User user) { - return customerRepository.findByUserId(user.getId()) - .map(c -> c.getCustomerId()) - .orElse(null); + primaryStore != null ? primaryStore.getStoreId() : null, + primaryStore != null ? primaryStore.getStoreName() : null + ); } private String trimToNull(String value) { diff --git a/backend/src/main/java/com/petshop/backend/controller/ChatController.java b/backend/src/main/java/com/petshop/backend/controller/ChatController.java index 7320cdb9..e56e353f 100644 --- a/backend/src/main/java/com/petshop/backend/controller/ChatController.java +++ b/backend/src/main/java/com/petshop/backend/controller/ChatController.java @@ -6,7 +6,6 @@ import com.petshop.backend.dto.chat.MessageRequest; import com.petshop.backend.dto.chat.MessageResponse; import com.petshop.backend.dto.chat.UpdateConversationRequest; import com.petshop.backend.entity.User; -import com.petshop.backend.repository.CustomerRepository; import com.petshop.backend.repository.UserRepository; import com.petshop.backend.service.ChatRealtimeService; import com.petshop.backend.service.ChatService; @@ -27,13 +26,11 @@ public class ChatController { private final ChatService chatService; private final ChatRealtimeService chatRealtimeService; private final UserRepository userRepository; - private final CustomerRepository customerRepository; - public ChatController(ChatService chatService, ChatRealtimeService chatRealtimeService, UserRepository userRepository, CustomerRepository customerRepository) { + public ChatController(ChatService chatService, ChatRealtimeService chatRealtimeService, UserRepository userRepository) { this.chatService = chatService; this.chatRealtimeService = chatRealtimeService; this.userRepository = userRepository; - this.customerRepository = customerRepository; } private User getCurrentUser() { diff --git a/backend/src/main/java/com/petshop/backend/controller/CustomerController.java b/backend/src/main/java/com/petshop/backend/controller/CustomerController.java index f3ab880e..4f17dd4f 100644 --- a/backend/src/main/java/com/petshop/backend/controller/CustomerController.java +++ b/backend/src/main/java/com/petshop/backend/controller/CustomerController.java @@ -1,9 +1,9 @@ package com.petshop.backend.controller; import com.petshop.backend.dto.common.BulkDeleteRequest; -import com.petshop.backend.dto.customer.CustomerRequest; -import com.petshop.backend.dto.customer.CustomerResponse; -import com.petshop.backend.service.CustomerService; +import com.petshop.backend.dto.user.UserRequest; +import com.petshop.backend.dto.user.UserResponse; +import com.petshop.backend.service.UserService; import jakarta.validation.Valid; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -17,45 +17,45 @@ import org.springframework.web.bind.annotation.*; @PreAuthorize("hasAnyRole('STAFF', 'ADMIN')") public class CustomerController { - private final CustomerService customerService; + private final UserService userService; - public CustomerController(CustomerService customerService) { - this.customerService = customerService; + public CustomerController(UserService userService) { + this.userService = userService; } @GetMapping - public ResponseEntity> getAllCustomers( + public ResponseEntity> getAllCustomers( @RequestParam(required = false) String q, Pageable pageable) { - return ResponseEntity.ok(customerService.getAllCustomers(q, pageable)); + return ResponseEntity.ok(userService.getAllUsers(q, "CUSTOMER", pageable)); } @GetMapping("/{id}") - public ResponseEntity getCustomerById(@PathVariable Long id) { - return ResponseEntity.ok(customerService.getCustomerById(id)); + public ResponseEntity getCustomerById(@PathVariable Long id) { + return ResponseEntity.ok(userService.getUserById(id)); } @PostMapping - public ResponseEntity createCustomer(@Valid @RequestBody CustomerRequest request) { - return ResponseEntity.status(HttpStatus.CREATED).body(customerService.createCustomer(request)); + public ResponseEntity createCustomer(@Valid @RequestBody UserRequest request) { + return ResponseEntity.status(HttpStatus.CREATED).body(userService.createUser(request)); } @PutMapping("/{id}") - public ResponseEntity updateCustomer( + public ResponseEntity updateCustomer( @PathVariable Long id, - @Valid @RequestBody CustomerRequest request) { - return ResponseEntity.ok(customerService.updateCustomer(id, request)); + @Valid @RequestBody UserRequest request) { + return ResponseEntity.ok(userService.updateUser(id, request)); } @DeleteMapping("/{id}") public ResponseEntity deleteCustomer(@PathVariable Long id) { - customerService.deleteCustomer(id); + userService.deleteUser(id); return ResponseEntity.noContent().build(); } @PostMapping("/bulk-delete") public ResponseEntity bulkDeleteCustomers(@Valid @RequestBody BulkDeleteRequest request) { - customerService.bulkDeleteCustomers(request); + userService.bulkDeleteUsers(request); return ResponseEntity.noContent().build(); } } diff --git a/backend/src/main/java/com/petshop/backend/controller/CustomerPetController.java b/backend/src/main/java/com/petshop/backend/controller/CustomerPetController.java deleted file mode 100644 index 4fd6648b..00000000 --- a/backend/src/main/java/com/petshop/backend/controller/CustomerPetController.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.petshop.backend.controller; - -import com.petshop.backend.dto.customerpet.CustomerPetRequest; -import com.petshop.backend.dto.customerpet.CustomerPetResponse; -import com.petshop.backend.service.CatalogImageStorageService; -import com.petshop.backend.service.CustomerPetService; -import com.petshop.backend.entity.CustomerPet; -import com.petshop.backend.repository.CustomerPetRepository; -import com.petshop.backend.repository.CustomerRepository; -import com.petshop.backend.repository.UserRepository; -import com.petshop.backend.entity.Customer; -import com.petshop.backend.util.AuthenticationHelper; -import jakarta.validation.Valid; -import org.springframework.core.io.Resource; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; - -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@RestController -@RequestMapping("/api/v1/my-pets") -@PreAuthorize("hasRole('CUSTOMER')") -public class CustomerPetController { - - private final CustomerPetService customerPetService; - private final CustomerPetRepository customerPetRepository; - private final CustomerRepository customerRepository; - private final UserRepository userRepository; - private final CatalogImageStorageService catalogImageStorageService; - - public CustomerPetController(CustomerPetService customerPetService, - CustomerPetRepository customerPetRepository, - CustomerRepository customerRepository, - UserRepository userRepository, - CatalogImageStorageService catalogImageStorageService) { - this.customerPetService = customerPetService; - this.customerPetRepository = customerPetRepository; - this.customerRepository = customerRepository; - this.userRepository = userRepository; - this.catalogImageStorageService = catalogImageStorageService; - } - - @GetMapping - public ResponseEntity> getMyPets() { - - return ResponseEntity.ok(customerPetService.getMyPets()); - } - - @PostMapping - public ResponseEntity createPet(@Valid @RequestBody CustomerPetRequest request) { - - return ResponseEntity.status(HttpStatus.CREATED).body(customerPetService.createPet(request)); - } - - @PutMapping("/{id}") - public ResponseEntity updatePet(@PathVariable Long id, @Valid @RequestBody CustomerPetRequest request) { - - return ResponseEntity.ok(customerPetService.updatePet(id, request)); - } - - @DeleteMapping("/{id}") - public ResponseEntity deletePet(@PathVariable Long id) { - customerPetService.deletePet(id); - - return ResponseEntity.noContent().build(); - } - - @PostMapping("/{id}/image") - public ResponseEntity uploadImage(@PathVariable Long id, @RequestParam("image") MultipartFile image) { - try { - - return ResponseEntity.ok(customerPetService.uploadImage(id, image)); - } - - catch (IllegalArgumentException ex) { - Map error = new HashMap<>(); - error.put("message", ex.getMessage()); - - return ResponseEntity.badRequest().body(error); - } - - catch (IOException ex) { - Map error = new HashMap<>(); - error.put("message", "Failed to upload image: " + ex.getMessage()); - - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error); - } - } - - @GetMapping("/{id}/image") - public ResponseEntity getImage(@PathVariable Long id) { - Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository); - CustomerPet pet = customerPetRepository.findByCustomerPetIdAndCustomerCustomerId(id, customer.getCustomerId()).orElse(null); - - if (pet == null || pet.getImageUrl() == null || pet.getImageUrl().isBlank()) { - - return ResponseEntity.notFound().build(); - } - - Resource resource = catalogImageStorageService.loadPetImage(pet.getImageUrl()); - MediaType mediaType = catalogImageStorageService.resolveMediaType(resource); - - return ResponseEntity.ok().contentType(mediaType).body(resource); - } - - @DeleteMapping("/{id}/image") - public ResponseEntity deleteImage(@PathVariable Long id) { - - return ResponseEntity.ok(customerPetService.deleteImage(id)); - } -} diff --git a/backend/src/main/java/com/petshop/backend/controller/DropdownController.java b/backend/src/main/java/com/petshop/backend/controller/DropdownController.java index d0a69036..4d995cd4 100644 --- a/backend/src/main/java/com/petshop/backend/controller/DropdownController.java +++ b/backend/src/main/java/com/petshop/backend/controller/DropdownController.java @@ -1,8 +1,6 @@ package com.petshop.backend.controller; import com.petshop.backend.dto.common.DropdownOption; -import com.petshop.backend.entity.CustomerPet; -import com.petshop.backend.entity.EmployeeStore; import com.petshop.backend.entity.User; import com.petshop.backend.repository.*; import org.springframework.http.ResponseEntity; @@ -20,31 +18,24 @@ import java.util.stream.Collectors; public class DropdownController { private final PetRepository petRepository; - private final CustomerRepository customerRepository; - private final CustomerPetRepository customerPetRepository; private final ServiceRepository serviceRepository; private final ProductRepository productRepository; private final CategoryRepository categoryRepository; private final StoreRepository storeRepository; private final SupplierRepository supplierRepository; - private final EmployeeStoreRepository employeeStoreRepository; private final UserRepository userRepository; - public DropdownController(PetRepository petRepository, CustomerRepository customerRepository, - CustomerPetRepository customerPetRepository, + public DropdownController(PetRepository petRepository, ServiceRepository serviceRepository, ProductRepository productRepository, CategoryRepository categoryRepository, StoreRepository storeRepository, - SupplierRepository supplierRepository, EmployeeStoreRepository employeeStoreRepository, + SupplierRepository supplierRepository, UserRepository userRepository) { this.petRepository = petRepository; - this.customerRepository = customerRepository; - this.customerPetRepository = customerPetRepository; this.serviceRepository = serviceRepository; this.productRepository = productRepository; this.categoryRepository = categoryRepository; this.storeRepository = storeRepository; this.supplierRepository = supplierRepository; - this.employeeStoreRepository = employeeStoreRepository; this.userRepository = userRepository; } @@ -71,8 +62,8 @@ public class DropdownController { @PreAuthorize("hasAnyRole('STAFF', 'ADMIN')") public ResponseEntity> getCustomers() { return ResponseEntity.ok( - customerRepository.findAll().stream() - .map(c -> new DropdownOption(c.getCustomerId(), c.getFirstName() + " " + c.getLastName())) + userRepository.findByRoleAndActiveTrue(User.Role.CUSTOMER).stream() + .map(u -> new DropdownOption(u.getId(), u.getFirstName() + " " + u.getLastName())) .collect(Collectors.toList()) ); } @@ -81,18 +72,8 @@ public class DropdownController { @PreAuthorize("hasAnyRole('STAFF', 'ADMIN')") public ResponseEntity> getAppointmentCustomers() { return ResponseEntity.ok( - customerRepository.findAllWithPets().stream() - .map(c -> new DropdownOption(c.getCustomerId(), c.getFirstName() + " " + c.getLastName())) - .collect(Collectors.toList()) - ); - } - - @GetMapping("/customers/{customerId}/pets") - @PreAuthorize("hasAnyRole('STAFF', 'ADMIN')") - public ResponseEntity> getCustomerPets(@PathVariable Long customerId) { - return ResponseEntity.ok( - customerPetRepository.findByCustomerCustomerIdOrderByPetNameAsc(customerId).stream() - .map(this::toCustomerPetOption) + userRepository.findByRoleAndActiveTrue(User.Role.CUSTOMER).stream() + .map(u -> new DropdownOption(u.getId(), u.getFirstName() + " " + u.getLastName())) .collect(Collectors.toList()) ); } @@ -159,17 +140,15 @@ public class DropdownController { @GetMapping({"/stores/{storeId}/employees", "/employees"}) @PreAuthorize("hasAnyRole('CUSTOMER', 'STAFF', 'ADMIN')") public ResponseEntity> getStoreEmployees(@PathVariable(required = false) Long storeId) { - List employees; + List employees; if (storeId == null || storeId == 0) { - employees = employeeStoreRepository.findActiveAllOrderByEmployeeEmployeeIdAsc(); + employees = userRepository.findByRoleAndActiveTrue(User.Role.STAFF); } else { - employees = employeeStoreRepository.findActiveByStoreStoreIdOrderByEmployeeEmployeeIdAsc(storeId); + employees = userRepository.findByPrimaryStoreStoreIdAndRoleAndActiveTrue(storeId, User.Role.STAFF); } return ResponseEntity.ok( employees.stream() - .filter(this::isAssignableEmployee) - .map(this::toEmployeeOption) - .distinct() + .map(u -> new DropdownOption(u.getId(), u.getFirstName() + " " + u.getLastName())) .collect(Collectors.toList()) ); } @@ -183,26 +162,4 @@ public class DropdownController { .collect(Collectors.toList()) ); } - - private DropdownOption toCustomerPetOption(CustomerPet pet) { - String species = pet.getSpecies() == null || pet.getSpecies().isBlank() ? "Pet" : pet.getSpecies(); - String breed = pet.getBreed() == null || pet.getBreed().isBlank() ? "" : " ยท " + pet.getBreed(); - return new DropdownOption(pet.getCustomerPetId(), pet.getPetName() + " (" + species + breed + ")"); - } - - private DropdownOption toEmployeeOption(EmployeeStore employeeStore) { - var employee = employeeStore.getEmployee(); - return new DropdownOption(employee.getEmployeeId(), employee.getFirstName() + " " + employee.getLastName()); - } - - private boolean isAssignableEmployee(EmployeeStore employeeStore) { - Long userId = employeeStore.getEmployee().getUserId(); - if (userId == null) { - return false; - } - return userRepository.findById(userId) - .filter(user -> user.getRole() == User.Role.STAFF) - .filter(user -> Boolean.TRUE.equals(user.getActive())) - .isPresent(); - } } diff --git a/backend/src/main/java/com/petshop/backend/controller/EmployeeController.java b/backend/src/main/java/com/petshop/backend/controller/EmployeeController.java index 1c567623..2276e6ad 100644 --- a/backend/src/main/java/com/petshop/backend/controller/EmployeeController.java +++ b/backend/src/main/java/com/petshop/backend/controller/EmployeeController.java @@ -1,8 +1,8 @@ package com.petshop.backend.controller; -import com.petshop.backend.dto.employee.EmployeeRequest; -import com.petshop.backend.dto.employee.EmployeeResponse; -import com.petshop.backend.service.EmployeeService; +import com.petshop.backend.dto.user.UserRequest; +import com.petshop.backend.dto.user.UserResponse; +import com.petshop.backend.service.UserService; import jakarta.validation.Valid; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -15,35 +15,40 @@ import org.springframework.web.bind.annotation.*; @RequestMapping("/api/v1/employees") @PreAuthorize("hasRole('ADMIN')") public class EmployeeController { - private final EmployeeService employeeService; - public EmployeeController(EmployeeService employeeService) { - this.employeeService = employeeService; + private final UserService userService; + + public EmployeeController(UserService userService) { + this.userService = userService; } @GetMapping - public ResponseEntity> getAllEmployees(@RequestParam(required = false) String q, Pageable pageable) { - return ResponseEntity.ok(employeeService.getAllEmployees(q, pageable)); + public ResponseEntity> getAllEmployees( + @RequestParam(required = false) String q, + Pageable pageable) { + return ResponseEntity.ok(userService.getAllUsers(q, "STAFF", pageable)); } @GetMapping("/{id}") - public ResponseEntity getEmployeeById(@PathVariable Long id) { - return ResponseEntity.ok(employeeService.getEmployeeById(id)); + public ResponseEntity getEmployeeById(@PathVariable Long id) { + return ResponseEntity.ok(userService.getUserById(id)); } @PostMapping - public ResponseEntity createEmployee(@Valid @RequestBody EmployeeRequest request) { - return ResponseEntity.status(HttpStatus.CREATED).body(employeeService.createEmployee(request)); + public ResponseEntity createEmployee(@Valid @RequestBody UserRequest request) { + return ResponseEntity.status(HttpStatus.CREATED).body(userService.createUser(request)); } @PutMapping("/{id}") - public ResponseEntity updateEmployee(@PathVariable Long id, @Valid @RequestBody EmployeeRequest request) { - return ResponseEntity.ok(employeeService.updateEmployee(id, request)); + public ResponseEntity updateEmployee( + @PathVariable Long id, + @Valid @RequestBody UserRequest request) { + return ResponseEntity.ok(userService.updateUser(id, request)); } @DeleteMapping("/{id}") public ResponseEntity deleteEmployee(@PathVariable Long id) { - employeeService.deleteEmployee(id); + userService.deleteUser(id); return ResponseEntity.noContent().build(); } } diff --git a/backend/src/main/java/com/petshop/backend/controller/RefundController.java b/backend/src/main/java/com/petshop/backend/controller/RefundController.java index 6968b9c3..bd6f158b 100644 --- a/backend/src/main/java/com/petshop/backend/controller/RefundController.java +++ b/backend/src/main/java/com/petshop/backend/controller/RefundController.java @@ -3,8 +3,7 @@ package com.petshop.backend.controller; import com.petshop.backend.dto.refund.RefundRequest; import com.petshop.backend.dto.refund.RefundResponse; import com.petshop.backend.dto.refund.RefundUpdateRequest; -import com.petshop.backend.entity.Customer; -import com.petshop.backend.repository.CustomerRepository; +import com.petshop.backend.entity.User; import com.petshop.backend.repository.UserRepository; import com.petshop.backend.service.RefundService; import com.petshop.backend.util.AuthenticationHelper; @@ -26,12 +25,10 @@ public class RefundController { private final RefundService refundService; private final UserRepository userRepository; - private final CustomerRepository customerRepository; - public RefundController(RefundService refundService, UserRepository userRepository, CustomerRepository customerRepository) { + public RefundController(RefundService refundService, UserRepository userRepository) { this.refundService = refundService; this.userRepository = userRepository; - this.customerRepository = customerRepository; } @PostMapping @@ -46,8 +43,8 @@ public class RefundController { Long customerId = null; if (role != null && role.equals("CUSTOMER")) { - Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository); - customerId = customer.getCustomerId(); + User user = AuthenticationHelper.getAuthenticatedUser(userRepository); + customerId = user.getId(); } RefundResponse refund = refundService.createRefund(request, customerId); @@ -70,8 +67,8 @@ public class RefundController { Long customerId = null; if (role != null && role.equals("CUSTOMER")) { - Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository); - customerId = customer.getCustomerId(); + User user = AuthenticationHelper.getAuthenticatedUser(userRepository); + customerId = user.getId(); } List refunds = refundService.getAllRefunds(customerId); @@ -90,8 +87,8 @@ public class RefundController { Long customerId = null; if (role != null && role.equals("CUSTOMER")) { - Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository); - customerId = customer.getCustomerId(); + User user = AuthenticationHelper.getAuthenticatedUser(userRepository); + customerId = user.getId(); } RefundResponse refund = refundService.getRefundById(id, customerId); diff --git a/backend/src/main/java/com/petshop/backend/dto/appointment/AppointmentRequest.java b/backend/src/main/java/com/petshop/backend/dto/appointment/AppointmentRequest.java index 3d127c19..c60c3fcd 100644 --- a/backend/src/main/java/com/petshop/backend/dto/appointment/AppointmentRequest.java +++ b/backend/src/main/java/com/petshop/backend/dto/appointment/AppointmentRequest.java @@ -27,8 +27,6 @@ public class AppointmentRequest { private List petIds; - private List customerPetIds; - private Long employeeId; public Long getCustomerId() { @@ -87,14 +85,6 @@ public class AppointmentRequest { this.petIds = petIds; } - public List getCustomerPetIds() { - return customerPetIds; - } - - public void setCustomerPetIds(List customerPetIds) { - this.customerPetIds = customerPetIds; - } - public Long getEmployeeId() { return employeeId; } @@ -115,13 +105,12 @@ public class AppointmentRequest { Objects.equals(appointmentTime, that.appointmentTime) && Objects.equals(appointmentStatus, that.appointmentStatus) && Objects.equals(petIds, that.petIds) && - Objects.equals(customerPetIds, that.customerPetIds) && Objects.equals(employeeId, that.employeeId); } @Override public int hashCode() { - return Objects.hash(customerId, storeId, serviceId, appointmentDate, appointmentTime, appointmentStatus, petIds, customerPetIds, employeeId); + return Objects.hash(customerId, storeId, serviceId, appointmentDate, appointmentTime, appointmentStatus, petIds, employeeId); } @Override @@ -134,7 +123,6 @@ public class AppointmentRequest { ", appointmentTime=" + appointmentTime + ", appointmentStatus='" + appointmentStatus + '\'' + ", petIds=" + petIds + - ", customerPetIds=" + customerPetIds + ", employeeId=" + employeeId + '}'; } diff --git a/backend/src/main/java/com/petshop/backend/dto/appointment/AppointmentResponse.java b/backend/src/main/java/com/petshop/backend/dto/appointment/AppointmentResponse.java index efc1c300..f8e14ac2 100644 --- a/backend/src/main/java/com/petshop/backend/dto/appointment/AppointmentResponse.java +++ b/backend/src/main/java/com/petshop/backend/dto/appointment/AppointmentResponse.java @@ -21,8 +21,6 @@ public class AppointmentResponse { private String employeeName; private List petNames; private List petIds; - private List customerPetNames; - private List customerPetIds; private LocalDateTime createdAt; private LocalDateTime updatedAt; @@ -158,24 +156,6 @@ public class AppointmentResponse { this.petIds = petIds; } - public List getCustomerPetNames() { - - return customerPetNames; - } - - public void setCustomerPetNames(List customerPetNames) { - this.customerPetNames = customerPetNames; - } - - public List getCustomerPetIds() { - - return customerPetIds; - } - - public void setCustomerPetIds(List customerPetIds) { - this.customerPetIds = customerPetIds; - } - public LocalDateTime getCreatedAt() { return createdAt; } diff --git a/backend/src/main/java/com/petshop/backend/dto/customer/CustomerRequest.java b/backend/src/main/java/com/petshop/backend/dto/customer/CustomerRequest.java deleted file mode 100644 index ded898e3..00000000 --- a/backend/src/main/java/com/petshop/backend/dto/customer/CustomerRequest.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.petshop.backend.dto.customer; - -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.NotBlank; -import java.util.Objects; - -public class CustomerRequest { - @NotBlank(message = "First name is required") - private String firstName; - - @NotBlank(message = "Last name is required") - private String lastName; - - @Email(message = "Invalid email format") - private String email; - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - CustomerRequest that = (CustomerRequest) o; - return Objects.equals(firstName, that.firstName) && - Objects.equals(lastName, that.lastName) && - Objects.equals(email, that.email); - } - - @Override - public int hashCode() { - return Objects.hash(firstName, lastName, email); - } - - @Override - public String toString() { - return "CustomerRequest{" + - "firstName='" + firstName + '\'' + - ", lastName='" + lastName + '\'' + - ", email='" + email + '\'' + - '}'; - } -} diff --git a/backend/src/main/java/com/petshop/backend/dto/customer/CustomerResponse.java b/backend/src/main/java/com/petshop/backend/dto/customer/CustomerResponse.java deleted file mode 100644 index bd05bf76..00000000 --- a/backend/src/main/java/com/petshop/backend/dto/customer/CustomerResponse.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.petshop.backend.dto.customer; - -import java.time.LocalDateTime; -import java.util.Objects; - -public class CustomerResponse { - private Long customerId; - private String firstName; - private String lastName; - private String email; - private LocalDateTime createdAt; - private LocalDateTime updatedAt; - - public CustomerResponse() { - } - - public CustomerResponse(Long customerId, String firstName, String lastName, String email, LocalDateTime createdAt, LocalDateTime updatedAt) { - this.customerId = customerId; - this.firstName = firstName; - this.lastName = lastName; - this.email = email; - this.createdAt = createdAt; - this.updatedAt = updatedAt; - } - - public Long getCustomerId() { - return customerId; - } - - public void setCustomerId(Long customerId) { - this.customerId = customerId; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(LocalDateTime createdAt) { - this.createdAt = createdAt; - } - - public LocalDateTime getUpdatedAt() { - return updatedAt; - } - - public void setUpdatedAt(LocalDateTime updatedAt) { - this.updatedAt = updatedAt; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - CustomerResponse that = (CustomerResponse) o; - return Objects.equals(customerId, that.customerId) && Objects.equals(firstName, that.firstName) && Objects.equals(lastName, that.lastName) && Objects.equals(email, that.email) && Objects.equals(createdAt, that.createdAt) && Objects.equals(updatedAt, that.updatedAt); - } - - @Override - public int hashCode() { - return Objects.hash(customerId, firstName, lastName, email, createdAt, updatedAt); - } - - @Override - public String toString() { - return "CustomerResponse{" + - "customerId=" + customerId + - ", firstName='" + firstName + '\'' + - ", lastName='" + lastName + '\'' + - ", email='" + email + '\'' + - ", createdAt=" + createdAt + - ", updatedAt=" + updatedAt + - '}'; - } -} diff --git a/backend/src/main/java/com/petshop/backend/dto/customerpet/CustomerPetRequest.java b/backend/src/main/java/com/petshop/backend/dto/customerpet/CustomerPetRequest.java deleted file mode 100644 index b4b37355..00000000 --- a/backend/src/main/java/com/petshop/backend/dto/customerpet/CustomerPetRequest.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.petshop.backend.dto.customerpet; - -import jakarta.validation.constraints.NotBlank; - -import java.util.Objects; - -public class CustomerPetRequest { - - @NotBlank(message = "Pet name is required") - private String petName; - - @NotBlank(message = "Species is required") - private String species; - - 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; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - - return true; - } - - if (o == null || getClass() != o.getClass()) { - - return false; - } - - CustomerPetRequest that = (CustomerPetRequest) o; - - return Objects.equals(petName, that.petName) && Objects.equals(species, that.species) && Objects.equals(breed, that.breed); - } - - @Override - public int hashCode() { - - return Objects.hash(petName, species, breed); - } -} diff --git a/backend/src/main/java/com/petshop/backend/dto/customerpet/CustomerPetResponse.java b/backend/src/main/java/com/petshop/backend/dto/customerpet/CustomerPetResponse.java deleted file mode 100644 index 8e9ab37d..00000000 --- a/backend/src/main/java/com/petshop/backend/dto/customerpet/CustomerPetResponse.java +++ /dev/null @@ -1,123 +0,0 @@ -package com.petshop.backend.dto.customerpet; - -import java.time.LocalDateTime; -import java.util.Objects; - -public class CustomerPetResponse { - - private Long customerPetId; - private Long customerId; - private String petName; - private String species; - private String breed; - private String imageUrl; - private LocalDateTime createdAt; - private LocalDateTime updatedAt; - - public CustomerPetResponse() { - } - - public CustomerPetResponse(Long customerPetId, Long customerId, String petName, String species, String breed, String imageUrl, LocalDateTime createdAt, LocalDateTime updatedAt) { - this.customerPetId = customerPetId; - this.customerId = customerId; - this.petName = petName; - this.species = species; - this.breed = breed; - this.imageUrl = imageUrl; - this.createdAt = createdAt; - this.updatedAt = updatedAt; - } - - public Long getCustomerPetId() { - - return customerPetId; - } - - public void setCustomerPetId(Long customerPetId) { - this.customerPetId = customerPetId; - } - - public Long getCustomerId() { - - return customerId; - } - - public void setCustomerId(Long customerId) { - this.customerId = customerId; - } - - 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; - } - - public LocalDateTime getCreatedAt() { - - return createdAt; - } - - public void setCreatedAt(LocalDateTime createdAt) { - this.createdAt = createdAt; - } - - public LocalDateTime getUpdatedAt() { - - return updatedAt; - } - - public void setUpdatedAt(LocalDateTime updatedAt) { - this.updatedAt = updatedAt; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (o == null || getClass() != o.getClass()) { - return false; - } - - CustomerPetResponse that = (CustomerPetResponse) o; - - return Objects.equals(customerPetId, that.customerPetId); - } - - @Override - public int hashCode() { - - return Objects.hash(customerPetId); - } -} diff --git a/backend/src/main/java/com/petshop/backend/dto/employee/EmployeeRequest.java b/backend/src/main/java/com/petshop/backend/dto/employee/EmployeeRequest.java deleted file mode 100644 index f5fb9020..00000000 --- a/backend/src/main/java/com/petshop/backend/dto/employee/EmployeeRequest.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.petshop.backend.dto.employee; - -import com.petshop.backend.entity.User; -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; - -public class EmployeeRequest { - @NotBlank(message = "Username is required") - @Size(min = 3, max = 50, message = "Username must be between 3 and 50 characters") - private String username; - - @Size(min = 6, message = "Password must be at least 6 characters") - private String password; - - @NotBlank(message = "First name is required") - private String firstName; - - @NotBlank(message = "Last name is required") - private String lastName; - - @Email(message = "Invalid email format") - private String email; - - @NotBlank(message = "Phone is required") - @Size(max = 20, message = "Phone must not exceed 20 characters") - private String phone; - - @NotNull(message = "Role is required") - private User.Role role; - - private Boolean active = true; - - public String getUsername() { return username; } - public void setUsername(String username) { this.username = username; } - public String getPassword() { return password; } - public void setPassword(String password) { this.password = password; } - public String getFirstName() { return firstName; } - public void setFirstName(String firstName) { this.firstName = firstName; } - public String getLastName() { return lastName; } - public void setLastName(String lastName) { this.lastName = lastName; } - public String getEmail() { return email; } - public void setEmail(String email) { this.email = email; } - public String getPhone() { return phone; } - public void setPhone(String phone) { this.phone = phone; } - public User.Role getRole() { return role; } - public void setRole(User.Role role) { this.role = role; } - public Boolean getActive() { return active; } - public void setActive(Boolean active) { this.active = active; } -} diff --git a/backend/src/main/java/com/petshop/backend/dto/employee/EmployeeResponse.java b/backend/src/main/java/com/petshop/backend/dto/employee/EmployeeResponse.java deleted file mode 100644 index a159fc35..00000000 --- a/backend/src/main/java/com/petshop/backend/dto/employee/EmployeeResponse.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.petshop.backend.dto.employee; - -import java.time.LocalDateTime; - -public class EmployeeResponse { - private Long employeeId; - private Long userId; - private String username; - private String firstName; - private String lastName; - private String fullName; - private String email; - private String phone; - private String role; - private Boolean active; - private LocalDateTime createdAt; - private LocalDateTime updatedAt; - - public Long getEmployeeId() { return employeeId; } - public void setEmployeeId(Long employeeId) { this.employeeId = employeeId; } - public Long getUserId() { return userId; } - public void setUserId(Long userId) { this.userId = userId; } - public String getUsername() { return username; } - public void setUsername(String username) { this.username = username; } - public String getFirstName() { return firstName; } - public void setFirstName(String firstName) { this.firstName = firstName; } - public String getLastName() { return lastName; } - public void setLastName(String lastName) { this.lastName = lastName; } - public String getFullName() { return fullName; } - public void setFullName(String fullName) { this.fullName = fullName; } - public String getEmail() { return email; } - public void setEmail(String email) { this.email = email; } - public String getPhone() { return phone; } - public void setPhone(String phone) { this.phone = phone; } - public String getRole() { return role; } - public void setRole(String role) { this.role = role; } - public Boolean getActive() { return active; } - public void setActive(Boolean active) { this.active = active; } - public LocalDateTime getCreatedAt() { return createdAt; } - public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; } - public LocalDateTime getUpdatedAt() { return updatedAt; } - public void setUpdatedAt(LocalDateTime updatedAt) { this.updatedAt = updatedAt; } -} diff --git a/backend/src/main/java/com/petshop/backend/entity/ActivityLog.java b/backend/src/main/java/com/petshop/backend/entity/ActivityLog.java index 211f75de..7c778bc3 100644 --- a/backend/src/main/java/com/petshop/backend/entity/ActivityLog.java +++ b/backend/src/main/java/com/petshop/backend/entity/ActivityLog.java @@ -14,8 +14,8 @@ public class ActivityLog { private Long logId; @ManyToOne - @JoinColumn(name = "employeeId", nullable = false) - private Employee employee; + @JoinColumn(name = "userId", nullable = false) + private User user; @Column(nullable = false, columnDefinition = "TEXT") private String activity; @@ -26,9 +26,9 @@ public class ActivityLog { public ActivityLog() { } - public ActivityLog(Long logId, Employee employee, String activity, LocalDateTime logTimestamp) { + public ActivityLog(Long logId, User user, String activity, LocalDateTime logTimestamp) { this.logId = logId; - this.employee = employee; + this.user = user; this.activity = activity; this.logTimestamp = logTimestamp; } @@ -41,12 +41,12 @@ public class ActivityLog { this.logId = logId; } - public Employee getEmployee() { - return employee; + public User getUser() { + return user; } - public void setEmployee(Employee employee) { - this.employee = employee; + public void setUser(User user) { + this.user = user; } public String getActivity() { @@ -82,7 +82,7 @@ public class ActivityLog { public String toString() { return "ActivityLog{" + "logId=" + logId + - ", employee=" + employee + + ", user=" + user + ", activity='" + activity + '\'' + ", logTimestamp=" + logTimestamp + '}'; diff --git a/backend/src/main/java/com/petshop/backend/entity/Adoption.java b/backend/src/main/java/com/petshop/backend/entity/Adoption.java index 78360e2e..35d4edac 100644 --- a/backend/src/main/java/com/petshop/backend/entity/Adoption.java +++ b/backend/src/main/java/com/petshop/backend/entity/Adoption.java @@ -4,7 +4,6 @@ import jakarta.persistence.*; import org.hibernate.annotations.CreationTimestamp; import org.hibernate.annotations.UpdateTimestamp; -import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.Objects; @@ -23,11 +22,11 @@ public class Adoption { @ManyToOne @JoinColumn(name = "customerId", nullable = false) - private Customer customer; + private User customer; @ManyToOne @JoinColumn(name = "employeeId", nullable = false) - private Employee employee; + private User employee; @Column(nullable = false) private LocalDate adoptionDate; @@ -46,17 +45,6 @@ public class Adoption { public Adoption() { } - public Adoption(Long adoptionId, Pet pet, Customer customer, Employee employee, LocalDate adoptionDate, String adoptionStatus, LocalDateTime createdAt, LocalDateTime updatedAt) { - this.adoptionId = adoptionId; - this.pet = pet; - this.customer = customer; - this.employee = employee; - this.adoptionDate = adoptionDate; - this.adoptionStatus = adoptionStatus; - this.createdAt = createdAt; - this.updatedAt = updatedAt; - } - public Long getAdoptionId() { return adoptionId; } @@ -73,19 +61,19 @@ public class Adoption { this.pet = pet; } - public Customer getCustomer() { + public User getCustomer() { return customer; } - public void setCustomer(Customer customer) { + public void setCustomer(User customer) { this.customer = customer; } - public Employee getEmployee() { + public User getEmployee() { return employee; } - public void setEmployee(Employee employee) { + public void setEmployee(User employee) { this.employee = employee; } @@ -138,13 +126,8 @@ public class Adoption { public String toString() { return "Adoption{" + "adoptionId=" + adoptionId + - ", pet=" + pet + - ", customer=" + customer + - ", employee=" + employee + - ", adoptionDate=" + adoptionDate + ", adoptionStatus='" + adoptionStatus + '\'' + - ", createdAt=" + createdAt + - ", updatedAt=" + updatedAt + + ", adoptionDate=" + adoptionDate + '}'; } } diff --git a/backend/src/main/java/com/petshop/backend/entity/Appointment.java b/backend/src/main/java/com/petshop/backend/entity/Appointment.java index d4ebc199..f313d928 100644 --- a/backend/src/main/java/com/petshop/backend/entity/Appointment.java +++ b/backend/src/main/java/com/petshop/backend/entity/Appointment.java @@ -21,7 +21,7 @@ public class Appointment { @ManyToOne @JoinColumn(name = "customerId", nullable = false) - private Customer customer; + private User customer; @ManyToOne @JoinColumn(name = "storeId", nullable = false) @@ -33,7 +33,7 @@ public class Appointment { @ManyToOne @JoinColumn(name = "employeeId", nullable = false) - private Employee employee; + private User employee; @Column(nullable = false) private LocalDate appointmentDate; @@ -52,14 +52,6 @@ public class Appointment { ) private Set pets = new HashSet<>(); - @ManyToMany - @JoinTable( - name = "appointment_customer_pet", - joinColumns = @JoinColumn(name = "appointment_id"), - inverseJoinColumns = @JoinColumn(name = "customer_pet_id") - ) - private Set customerPets = new HashSet<>(); - @CreationTimestamp @Column(name = "created_at", updatable = false) private LocalDateTime createdAt; @@ -71,20 +63,6 @@ public class Appointment { public Appointment() { } - public Appointment(Long appointmentId, Customer customer, StoreLocation store, Service service, Employee employee, LocalDate appointmentDate, LocalTime appointmentTime, String appointmentStatus, Set pets, LocalDateTime createdAt, LocalDateTime updatedAt) { - this.appointmentId = appointmentId; - this.customer = customer; - this.store = store; - this.service = service; - this.employee = employee; - this.appointmentDate = appointmentDate; - this.appointmentTime = appointmentTime; - this.appointmentStatus = appointmentStatus; - this.pets = pets; - this.createdAt = createdAt; - this.updatedAt = updatedAt; - } - public Long getAppointmentId() { return appointmentId; } @@ -93,11 +71,11 @@ public class Appointment { this.appointmentId = appointmentId; } - public Customer getCustomer() { + public User getCustomer() { return customer; } - public void setCustomer(Customer customer) { + public void setCustomer(User customer) { this.customer = customer; } @@ -117,11 +95,11 @@ public class Appointment { this.service = service; } - public Employee getEmployee() { + public User getEmployee() { return employee; } - public void setEmployee(Employee employee) { + public void setEmployee(User employee) { this.employee = employee; } @@ -157,15 +135,6 @@ public class Appointment { this.pets = pets; } - public Set getCustomerPets() { - - return customerPets; - } - - public void setCustomerPets(Set customerPets) { - this.customerPets = customerPets; - } - public LocalDateTime getCreatedAt() { return createdAt; } diff --git a/backend/src/main/java/com/petshop/backend/entity/Customer.java b/backend/src/main/java/com/petshop/backend/entity/Customer.java deleted file mode 100644 index 09035619..00000000 --- a/backend/src/main/java/com/petshop/backend/entity/Customer.java +++ /dev/null @@ -1,132 +0,0 @@ -package com.petshop.backend.entity; - -import jakarta.persistence.*; -import org.hibernate.annotations.CreationTimestamp; -import org.hibernate.annotations.UpdateTimestamp; - -import java.time.LocalDateTime; -import java.util.Objects; - -@Entity -@Table(name = "customer") -public class Customer { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long customerId; - - @Column(name = "user_id") - private Long userId; - - @Column(nullable = false, length = 50) - private String firstName; - - @Column(nullable = false, length = 50) - private String lastName; - - @Column(nullable = false, length = 100) - private String email; - - @CreationTimestamp - @Column(name = "created_at", updatable = false) - private LocalDateTime createdAt; - - @UpdateTimestamp - @Column(name = "updated_at") - private LocalDateTime updatedAt; - - public Customer() { - } - - public Customer(Long customerId, Long userId, String firstName, String lastName, String email, LocalDateTime createdAt, LocalDateTime updatedAt) { - this.customerId = customerId; - this.userId = userId; - this.firstName = firstName; - this.lastName = lastName; - this.email = email; - this.createdAt = createdAt; - this.updatedAt = updatedAt; - } - - public Long getCustomerId() { - return customerId; - } - - public void setCustomerId(Long customerId) { - this.customerId = customerId; - } - - public Long getUserId() { - return userId; - } - - public void setUserId(Long userId) { - this.userId = userId; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(LocalDateTime createdAt) { - this.createdAt = createdAt; - } - - public LocalDateTime getUpdatedAt() { - return updatedAt; - } - - public void setUpdatedAt(LocalDateTime updatedAt) { - this.updatedAt = updatedAt; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Customer customer = (Customer) o; - return Objects.equals(customerId, customer.customerId); - } - - @Override - public int hashCode() { - return Objects.hash(customerId); - } - - @Override - public String toString() { - return "Customer{" + - "customerId=" + customerId + - ", userId=" + userId + - ", firstName='" + firstName + '\'' + - ", lastName='" + lastName + '\'' + - ", email='" + email + '\'' + - ", createdAt=" + createdAt + - ", updatedAt=" + updatedAt + - '}'; - } -} diff --git a/backend/src/main/java/com/petshop/backend/entity/CustomerPet.java b/backend/src/main/java/com/petshop/backend/entity/CustomerPet.java deleted file mode 100644 index df75df8c..00000000 --- a/backend/src/main/java/com/petshop/backend/entity/CustomerPet.java +++ /dev/null @@ -1,137 +0,0 @@ -package com.petshop.backend.entity; - -import jakarta.persistence.*; -import org.hibernate.annotations.CreationTimestamp; -import org.hibernate.annotations.UpdateTimestamp; - -import java.time.LocalDateTime; -import java.util.Objects; - -@Entity -@Table(name = "customer_pet") -public class CustomerPet { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "customer_pet_id") - private Long customerPetId; - - @ManyToOne - @JoinColumn(name = "customer_id", nullable = false) - private Customer customer; - - @Column(name = "pet_name", nullable = false, length = 50) - private String petName; - - @Column(nullable = false, length = 50) - private String species; - - @Column(length = 50) - private String breed; - - @Column(name = "image_url", length = 255) - private String imageUrl; - - @CreationTimestamp - @Column(name = "created_at", updatable = false) - private LocalDateTime createdAt; - - @UpdateTimestamp - @Column(name = "updated_at") - private LocalDateTime updatedAt; - - public CustomerPet() { - } - - public Long getCustomerPetId() { - - return customerPetId; - } - - public void setCustomerPetId(Long customerPetId) { - this.customerPetId = customerPetId; - } - - public Customer getCustomer() { - - return customer; - } - - public void setCustomer(Customer customer) { - this.customer = customer; - } - - 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; - } - - public LocalDateTime getCreatedAt() { - - return createdAt; - } - - public void setCreatedAt(LocalDateTime createdAt) { - this.createdAt = createdAt; - } - - public LocalDateTime getUpdatedAt() { - - return updatedAt; - } - - public void setUpdatedAt(LocalDateTime updatedAt) { - this.updatedAt = updatedAt; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (o == null || getClass() != o.getClass()) { - return false; - } - - CustomerPet that = (CustomerPet) o; - return Objects.equals(customerPetId, that.customerPetId); - } - - @Override - public int hashCode() { - - return Objects.hash(customerPetId); - } -} diff --git a/backend/src/main/java/com/petshop/backend/entity/Employee.java b/backend/src/main/java/com/petshop/backend/entity/Employee.java deleted file mode 100644 index c88216f6..00000000 --- a/backend/src/main/java/com/petshop/backend/entity/Employee.java +++ /dev/null @@ -1,158 +0,0 @@ -package com.petshop.backend.entity; - -import jakarta.persistence.*; -import org.hibernate.annotations.CreationTimestamp; -import org.hibernate.annotations.UpdateTimestamp; - -import java.time.LocalDateTime; -import java.util.Objects; - -@Entity -@Table(name = "employee") -public class Employee { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long employeeId; - - @Column(name = "user_id") - private Long userId; - - @Column(nullable = false, length = 50) - private String firstName; - - @Column(nullable = false, length = 50) - private String lastName; - - @Column(nullable = false, length = 100) - private String email; - - @Column(nullable = false, length = 50) - private String role; - - @Column(nullable = false) - private Boolean isActive = true; - - @CreationTimestamp - @Column(name = "created_at", updatable = false) - private LocalDateTime createdAt; - - @UpdateTimestamp - @Column(name = "updated_at") - private LocalDateTime updatedAt; - - public Employee() { - } - - public Employee(Long employeeId, Long userId, String firstName, String lastName, String email, String role, Boolean isActive, LocalDateTime createdAt, LocalDateTime updatedAt) { - this.employeeId = employeeId; - this.userId = userId; - this.firstName = firstName; - this.lastName = lastName; - this.email = email; - this.role = role; - this.isActive = isActive; - this.createdAt = createdAt; - this.updatedAt = updatedAt; - } - - public Long getEmployeeId() { - return employeeId; - } - - public void setEmployeeId(Long employeeId) { - this.employeeId = employeeId; - } - - public Long getUserId() { - return userId; - } - - public void setUserId(Long userId) { - this.userId = userId; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public String getRole() { - return role; - } - - public void setRole(String role) { - this.role = role; - } - - public Boolean getIsActive() { - return isActive; - } - - public void setIsActive(Boolean isActive) { - this.isActive = isActive; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(LocalDateTime createdAt) { - this.createdAt = createdAt; - } - - public LocalDateTime getUpdatedAt() { - return updatedAt; - } - - public void setUpdatedAt(LocalDateTime updatedAt) { - this.updatedAt = updatedAt; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Employee employee = (Employee) o; - return Objects.equals(employeeId, employee.employeeId); - } - - @Override - public int hashCode() { - return Objects.hash(employeeId); - } - - @Override - public String toString() { - return "Employee{" + - "employeeId=" + employeeId + - ", userId=" + userId + - ", firstName='" + firstName + '\'' + - ", lastName='" + lastName + '\'' + - ", email='" + email + '\'' + - ", role='" + role + '\'' + - ", isActive=" + isActive + - ", createdAt=" + createdAt + - ", updatedAt=" + updatedAt + - '}'; - } -} diff --git a/backend/src/main/java/com/petshop/backend/entity/EmployeeStore.java b/backend/src/main/java/com/petshop/backend/entity/EmployeeStore.java deleted file mode 100644 index daa2a2e2..00000000 --- a/backend/src/main/java/com/petshop/backend/entity/EmployeeStore.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.petshop.backend.entity; - -import jakarta.persistence.*; - -import java.io.Serializable; -import java.util.Objects; - -@Entity -@Table(name = "employeeStore") -@IdClass(EmployeeStore.EmployeeStoreId.class) -public class EmployeeStore { - - @Id - @ManyToOne - @JoinColumn(name = "employeeId", nullable = false) - private Employee employee; - - @Id - @ManyToOne - @JoinColumn(name = "storeId", nullable = false) - private StoreLocation store; - - public EmployeeStore() { - } - - public EmployeeStore(Employee employee, StoreLocation store) { - this.employee = employee; - this.store = store; - } - - public Employee getEmployee() { - return employee; - } - - public void setEmployee(Employee employee) { - this.employee = employee; - } - - public StoreLocation getStore() { - return store; - } - - public void setStore(StoreLocation store) { - this.store = store; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - EmployeeStore that = (EmployeeStore) o; - return Objects.equals(employee, that.employee) && Objects.equals(store, that.store); - } - - @Override - public int hashCode() { - return Objects.hash(employee, store); - } - - @Override - public String toString() { - return "EmployeeStore{" + - "employee=" + employee + - ", store=" + store + - '}'; - } - - public static class EmployeeStoreId implements Serializable { - private Long employee; - private Long store; - - public EmployeeStoreId() { - } - - public EmployeeStoreId(Long employee, Long store) { - this.employee = employee; - this.store = store; - } - - public Long getEmployee() { - return employee; - } - - public void setEmployee(Long employee) { - this.employee = employee; - } - - public Long getStore() { - return store; - } - - public void setStore(Long store) { - this.store = store; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - EmployeeStoreId that = (EmployeeStoreId) o; - return Objects.equals(employee, that.employee) && Objects.equals(store, that.store); - } - - @Override - public int hashCode() { - return Objects.hash(employee, store); - } - - @Override - public String toString() { - return "EmployeeStoreId{" + - "employee=" + employee + - ", store=" + store + - '}'; - } - } -} diff --git a/backend/src/main/java/com/petshop/backend/entity/Pet.java b/backend/src/main/java/com/petshop/backend/entity/Pet.java index d0b3b3fc..604a24db 100644 --- a/backend/src/main/java/com/petshop/backend/entity/Pet.java +++ b/backend/src/main/java/com/petshop/backend/entity/Pet.java @@ -23,24 +23,24 @@ public class Pet { @Column(nullable = false, length = 50) private String petSpecies; - @Column(nullable = false, length = 50) + @Column(length = 50) private String petBreed; - @Column(nullable = false) + @Column private Integer petAge; @Column(nullable = false, length = 20) private String petStatus; - @Column(nullable = false, precision = 10, scale = 2) + @Column(precision = 10, scale = 2) private BigDecimal petPrice; @Column(length = 255) private String imageUrl; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "customerId") - private Customer customer; + @JoinColumn(name = "ownerUserId") + private User owner; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "storeId") @@ -57,19 +57,6 @@ public class Pet { public Pet() { } - public Pet(Long id, String petName, String petSpecies, String petBreed, Integer petAge, String petStatus, BigDecimal petPrice, String imageUrl, LocalDateTime createdAt, LocalDateTime updatedAt) { - this.id = id; - this.petName = petName; - this.petSpecies = petSpecies; - this.petBreed = petBreed; - this.petAge = petAge; - this.petStatus = petStatus; - this.petPrice = petPrice; - this.imageUrl = imageUrl; - this.createdAt = createdAt; - this.updatedAt = updatedAt; - } - public Long getPetId() { return id; } @@ -134,6 +121,22 @@ public class Pet { this.imageUrl = imageUrl; } + public User getOwner() { + return owner; + } + + public void setOwner(User owner) { + this.owner = owner; + } + + public StoreLocation getStore() { + return store; + } + + public void setStore(StoreLocation store) { + this.store = store; + } + public LocalDateTime getCreatedAt() { return createdAt; } @@ -150,22 +153,6 @@ public class Pet { this.updatedAt = updatedAt; } - public Customer getCustomer() { - return customer; - } - - public void setCustomer(Customer customer) { - this.customer = customer; - } - - public StoreLocation getStore() { - return store; - } - - public void setStore(StoreLocation store) { - this.store = store; - } - @Override public boolean equals(Object o) { if (this == o) return true; @@ -185,13 +172,7 @@ public class Pet { "id=" + id + ", petName='" + petName + '\'' + ", petSpecies='" + petSpecies + '\'' + - ", petBreed='" + petBreed + '\'' + - ", petAge=" + petAge + ", petStatus='" + petStatus + '\'' + - ", petPrice=" + petPrice + - ", imageUrl='" + imageUrl + '\'' + - ", createdAt=" + createdAt + - ", updatedAt=" + updatedAt + '}'; } } diff --git a/backend/src/main/java/com/petshop/backend/entity/Sale.java b/backend/src/main/java/com/petshop/backend/entity/Sale.java index c60c0927..ee1a9d51 100644 --- a/backend/src/main/java/com/petshop/backend/entity/Sale.java +++ b/backend/src/main/java/com/petshop/backend/entity/Sale.java @@ -23,7 +23,7 @@ public class Sale { @ManyToOne @JoinColumn(name = "employeeId", nullable = false) - private Employee employee; + private User employee; @ManyToOne @JoinColumn(name = "storeId", nullable = false) @@ -31,7 +31,7 @@ public class Sale { @ManyToOne @JoinColumn(name = "customerId") - private Customer customer; + private User customer; @Column(nullable = false, precision = 10, scale = 2) private BigDecimal totalAmount; @@ -60,21 +60,6 @@ public class Sale { public Sale() { } - public Sale(Long saleId, LocalDateTime saleDate, Employee employee, StoreLocation store, Customer customer, BigDecimal totalAmount, String paymentMethod, Boolean isRefund, Sale originalSale, List items, LocalDateTime createdAt, LocalDateTime updatedAt) { - this.saleId = saleId; - this.saleDate = saleDate; - this.employee = employee; - this.store = store; - this.customer = customer; - this.totalAmount = totalAmount; - this.paymentMethod = paymentMethod; - this.isRefund = isRefund; - this.originalSale = originalSale; - this.items = items; - this.createdAt = createdAt; - this.updatedAt = updatedAt; - } - public Long getSaleId() { return saleId; } @@ -91,11 +76,11 @@ public class Sale { this.saleDate = saleDate; } - public Employee getEmployee() { + public User getEmployee() { return employee; } - public void setEmployee(Employee employee) { + public void setEmployee(User employee) { this.employee = employee; } @@ -107,11 +92,11 @@ public class Sale { this.store = store; } - public Customer getCustomer() { + public User getCustomer() { return customer; } - public void setCustomer(Customer customer) { + public void setCustomer(User customer) { this.customer = customer; } @@ -189,16 +174,9 @@ public class Sale { return "Sale{" + "saleId=" + saleId + ", saleDate=" + saleDate + - ", employee=" + employee + - ", store=" + store + - ", customer=" + customer + ", totalAmount=" + totalAmount + ", paymentMethod='" + paymentMethod + '\'' + ", isRefund=" + isRefund + - ", originalSale=" + originalSale + - ", items=" + items + - ", createdAt=" + createdAt + - ", updatedAt=" + updatedAt + '}'; } } diff --git a/backend/src/main/java/com/petshop/backend/repository/AdoptionRepository.java b/backend/src/main/java/com/petshop/backend/repository/AdoptionRepository.java index 7b632f7f..7502ec33 100644 --- a/backend/src/main/java/com/petshop/backend/repository/AdoptionRepository.java +++ b/backend/src/main/java/com/petshop/backend/repository/AdoptionRepository.java @@ -19,9 +19,9 @@ public interface AdoptionRepository extends JpaRepository { "LOWER(a.pet.petName) LIKE LOWER(CONCAT('%', :q, '%'))") Page searchAdoptions(@Param("q") String query, Pageable pageable); - Page findByCustomerCustomerId(Long customerId, Pageable pageable); + Page findByCustomerId(Long customerId, Pageable pageable); - @Query("SELECT a FROM Adoption a WHERE a.customer.customerId = :customerId AND (" + + @Query("SELECT a FROM Adoption a WHERE a.customer.id = :customerId AND (" + "LOWER(a.customer.firstName) LIKE LOWER(CONCAT('%', :q, '%')) OR " + "LOWER(a.customer.lastName) LIKE LOWER(CONCAT('%', :q, '%')) OR " + "LOWER(a.pet.petName) LIKE LOWER(CONCAT('%', :q, '%')))") diff --git a/backend/src/main/java/com/petshop/backend/repository/AppointmentRepository.java b/backend/src/main/java/com/petshop/backend/repository/AppointmentRepository.java index f8649671..f4cdc564 100644 --- a/backend/src/main/java/com/petshop/backend/repository/AppointmentRepository.java +++ b/backend/src/main/java/com/petshop/backend/repository/AppointmentRepository.java @@ -28,18 +28,18 @@ public interface AppointmentRepository extends JpaRepository "LOWER(p.petName) LIKE LOWER(CONCAT('%', :q, '%'))") Page searchAppointments(@Param("q") String query, Pageable pageable); - Page findByCustomerCustomerId(Long customerId, Pageable pageable); + Page findByCustomerId(Long customerId, Pageable pageable); - @Query("SELECT DISTINCT a FROM Appointment a LEFT JOIN a.pets p WHERE a.customer.customerId = :customerId AND (" + + @Query("SELECT DISTINCT a FROM Appointment a LEFT JOIN a.pets p WHERE a.customer.id = :customerId AND (" + "LOWER(a.customer.firstName) LIKE LOWER(CONCAT('%', :q, '%')) OR " + "LOWER(a.customer.lastName) LIKE LOWER(CONCAT('%', :q, '%')) OR " + "LOWER(a.service.serviceName) LIKE LOWER(CONCAT('%', :q, '%')) OR " + "LOWER(p.petName) LIKE LOWER(CONCAT('%', :q, '%')))") Page searchAppointmentsByCustomer(@Param("customerId") Long customerId, @Param("q") String query, Pageable pageable); - @Query("SELECT a FROM Appointment a JOIN FETCH a.service WHERE a.employee.employeeId = :employeeId AND a.appointmentDate = :date AND LOWER(a.appointmentStatus) NOT IN ('cancelled', 'missed')") - List findByEmployeeEmployeeIdAndAppointmentDate(@Param("employeeId") Long employeeId, @Param("date") LocalDate date); + @Query("SELECT a FROM Appointment a JOIN FETCH a.service WHERE a.employee.id = :employeeId AND a.appointmentDate = :date AND LOWER(a.appointmentStatus) NOT IN ('cancelled', 'missed')") + List findByEmployeeIdAndAppointmentDate(@Param("employeeId") Long employeeId, @Param("date") LocalDate date); - @Query("SELECT a FROM Appointment a JOIN FETCH a.service WHERE a.employee.employeeId IN :employeeIds AND a.appointmentDate = :date AND LOWER(a.appointmentStatus) NOT IN ('cancelled', 'missed')") - List findByEmployeeEmployeeIdInAndAppointmentDate(@Param("employeeIds") List employeeIds, @Param("date") LocalDate date); + @Query("SELECT a FROM Appointment a JOIN FETCH a.service WHERE a.employee.id IN :employeeIds AND a.appointmentDate = :date AND LOWER(a.appointmentStatus) NOT IN ('cancelled', 'missed')") + List findByEmployeeIdInAndAppointmentDate(@Param("employeeIds") List employeeIds, @Param("date") LocalDate date); } diff --git a/backend/src/main/java/com/petshop/backend/repository/CustomerPetRepository.java b/backend/src/main/java/com/petshop/backend/repository/CustomerPetRepository.java deleted file mode 100644 index 4fe0ef81..00000000 --- a/backend/src/main/java/com/petshop/backend/repository/CustomerPetRepository.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.petshop.backend.repository; - -import com.petshop.backend.entity.CustomerPet; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -import java.util.List; -import java.util.Optional; - -@Repository -public interface CustomerPetRepository extends JpaRepository { - - List findByCustomerCustomerIdOrderByCreatedAtDesc(Long customerId); - - List findByCustomerCustomerIdOrderByPetNameAsc(Long customerId); - - Optional findByCustomerPetIdAndCustomerCustomerId(Long customerPetId, Long customerId); -} diff --git a/backend/src/main/java/com/petshop/backend/repository/CustomerRepository.java b/backend/src/main/java/com/petshop/backend/repository/CustomerRepository.java deleted file mode 100644 index 2c860de7..00000000 --- a/backend/src/main/java/com/petshop/backend/repository/CustomerRepository.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.petshop.backend.repository; - -import com.petshop.backend.entity.Customer; -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.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; - -import java.util.List; -import java.util.Optional; - -@Repository -public interface CustomerRepository extends JpaRepository { - - Optional findByUserId(Long userId); - List findAllByEmail(String email); - - @Query("SELECT DISTINCT c FROM Customer c WHERE EXISTS (SELECT cp FROM CustomerPet cp WHERE cp.customer = c) ORDER BY c.firstName ASC, c.lastName ASC") - List findAllWithPets(); - - @Query("SELECT c FROM Customer c WHERE " + - "LOWER(c.firstName) LIKE LOWER(CONCAT('%', :q, '%')) OR " + - "LOWER(c.lastName) LIKE LOWER(CONCAT('%', :q, '%')) OR " + - "LOWER(c.email) LIKE LOWER(CONCAT('%', :q, '%')) OR " + - "EXISTS (SELECT u FROM User u WHERE u.id = c.userId AND LOWER(COALESCE(u.phone, '')) LIKE LOWER(CONCAT('%', :q, '%')))") - Page searchCustomers(@Param("q") String query, Pageable pageable); -} diff --git a/backend/src/main/java/com/petshop/backend/repository/EmployeeRepository.java b/backend/src/main/java/com/petshop/backend/repository/EmployeeRepository.java deleted file mode 100644 index e320fc00..00000000 --- a/backend/src/main/java/com/petshop/backend/repository/EmployeeRepository.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.petshop.backend.repository; - -import com.petshop.backend.entity.Employee; -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.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; - -import java.util.List; -import java.util.Optional; - -@Repository -public interface EmployeeRepository extends JpaRepository { - Optional findByUserId(Long userId); - List findAllByEmail(String email); - Optional findFirstByIsActiveTrueOrderByEmployeeIdAsc(); - List findAllByIsActiveTrueOrderByEmployeeIdAsc(); - - @Query("SELECT e FROM Employee e WHERE " + - "LOWER(e.firstName) LIKE LOWER(CONCAT('%', :q, '%')) OR " + - "LOWER(e.lastName) LIKE LOWER(CONCAT('%', :q, '%')) OR " + - "LOWER(e.email) LIKE LOWER(CONCAT('%', :q, '%')) OR " + - "LOWER(e.role) LIKE LOWER(CONCAT('%', :q, '%')) OR " + - "EXISTS (SELECT u FROM User u WHERE u.id = e.userId AND (" + - "LOWER(u.username) LIKE LOWER(CONCAT('%', :q, '%')) OR " + - "LOWER(COALESCE(u.phone, '')) LIKE LOWER(CONCAT('%', :q, '%'))))") - Page searchEmployees(@Param("q") String query, Pageable pageable); -} diff --git a/backend/src/main/java/com/petshop/backend/repository/EmployeeStoreRepository.java b/backend/src/main/java/com/petshop/backend/repository/EmployeeStoreRepository.java deleted file mode 100644 index 16a59cea..00000000 --- a/backend/src/main/java/com/petshop/backend/repository/EmployeeStoreRepository.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.petshop.backend.repository; - -import com.petshop.backend.entity.EmployeeStore; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; - -import java.util.List; -import java.util.Optional; - -@Repository -public interface EmployeeStoreRepository extends JpaRepository { - Optional findByEmployeeEmployeeId(Long employeeId); - - @Query("SELECT es FROM EmployeeStore es WHERE es.store.storeId = :storeId AND es.employee.isActive = true ORDER BY es.employee.employeeId ASC") - List findActiveByStoreStoreIdOrderByEmployeeEmployeeIdAsc(@Param("storeId") Long storeId); - - @Query("SELECT es FROM EmployeeStore es WHERE es.employee.isActive = true ORDER BY es.employee.employeeId ASC") - List findActiveAllOrderByEmployeeEmployeeIdAsc(); -} diff --git a/backend/src/main/java/com/petshop/backend/repository/PetRepository.java b/backend/src/main/java/com/petshop/backend/repository/PetRepository.java index d01c2d85..fd55fabe 100644 --- a/backend/src/main/java/com/petshop/backend/repository/PetRepository.java +++ b/backend/src/main/java/com/petshop/backend/repository/PetRepository.java @@ -16,21 +16,21 @@ public interface PetRepository extends JpaRepository { List findAllByPetStatusIgnoreCaseOrderByPetNameAsc(String petStatus); @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(p.petBreed) LIKE LOWER(CONCAT('%', :q, '%'))) AND " + + "(: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 " + "(:species IS NULL OR LOWER(p.petSpecies) = LOWER(:species)) AND " + "(:status IS NULL OR LOWER(p.petStatus) = LOWER(:status)) AND " + "(:storeId IS NULL OR p.store.storeId = :storeId)") Page searchPets(@Param("q") String query, @Param("species") String species, @Param("status") String status, @Param("storeId") Long storeId, Pageable pageable); @Query("SELECT p FROM Pet p WHERE LOWER(p.petStatus) = 'available' AND " + - "(:q IS NULL OR LOWER(p.petName) LIKE LOWER(CONCAT('%', :q, '%')) OR LOWER(p.petSpecies) LIKE LOWER(CONCAT('%', :q, '%')) OR LOWER(p.petBreed) LIKE LOWER(CONCAT('%', :q, '%'))) AND " + + "(: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 " + "(:species IS NULL OR LOWER(p.petSpecies) = LOWER(:species)) AND " + "(:storeId IS NULL OR p.store.storeId = :storeId)") Page searchPublicPets(@Param("q") String query, @Param("species") String species, @Param("storeId") Long storeId, Pageable pageable); @Query("SELECT DISTINCT p FROM Pet p LEFT JOIN Adoption a ON a.pet = p AND LOWER(a.adoptionStatus) = 'completed' WHERE " + - "(LOWER(p.petStatus) = 'available' OR a.customer.userId = :userId OR (LOWER(p.petStatus) = 'owned' AND p.customer.userId = :userId)) AND " + - "(:q IS NULL OR LOWER(p.petName) LIKE LOWER(CONCAT('%', :q, '%')) OR LOWER(p.petSpecies) LIKE LOWER(CONCAT('%', :q, '%')) OR LOWER(p.petBreed) LIKE LOWER(CONCAT('%', :q, '%'))) AND " + + "(LOWER(p.petStatus) = 'available' OR a.customer.id = :userId OR (LOWER(p.petStatus) = 'owned' AND p.owner.id = :userId)) AND " + + "(: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 " + "(:species IS NULL OR LOWER(p.petSpecies) = LOWER(:species)) AND " + "(:status IS NULL OR LOWER(p.petStatus) = LOWER(:status))") Page searchCustomerVisiblePets(@Param("userId") Long userId, @Param("q") String query, @Param("species") String species, @Param("status") String status, Pageable pageable); diff --git a/backend/src/main/java/com/petshop/backend/repository/UserRepository.java b/backend/src/main/java/com/petshop/backend/repository/UserRepository.java index 6bec352f..592a4a76 100644 --- a/backend/src/main/java/com/petshop/backend/repository/UserRepository.java +++ b/backend/src/main/java/com/petshop/backend/repository/UserRepository.java @@ -8,6 +8,7 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import java.util.List; import java.util.Optional; @Repository @@ -17,16 +18,24 @@ public interface UserRepository extends JpaRepository { Optional findByPhone(String phone); boolean existsByUsername(String username); Page findByRole(User.Role role, Pageable pageable); + List findByRoleAndActiveTrue(User.Role role); + List findByPrimaryStoreStoreIdAndRoleAndActiveTrue(Long storeId, User.Role role); + Optional findFirstByPrimaryStoreStoreIdAndRoleAndActiveTrueOrderByIdAsc(Long storeId, User.Role role); + Optional findFirstByRoleAndActiveTrueOrderByIdAsc(User.Role role); @Query("SELECT u FROM User u WHERE " + - "LOWER(u.username) LIKE LOWER(CONCAT('%', :q, '%')) OR " + + "LOWER(COALESCE(u.username, '')) LIKE LOWER(CONCAT('%', :q, '%')) OR " + + "LOWER(COALESCE(u.firstName, '')) LIKE LOWER(CONCAT('%', :q, '%')) OR " + + "LOWER(COALESCE(u.lastName, '')) LIKE LOWER(CONCAT('%', :q, '%')) OR " + "LOWER(COALESCE(u.fullName, '')) LIKE LOWER(CONCAT('%', :q, '%')) OR " + "LOWER(COALESCE(u.email, '')) LIKE LOWER(CONCAT('%', :q, '%')) OR " + "LOWER(COALESCE(u.phone, '')) LIKE LOWER(CONCAT('%', :q, '%'))") Page searchUsers(@Param("q") String query, Pageable pageable); @Query("SELECT u FROM User u WHERE u.role = :role AND (" + - "LOWER(u.username) LIKE LOWER(CONCAT('%', :q, '%')) OR " + + "LOWER(COALESCE(u.username, '')) LIKE LOWER(CONCAT('%', :q, '%')) OR " + + "LOWER(COALESCE(u.firstName, '')) LIKE LOWER(CONCAT('%', :q, '%')) OR " + + "LOWER(COALESCE(u.lastName, '')) LIKE LOWER(CONCAT('%', :q, '%')) OR " + "LOWER(COALESCE(u.fullName, '')) LIKE LOWER(CONCAT('%', :q, '%')) OR " + "LOWER(COALESCE(u.email, '')) LIKE LOWER(CONCAT('%', :q, '%')) OR " + "LOWER(COALESCE(u.phone, '')) LIKE LOWER(CONCAT('%', :q, '%')))") diff --git a/backend/src/main/java/com/petshop/backend/service/AdoptionService.java b/backend/src/main/java/com/petshop/backend/service/AdoptionService.java index c6ff1c60..caadfbb9 100644 --- a/backend/src/main/java/com/petshop/backend/service/AdoptionService.java +++ b/backend/src/main/java/com/petshop/backend/service/AdoptionService.java @@ -4,14 +4,10 @@ import com.petshop.backend.dto.adoption.AdoptionRequest; import com.petshop.backend.dto.adoption.AdoptionResponse; import com.petshop.backend.dto.common.BulkDeleteRequest; import com.petshop.backend.entity.Adoption; -import com.petshop.backend.entity.Customer; -import com.petshop.backend.entity.Employee; import com.petshop.backend.entity.Pet; import com.petshop.backend.entity.User; import com.petshop.backend.exception.ResourceNotFoundException; import com.petshop.backend.repository.AdoptionRepository; -import com.petshop.backend.repository.CustomerRepository; -import com.petshop.backend.repository.EmployeeRepository; import com.petshop.backend.repository.PetRepository; import com.petshop.backend.repository.UserRepository; import org.springframework.data.domain.Page; @@ -30,15 +26,11 @@ public class AdoptionService { private final AdoptionRepository adoptionRepository; private final PetRepository petRepository; - private final CustomerRepository customerRepository; - private final EmployeeRepository employeeRepository; private final UserRepository userRepository; - public AdoptionService(AdoptionRepository adoptionRepository, PetRepository petRepository, CustomerRepository customerRepository, EmployeeRepository employeeRepository, UserRepository userRepository) { + public AdoptionService(AdoptionRepository adoptionRepository, PetRepository petRepository, UserRepository userRepository) { this.adoptionRepository = adoptionRepository; this.petRepository = petRepository; - this.customerRepository = customerRepository; - this.employeeRepository = employeeRepository; this.userRepository = userRepository; } @@ -49,7 +41,7 @@ public class AdoptionService { if (query != null && !query.trim().isEmpty()) { adoptions = adoptionRepository.searchAdoptionsByCustomer(customerId, query, pageable); } else { - adoptions = adoptionRepository.findByCustomerCustomerId(customerId, pageable); + adoptions = adoptionRepository.findByCustomerId(customerId, pageable); } } else { if (query != null && !query.trim().isEmpty()) { @@ -66,7 +58,7 @@ public class AdoptionService { Adoption adoption = adoptionRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException("Adoption not found with id: " + id)); - if (customerId != null && !adoption.getCustomer().getCustomerId().equals(customerId)) { + if (customerId != null && !adoption.getCustomer().getId().equals(customerId)) { throw new ResourceNotFoundException("You can only view your own adoptions"); } @@ -78,9 +70,9 @@ public class AdoptionService { Pet pet = petRepository.findById(request.getPetId()) .orElseThrow(() -> new ResourceNotFoundException("Pet not found with id: " + request.getPetId())); - Customer customer = customerRepository.findById(request.getCustomerId()) + User customer = userRepository.findById(request.getCustomerId()) .orElseThrow(() -> new ResourceNotFoundException("Customer not found with id: " + request.getCustomerId())); - Employee employee = resolveAdoptionEmployee(request.getEmployeeId()); + User employee = resolveAdoptionEmployee(request.getEmployeeId()); String adoptionStatus = normalizeAdoptionStatus(request.getAdoptionStatus()); validatePetAvailability(pet, null); @@ -104,9 +96,9 @@ public class AdoptionService { Pet pet = petRepository.findById(request.getPetId()) .orElseThrow(() -> new ResourceNotFoundException("Pet not found with id: " + request.getPetId())); - Customer customer = customerRepository.findById(request.getCustomerId()) + User customer = userRepository.findById(request.getCustomerId()) .orElseThrow(() -> new ResourceNotFoundException("Customer not found with id: " + request.getCustomerId())); - Employee employee = resolveAdoptionEmployee(request.getEmployeeId()); + User employee = resolveAdoptionEmployee(request.getEmployeeId()); String adoptionStatus = normalizeAdoptionStatus(request.getAdoptionStatus()); validatePetAvailability(pet, adoption.getAdoptionId()); @@ -139,9 +131,9 @@ public class AdoptionService { adoption.getAdoptionId(), adoption.getPet().getPetId(), adoption.getPet().getPetName(), - adoption.getCustomer().getCustomerId(), + adoption.getCustomer().getId(), adoption.getCustomer().getFirstName() + " " + adoption.getCustomer().getLastName(), - adoption.getEmployee().getEmployeeId(), + adoption.getEmployee().getId(), adoption.getEmployee().getFirstName() + " " + adoption.getEmployee().getLastName(), adoption.getAdoptionDate(), adoption.getAdoptionStatus(), @@ -151,31 +143,22 @@ public class AdoptionService { ); } - private Employee resolveAdoptionEmployee(Long requestedEmployeeId) { + private User resolveAdoptionEmployee(Long requestedEmployeeId) { if (requestedEmployeeId != null) { - Employee employee = employeeRepository.findById(requestedEmployeeId) + User employee = userRepository.findById(requestedEmployeeId) .orElseThrow(() -> new ResourceNotFoundException("Employee not found with id: " + requestedEmployeeId)); - if (!isAssignableEmployee(employee)) { + if (!isAssignableUser(employee)) { throw new IllegalArgumentException("Selected employee is not assignable for adoption work"); } return employee; } - return employeeRepository.findAllByIsActiveTrueOrderByEmployeeIdAsc().stream() - .filter(this::isAssignableEmployee) - .findFirst() + return userRepository.findFirstByRoleAndActiveTrueOrderByIdAsc(User.Role.STAFF) .orElseThrow(() -> new IllegalArgumentException("No assignable staff member is available for adoption assignment")); } - private boolean isAssignableEmployee(Employee employee) { - Long userId = employee.getUserId(); - if (userId == null || !Boolean.TRUE.equals(employee.getIsActive())) { - return false; - } - return userRepository.findById(userId) - .filter(user -> user.getRole() == User.Role.STAFF) - .filter(user -> Boolean.TRUE.equals(user.getActive())) - .isPresent(); + private boolean isAssignableUser(User user) { + return user.getRole() == User.Role.STAFF && Boolean.TRUE.equals(user.getActive()); } private String normalizeAdoptionStatus(String adoptionStatus) { diff --git a/backend/src/main/java/com/petshop/backend/service/AnalyticsService.java b/backend/src/main/java/com/petshop/backend/service/AnalyticsService.java index c14a9511..f4841228 100644 --- a/backend/src/main/java/com/petshop/backend/service/AnalyticsService.java +++ b/backend/src/main/java/com/petshop/backend/service/AnalyticsService.java @@ -1,12 +1,10 @@ package com.petshop.backend.service; import com.petshop.backend.dto.analytics.DashboardResponse; -import com.petshop.backend.entity.Employee; import com.petshop.backend.entity.Inventory; import com.petshop.backend.entity.Product; import com.petshop.backend.entity.Sale; import com.petshop.backend.entity.User; -import com.petshop.backend.repository.EmployeeRepository; import com.petshop.backend.repository.InventoryRepository; import com.petshop.backend.repository.ProductRepository; import com.petshop.backend.repository.SaleRepository; @@ -26,14 +24,12 @@ public class AnalyticsService { private final SaleRepository saleRepository; private final InventoryRepository inventoryRepository; private final ProductRepository productRepository; - private final EmployeeRepository employeeRepository; public AnalyticsService(SaleRepository saleRepository, - InventoryRepository inventoryRepository, ProductRepository productRepository, EmployeeRepository employeeRepository) { + InventoryRepository inventoryRepository, ProductRepository productRepository) { this.saleRepository = saleRepository; this.inventoryRepository = inventoryRepository; this.productRepository = productRepository; - this.employeeRepository = employeeRepository; } @Transactional(readOnly = true) @@ -183,11 +179,8 @@ public class AnalyticsService { } if (user.getRole() == User.Role.STAFF && employeeRevenue.isEmpty()) { - Employee employee = employeeRepository.findByUserId(user.getId()).orElse(null); - if (employee != null) { - String employeeName = employee.getFirstName() + " " + employee.getLastName(); - employeeRevenue.put(employeeName, BigDecimal.ZERO); - } + String employeeName = user.getFirstName() + " " + user.getLastName(); + employeeRevenue.put(employeeName, BigDecimal.ZERO); } return employeeRevenue.entrySet().stream() @@ -200,7 +193,7 @@ public class AnalyticsService { return true; } if (user.getRole() == User.Role.STAFF) { - return sale.getEmployee() != null && sale.getEmployee().getUserId() != null && sale.getEmployee().getUserId().equals(user.getId()); + return sale.getEmployee() != null && sale.getEmployee().getId() != null && sale.getEmployee().getId().equals(user.getId()); } return false; } 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 155b7524..d3a8594e 100644 --- a/backend/src/main/java/com/petshop/backend/service/AppointmentService.java +++ b/backend/src/main/java/com/petshop/backend/service/AppointmentService.java @@ -4,19 +4,11 @@ import com.petshop.backend.dto.appointment.AppointmentRequest; import com.petshop.backend.dto.appointment.AppointmentResponse; import com.petshop.backend.dto.common.BulkDeleteRequest; import com.petshop.backend.entity.Appointment; -import com.petshop.backend.entity.Customer; -import com.petshop.backend.entity.CustomerPet; -import com.petshop.backend.entity.Employee; -import com.petshop.backend.entity.EmployeeStore; import com.petshop.backend.entity.Pet; import com.petshop.backend.entity.StoreLocation; import com.petshop.backend.entity.User; import com.petshop.backend.exception.ResourceNotFoundException; import com.petshop.backend.repository.AppointmentRepository; -import com.petshop.backend.repository.CustomerPetRepository; -import com.petshop.backend.repository.CustomerRepository; -import com.petshop.backend.repository.EmployeeRepository; -import com.petshop.backend.repository.EmployeeStoreRepository; import com.petshop.backend.repository.PetRepository; import com.petshop.backend.repository.ServiceRepository; import com.petshop.backend.repository.StoreRepository; @@ -41,25 +33,17 @@ import java.util.stream.Collectors; public class AppointmentService { private final AppointmentRepository appointmentRepository; - private final CustomerRepository customerRepository; - private final CustomerPetRepository customerPetRepository; private final ServiceRepository serviceRepository; private final PetRepository petRepository; private final StoreRepository storeRepository; private final UserRepository userRepository; - private final EmployeeRepository employeeRepository; - private final EmployeeStoreRepository employeeStoreRepository; - public AppointmentService(AppointmentRepository appointmentRepository, CustomerRepository customerRepository, CustomerPetRepository customerPetRepository, ServiceRepository serviceRepository, PetRepository petRepository, StoreRepository storeRepository, UserRepository userRepository, EmployeeRepository employeeRepository, EmployeeStoreRepository employeeStoreRepository) { + public AppointmentService(AppointmentRepository appointmentRepository, ServiceRepository serviceRepository, PetRepository petRepository, StoreRepository storeRepository, UserRepository userRepository) { this.appointmentRepository = appointmentRepository; - this.customerRepository = customerRepository; - this.customerPetRepository = customerPetRepository; this.serviceRepository = serviceRepository; this.petRepository = petRepository; this.storeRepository = storeRepository; this.userRepository = userRepository; - this.employeeRepository = employeeRepository; - this.employeeStoreRepository = employeeStoreRepository; } @Transactional(readOnly = true) @@ -70,7 +54,7 @@ public class AppointmentService { if (query != null && !query.trim().isEmpty()) { appointments = appointmentRepository.searchAppointmentsByCustomer(customerId, query, pageable); } else { - appointments = appointmentRepository.findByCustomerCustomerId(customerId, pageable); + appointments = appointmentRepository.findByCustomerId(customerId, pageable); } } else { if (query != null && !query.trim().isEmpty()) { @@ -88,7 +72,7 @@ public class AppointmentService { Appointment appointment = appointmentRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException("Appointment not found with id: " + id)); - if (customerId != null && !appointment.getCustomer().getCustomerId().equals(customerId)) { + if (customerId != null && !appointment.getCustomer().getId().equals(customerId)) { throw new ResourceNotFoundException("You can only view your own appointments"); } @@ -101,7 +85,7 @@ public class AppointmentService { User authenticatedUser = AuthenticationHelper.getAuthenticatedUser(userRepository); - Customer customer = customerRepository.findById(request.getCustomerId()) + User customer = userRepository.findById(request.getCustomerId()) .orElseThrow(() -> new ResourceNotFoundException("Customer not found with id: " + request.getCustomerId())); StoreLocation store = storeRepository.findById(request.getStoreId()) @@ -111,15 +95,13 @@ public class AppointmentService { .orElseThrow(() -> new ResourceNotFoundException("Service not found with id: " + request.getServiceId())); boolean hasPetIds = request.getPetIds() != null && !request.getPetIds().isEmpty(); - boolean hasCustomerPetIds = request.getCustomerPetIds() != null && !request.getCustomerPetIds().isEmpty(); - if (!hasPetIds && !hasCustomerPetIds) { + if (!hasPetIds) { throw new IllegalArgumentException("Please specify at least one pet."); } - Set pets = hasPetIds ? fetchPets(request.getPetIds()) : new HashSet<>(); - Set customerPets = hasCustomerPetIds ? fetchCustomerPets(request.getCustomerPetIds(), customer.getCustomerId()) : new HashSet<>(); - Employee employee = resolveAppointmentEmployee(request.getEmployeeId(), store.getStoreId()); + Set pets = fetchPets(request.getPetIds()); + User employee = resolveAppointmentEmployee(request.getEmployeeId(), store.getStoreId()); validateStoreAccess(store.getStoreId(), authenticatedUser); validateAvailability(employee, service, request.getAppointmentDate(), request.getAppointmentTime(), null); @@ -132,7 +114,6 @@ public class AppointmentService { appointment.setAppointmentTime(request.getAppointmentTime()); appointment.setAppointmentStatus(request.getAppointmentStatus()); appointment.setPets(pets); - appointment.setCustomerPets(customerPets); appointment.setEmployee(employee); appointment = appointmentRepository.save(appointment); @@ -148,7 +129,7 @@ public class AppointmentService { Appointment appointment = appointmentRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException("Appointment not found with id: " + id)); - Customer customer = customerRepository.findById(request.getCustomerId()) + User customer = userRepository.findById(request.getCustomerId()) .orElseThrow(() -> new ResourceNotFoundException("Customer not found with id: " + request.getCustomerId())); StoreLocation store = storeRepository.findById(request.getStoreId()) @@ -158,15 +139,13 @@ public class AppointmentService { .orElseThrow(() -> new ResourceNotFoundException("Service not found with id: " + request.getServiceId())); boolean hasPetIds = request.getPetIds() != null && !request.getPetIds().isEmpty(); - boolean hasCustomerPetIds = request.getCustomerPetIds() != null && !request.getCustomerPetIds().isEmpty(); - if (!hasPetIds && !hasCustomerPetIds) { + if (!hasPetIds) { throw new IllegalArgumentException("Please specify at least one pet."); } - Set pets = hasPetIds ? fetchPets(request.getPetIds()) : new HashSet<>(); - Set customerPets = hasCustomerPetIds ? fetchCustomerPets(request.getCustomerPetIds(), customer.getCustomerId()) : new HashSet<>(); - Employee employee = resolveAppointmentEmployee(request.getEmployeeId(), store.getStoreId()); + Set pets = fetchPets(request.getPetIds()); + User employee = resolveAppointmentEmployee(request.getEmployeeId(), store.getStoreId()); validateStoreAccess(store.getStoreId(), authenticatedUser); validateAvailability(employee, service, request.getAppointmentDate(), request.getAppointmentTime(), id); @@ -178,7 +157,6 @@ public class AppointmentService { appointment.setAppointmentTime(request.getAppointmentTime()); appointment.setAppointmentStatus(request.getAppointmentStatus()); appointment.setPets(pets); - appointment.setCustomerPets(customerPets); appointment.setEmployee(employee); appointment = appointmentRepository.save(appointment); @@ -206,20 +184,17 @@ public class AppointmentService { com.petshop.backend.entity.Service service = serviceRepository.findById(serviceId) .orElseThrow(() -> new ResourceNotFoundException("Service not found with id: " + serviceId)); - List assignableEmployees = employeeStoreRepository.findActiveByStoreStoreIdOrderByEmployeeEmployeeIdAsc(storeId).stream() - .filter(es -> isAssignableEmployee(es.getEmployee())) - .map(EmployeeStore::getEmployee) - .collect(Collectors.toList()); + List assignableUsers = userRepository.findByPrimaryStoreStoreIdAndRoleAndActiveTrue(storeId, User.Role.STAFF); - if (assignableEmployees.isEmpty()) { + if (assignableUsers.isEmpty()) { return List.of(); } - List employeeIds = assignableEmployees.stream().map(Employee::getEmployeeId).collect(Collectors.toList()); - List allAppointments = appointmentRepository.findByEmployeeEmployeeIdInAndAppointmentDate(employeeIds, date); - + List employeeIds = assignableUsers.stream().map(User::getId).collect(Collectors.toList()); + List allAppointments = appointmentRepository.findByEmployeeIdInAndAppointmentDate(employeeIds, date); + java.util.Map> appointmentsByEmployee = allAppointments.stream() - .collect(Collectors.groupingBy(a -> a.getEmployee().getEmployeeId())); + .collect(Collectors.groupingBy(a -> a.getEmployee().getId())); List availableSlots = new ArrayList<>(); LocalTime startTime = LocalTime.of(9, 0); @@ -229,8 +204,8 @@ public class AppointmentService { LocalTime currentTime = startTime; while (!currentTime.isAfter(latestStart)) { final LocalTime slotTime = currentTime; - boolean anyEmployeeAvailable = assignableEmployees.stream().anyMatch(emp -> { - List empAppointments = appointmentsByEmployee.getOrDefault(emp.getEmployeeId(), List.of()); + boolean anyEmployeeAvailable = assignableUsers.stream().anyMatch(emp -> { + List empAppointments = appointmentsByEmployee.getOrDefault(emp.getId(), List.of()); return isSlotAvailable(empAppointments, service, slotTime, null); }); @@ -262,20 +237,6 @@ public class AppointmentService { return pets; } - private Set fetchCustomerPets(List customerPetIds, Long customerId) { - Set customerPets = new HashSet<>(); - for (Long customerPetId : customerPetIds) { - CustomerPet customerPet = customerPetRepository.findById(customerPetId) - .orElseThrow(() -> new ResourceNotFoundException("Customer pet not found with id: " + customerPetId)); - if (!customerPet.getCustomer().getCustomerId().equals(customerId)) { - throw new IllegalArgumentException("Selected pet does not belong to the selected customer"); - } - customerPets.add(customerPet); - } - - return customerPets; - } - private AppointmentResponse mapToResponse(Appointment appointment) { List petNames = appointment.getPets().stream() .map(Pet::getPetName) @@ -285,17 +246,9 @@ public class AppointmentService { .map(Pet::getPetId) .collect(Collectors.toList()); - List customerPetNames = appointment.getCustomerPets().stream() - .map(CustomerPet::getPetName) - .collect(Collectors.toList()); - - List customerPetIds = appointment.getCustomerPets().stream() - .map(CustomerPet::getCustomerPetId) - .collect(Collectors.toList()); - AppointmentResponse response = new AppointmentResponse(); response.setAppointmentId(appointment.getAppointmentId()); - response.setCustomerId(appointment.getCustomer().getCustomerId()); + response.setCustomerId(appointment.getCustomer().getId()); response.setCustomerName(appointment.getCustomer().getFirstName() + " " + appointment.getCustomer().getLastName()); response.setStoreId(appointment.getStore().getStoreId()); response.setStoreName(appointment.getStore().getStoreName()); @@ -304,54 +257,38 @@ public class AppointmentService { response.setAppointmentDate(appointment.getAppointmentDate()); response.setAppointmentTime(appointment.getAppointmentTime()); response.setAppointmentStatus(appointment.getAppointmentStatus()); - response.setEmployeeId(appointment.getEmployee().getEmployeeId()); + response.setEmployeeId(appointment.getEmployee().getId()); response.setEmployeeName(appointment.getEmployee().getFirstName() + " " + appointment.getEmployee().getLastName()); response.setPetNames(petNames); response.setPetIds(petIds); - response.setCustomerPetNames(customerPetNames); - response.setCustomerPetIds(customerPetIds); response.setCreatedAt(appointment.getCreatedAt()); response.setUpdatedAt(appointment.getUpdatedAt()); - + return response; } - private Employee resolveAppointmentEmployee(Long requestedEmployeeId, Long storeId) { - List assignableEmployees = employeeStoreRepository.findActiveByStoreStoreIdOrderByEmployeeEmployeeIdAsc(storeId).stream() - .filter(es -> isAssignableEmployee(es.getEmployee())) - .collect(Collectors.toList()); + private User resolveAppointmentEmployee(Long requestedEmployeeId, Long storeId) { + List assignableUsers = userRepository.findByPrimaryStoreStoreIdAndRoleAndActiveTrue(storeId, User.Role.STAFF); if (requestedEmployeeId != null) { - Employee employee = employeeRepository.findById(requestedEmployeeId) + User employee = userRepository.findById(requestedEmployeeId) .orElseThrow(() -> new ResourceNotFoundException("Employee not found with id: " + requestedEmployeeId)); - boolean assignedToStore = assignableEmployees.stream() - .anyMatch(es -> es.getEmployee().getEmployeeId().equals(requestedEmployeeId)); + boolean assignedToStore = assignableUsers.stream() + .anyMatch(u -> u.getId().equals(requestedEmployeeId)); if (!assignedToStore) { throw new IllegalArgumentException("Selected employee is not assignable for the selected store"); } return employee; } - return assignableEmployees.stream() - .map(EmployeeStore::getEmployee) + return assignableUsers.stream() .findFirst() .orElseThrow(() -> new IllegalArgumentException("No assignable staff member is assigned to the selected store")); } - private boolean isAssignableEmployee(Employee employee) { - Long userId = employee.getUserId(); - if (userId == null || !Boolean.TRUE.equals(employee.getIsActive())) { - return false; - } - return userRepository.findById(userId) - .filter(user -> user.getRole() == User.Role.STAFF) - .filter(user -> Boolean.TRUE.equals(user.getActive())) - .isPresent(); - } - - private void validateAvailability(Employee employee, com.petshop.backend.entity.Service service, LocalDate date, LocalTime time, Long appointmentIdToIgnore) { + private void validateAvailability(User employee, com.petshop.backend.entity.Service service, LocalDate date, LocalTime time, Long appointmentIdToIgnore) { List existingAppointments = appointmentRepository - .findByEmployeeEmployeeIdAndAppointmentDate(employee.getEmployeeId(), date); + .findByEmployeeIdAndAppointmentDate(employee.getId(), date); if (!isSlotAvailable(existingAppointments, service, time, appointmentIdToIgnore)) { throw new IllegalArgumentException("The selected employee is already booked for this time slot"); } @@ -377,11 +314,7 @@ public class AppointmentService { return; } - Employee employee = AuthenticationHelper.getAuthenticatedEmployee(userRepository, employeeRepository); - EmployeeStore employeeStore = employeeStoreRepository.findByEmployeeEmployeeId(employee.getEmployeeId()) - .orElseThrow(() -> new AccessDeniedException("Authenticated staff member is not assigned to a store")); - - if (!employeeStore.getStore().getStoreId().equals(requestedStoreId)) { + if (user.getPrimaryStore() == null || !user.getPrimaryStore().getStoreId().equals(requestedStoreId)) { throw new AccessDeniedException("Staff can only manage appointments for their assigned store"); } } diff --git a/backend/src/main/java/com/petshop/backend/service/ChatRealtimeService.java b/backend/src/main/java/com/petshop/backend/service/ChatRealtimeService.java index 9b835823..b5b808c2 100644 --- a/backend/src/main/java/com/petshop/backend/service/ChatRealtimeService.java +++ b/backend/src/main/java/com/petshop/backend/service/ChatRealtimeService.java @@ -3,11 +3,9 @@ package com.petshop.backend.service; import com.petshop.backend.dto.chat.ConversationResponse; import com.petshop.backend.dto.chat.MessageResponse; import com.petshop.backend.entity.Conversation; -import com.petshop.backend.entity.Customer; import com.petshop.backend.entity.User; import com.petshop.backend.exception.ResourceNotFoundException; import com.petshop.backend.repository.ConversationRepository; -import com.petshop.backend.repository.CustomerRepository; import com.petshop.backend.repository.MessageRepository; import com.petshop.backend.repository.UserRepository; import org.springframework.messaging.simp.SimpMessagingTemplate; @@ -21,14 +19,12 @@ public class ChatRealtimeService { private final SimpMessagingTemplate messagingTemplate; private final ConversationRepository conversationRepository; private final MessageRepository messageRepository; - private final CustomerRepository customerRepository; private final UserRepository userRepository; - public ChatRealtimeService(SimpMessagingTemplate messagingTemplate, ConversationRepository conversationRepository, MessageRepository messageRepository, CustomerRepository customerRepository, UserRepository userRepository) { + public ChatRealtimeService(SimpMessagingTemplate messagingTemplate, ConversationRepository conversationRepository, MessageRepository messageRepository, UserRepository userRepository) { this.messagingTemplate = messagingTemplate; this.conversationRepository = conversationRepository; this.messageRepository = messageRepository; - this.customerRepository = customerRepository; this.userRepository = userRepository; } @@ -54,13 +50,11 @@ public class ChatRealtimeService { } private void sendConversationToCustomerQueue(ConversationResponse conversation) { - Customer customer = customerRepository.findById(conversation.getCustomerId()) - .orElseThrow(() -> new ResourceNotFoundException("Customer not found")); - if (customer.getUserId() == null) { + User customerUser = userRepository.findById(conversation.getCustomerId()) + .orElseThrow(() -> new ResourceNotFoundException("User not found")); + if (customerUser.getUsername() == null) { return; } - User customerUser = userRepository.findById(customer.getUserId()) - .orElseThrow(() -> new ResourceNotFoundException("User not found")); messagingTemplate.convertAndSendToUser(customerUser.getUsername(), "/queue/chat/conversations", conversation); } diff --git a/backend/src/main/java/com/petshop/backend/service/ChatService.java b/backend/src/main/java/com/petshop/backend/service/ChatService.java index 6ae0c4da..e39d9c55 100644 --- a/backend/src/main/java/com/petshop/backend/service/ChatService.java +++ b/backend/src/main/java/com/petshop/backend/service/ChatService.java @@ -6,12 +6,10 @@ import com.petshop.backend.dto.chat.MessageRequest; import com.petshop.backend.dto.chat.MessageResponse; import com.petshop.backend.dto.chat.UpdateConversationRequest; import com.petshop.backend.entity.Conversation; -import com.petshop.backend.entity.Customer; import com.petshop.backend.entity.Message; import com.petshop.backend.entity.User; import com.petshop.backend.exception.ResourceNotFoundException; import com.petshop.backend.repository.ConversationRepository; -import com.petshop.backend.repository.CustomerRepository; import com.petshop.backend.repository.MessageRepository; import com.petshop.backend.repository.UserRepository; import org.springframework.security.access.AccessDeniedException; @@ -28,16 +26,13 @@ public class ChatService { private final ConversationRepository conversationRepository; private final MessageRepository messageRepository; private final UserRepository userRepository; - private final CustomerRepository customerRepository; public ChatService(ConversationRepository conversationRepository, MessageRepository messageRepository, - UserRepository userRepository, - CustomerRepository customerRepository) { + UserRepository userRepository) { this.conversationRepository = conversationRepository; this.messageRepository = messageRepository; this.userRepository = userRepository; - this.customerRepository = customerRepository; } @Transactional @@ -49,11 +44,8 @@ public class ChatService { throw new AccessDeniedException("Only customers can start new conversations"); } - Customer customer = customerRepository.findByUserId(userId) - .orElseThrow(() -> new ResourceNotFoundException("Customer record not found for user")); - Conversation conversation = new Conversation(); - conversation.setCustomerId(customer.getCustomerId()); + conversation.setCustomerId(userId); conversation.setStatus(Conversation.ConversationStatus.OPEN); conversation.setMode(Conversation.ConversationMode.AUTOMATED); conversation = conversationRepository.save(conversation); @@ -72,9 +64,7 @@ public class ChatService { List conversations; if (role == User.Role.CUSTOMER) { - Customer customer = customerRepository.findByUserId(userId) - .orElseThrow(() -> new ResourceNotFoundException("Customer record not found for user")); - conversations = conversationRepository.findByCustomerId(customer.getCustomerId()); + conversations = conversationRepository.findByCustomerId(userId); } else if (role == User.Role.STAFF) { List assignedToMe = conversationRepository.findByStaffId(userId); List unassigned = conversationRepository.findByStaffIdIsNull(); @@ -225,9 +215,7 @@ public class ChatService { } if (role == User.Role.CUSTOMER) { - Customer customer = customerRepository.findByUserId(userId) - .orElseThrow(() -> new ResourceNotFoundException("Customer record not found for user")); - return conversation.getCustomerId().equals(customer.getCustomerId()); + return conversation.getCustomerId().equals(userId); } if (role == User.Role.STAFF) { diff --git a/backend/src/main/java/com/petshop/backend/service/CustomerPetService.java b/backend/src/main/java/com/petshop/backend/service/CustomerPetService.java deleted file mode 100644 index fa424737..00000000 --- a/backend/src/main/java/com/petshop/backend/service/CustomerPetService.java +++ /dev/null @@ -1,163 +0,0 @@ -package com.petshop.backend.service; - -import com.petshop.backend.dto.customerpet.CustomerPetRequest; -import com.petshop.backend.dto.customerpet.CustomerPetResponse; -import com.petshop.backend.entity.Customer; -import com.petshop.backend.entity.CustomerPet; -import com.petshop.backend.exception.ResourceNotFoundException; -import com.petshop.backend.repository.CustomerPetRepository; -import com.petshop.backend.repository.CustomerRepository; -import com.petshop.backend.repository.UserRepository; -import com.petshop.backend.util.AuthenticationHelper; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.multipart.MultipartFile; - -import java.io.IOException; -import java.util.List; -import java.util.Locale; -import java.util.stream.Collectors; - -@Service -public class CustomerPetService { - - private final CustomerPetRepository customerPetRepository; - private final CustomerRepository customerRepository; - private final UserRepository userRepository; - private final CatalogImageStorageService catalogImageStorageService; - - public CustomerPetService(CustomerPetRepository customerPetRepository, - CustomerRepository customerRepository, - UserRepository userRepository, - CatalogImageStorageService catalogImageStorageService) { - this.customerPetRepository = customerPetRepository; - this.customerRepository = customerRepository; - this.userRepository = userRepository; - this.catalogImageStorageService = catalogImageStorageService; - } - - @Transactional(readOnly = true) - public List getMyPets() { - Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository); - - return customerPetRepository.findByCustomerCustomerIdOrderByCreatedAtDesc(customer.getCustomerId()) - .stream() - .map(this::mapToResponse) - .collect(Collectors.toList()); - } - - @Transactional - public CustomerPetResponse createPet(CustomerPetRequest request) { - Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository); - - CustomerPet pet = new CustomerPet(); - pet.setCustomer(customer); - pet.setPetName(request.getPetName()); - pet.setSpecies(request.getSpecies()); - pet.setBreed(request.getBreed()); - - pet = customerPetRepository.save(pet); - - return mapToResponse(pet); - } - - @Transactional - public CustomerPetResponse updatePet(Long id, CustomerPetRequest request) { - Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository); - CustomerPet pet = customerPetRepository.findByCustomerPetIdAndCustomerCustomerId(id, customer.getCustomerId()) - .orElseThrow(() -> new ResourceNotFoundException("Pet not found with id: " + id)); - - pet.setPetName(request.getPetName()); - pet.setSpecies(request.getSpecies()); - pet.setBreed(request.getBreed()); - - pet = customerPetRepository.save(pet); - - return mapToResponse(pet); - } - - @Transactional - public void deletePet(Long id) { - Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository); - CustomerPet pet = customerPetRepository.findByCustomerPetIdAndCustomerCustomerId(id, customer.getCustomerId()).orElseThrow(() -> new ResourceNotFoundException("Pet not found with id: " + id)); - deleteStoredImageIfPresent(pet.getImageUrl()); - - customerPetRepository.delete(pet); - } - - @Transactional - public CustomerPetResponse uploadImage(Long id, MultipartFile file) throws IOException { - validateImageFile(file); - Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository); - CustomerPet pet = customerPetRepository.findByCustomerPetIdAndCustomerCustomerId(id, customer.getCustomerId()).orElseThrow(() -> new ResourceNotFoundException("Pet not found with id: " + id)); - deleteStoredImageIfPresent(pet.getImageUrl()); - pet.setImageUrl(catalogImageStorageService.storePetImage(file)); - - return mapToResponse(customerPetRepository.save(pet)); - } - - @Transactional - public CustomerPetResponse deleteImage(Long id) { - Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository); - CustomerPet pet = customerPetRepository.findByCustomerPetIdAndCustomerCustomerId(id, customer.getCustomerId()).orElseThrow(() -> new ResourceNotFoundException("Pet not found with id: " + id)); - deleteStoredImageIfPresent(pet.getImageUrl()); - pet.setImageUrl(null); - - return mapToResponse(customerPetRepository.save(pet)); - } - - private CustomerPetResponse mapToResponse(CustomerPet pet) { - return new CustomerPetResponse( - pet.getCustomerPetId(), - pet.getCustomer().getCustomerId(), - pet.getPetName(), - pet.getSpecies(), - pet.getBreed(), - pet.getImageUrl() != null && !pet.getImageUrl().isBlank() - ? "/api/v1/my-pets/" + pet.getCustomerPetId() + "/image" - : null, - pet.getCreatedAt(), - pet.getUpdatedAt() - ); - } - - private void validateImageFile(MultipartFile file) { - if (file == null || file.isEmpty()) { - - throw new IllegalArgumentException("Please select an image to upload"); - } - - if (file.getSize() > 5 * 1024 * 1024) { - - throw new IllegalArgumentException("Image file size must be less than 5MB"); - } - - String contentType = file.getContentType(); - - if (contentType == null) { - - throw new IllegalArgumentException("Only JPG, PNG, and GIF images are allowed"); - } - - String normalized = contentType.toLowerCase(Locale.ROOT); - - if (!normalized.equals("image/jpeg") && !normalized.equals("image/png") && !normalized.equals("image/gif")) { - - throw new IllegalArgumentException("Only JPG, PNG, and GIF images are allowed"); - } - } - - private void deleteStoredImageIfPresent(String storedImagePath) { - if (storedImagePath == null || storedImagePath.isBlank()) { - - return; - } - - try { - catalogImageStorageService.deletePetImage(storedImagePath); - } - - catch (IOException ignored) { - } - } -} diff --git a/backend/src/main/java/com/petshop/backend/service/CustomerService.java b/backend/src/main/java/com/petshop/backend/service/CustomerService.java deleted file mode 100644 index 33c731d1..00000000 --- a/backend/src/main/java/com/petshop/backend/service/CustomerService.java +++ /dev/null @@ -1,158 +0,0 @@ -package com.petshop.backend.service; - -import com.petshop.backend.dto.common.BulkDeleteRequest; -import com.petshop.backend.dto.customer.CustomerRequest; -import com.petshop.backend.dto.customer.CustomerResponse; -import com.petshop.backend.entity.Customer; -import com.petshop.backend.entity.User; -import com.petshop.backend.exception.ResourceNotFoundException; -import com.petshop.backend.repository.CustomerRepository; -import com.petshop.backend.repository.UserRepository; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.server.ResponseStatusException; - -import static org.springframework.http.HttpStatus.CONFLICT; - -@Service -public class CustomerService { - - private static final String TEMP_PASSWORD = "TempPass123!"; - - private final CustomerRepository customerRepository; - private final UserRepository userRepository; - private final PasswordEncoder passwordEncoder; - private final UserBusinessLinkageService userBusinessLinkageService; - - public CustomerService(CustomerRepository customerRepository, UserRepository userRepository, PasswordEncoder passwordEncoder, UserBusinessLinkageService userBusinessLinkageService) { - this.customerRepository = customerRepository; - this.userRepository = userRepository; - this.passwordEncoder = passwordEncoder; - this.userBusinessLinkageService = userBusinessLinkageService; - } - - public Page getAllCustomers(String query, Pageable pageable) { - Page customers; - if (query != null && !query.trim().isEmpty()) { - customers = customerRepository.searchCustomers(query, pageable); - } else { - customers = customerRepository.findAll(pageable); - } - return customers.map(this::mapToResponse); - } - - public CustomerResponse getCustomerById(Long id) { - Customer customer = customerRepository.findById(id) - .orElseThrow(() -> new ResourceNotFoundException("Customer not found with id: " + id)); - return mapToResponse(customer); - } - - @Transactional - public CustomerResponse createCustomer(CustomerRequest request) { - ensureEmailAvailable(request.getEmail(), null); - - Customer customer = new Customer(); - customer.setFirstName(request.getFirstName()); - customer.setLastName(request.getLastName()); - customer.setEmail(request.getEmail()); - - customer = customerRepository.save(customer); - User user = createLinkedUser(customer); - - Customer linkedCustomer = userBusinessLinkageService.ensureLinkedCustomer(user); - syncLinkedUser(linkedCustomer); - return mapToResponse(linkedCustomer); - } - - @Transactional - public CustomerResponse updateCustomer(Long id, CustomerRequest request) { - Customer customer = customerRepository.findById(id) - .orElseThrow(() -> new ResourceNotFoundException("Customer not found with id: " + id)); - - ensureEmailAvailable(request.getEmail(), customer.getUserId()); - - customer.setFirstName(request.getFirstName()); - customer.setLastName(request.getLastName()); - customer.setEmail(request.getEmail()); - - customer = customerRepository.save(customer); - syncLinkedUser(customer); - return mapToResponse(customer); - } - - @Transactional - public void deleteCustomer(Long id) { - Customer customer = customerRepository.findById(id) - .orElseThrow(() -> new ResourceNotFoundException("Customer not found with id: " + id)); - - if (customer.getUserId() != null && userRepository.existsById(customer.getUserId())) { - userRepository.deleteById(customer.getUserId()); - return; - } - - customerRepository.deleteById(id); - } - - @Transactional - public void bulkDeleteCustomers(BulkDeleteRequest request) { - customerRepository.deleteAllById(request.getIds()); - } - - private CustomerResponse mapToResponse(Customer customer) { - return new CustomerResponse( - customer.getCustomerId(), - customer.getFirstName(), - customer.getLastName(), - customer.getEmail(), - customer.getCreatedAt(), - customer.getUpdatedAt() - ); - } - - private void syncLinkedUser(Customer customer) { - if (customer.getUserId() == null) { - return; - } - userRepository.findById(customer.getUserId()).ifPresent(user -> { - user.setEmail(customer.getEmail()); - user.setFullName((customer.getFirstName() + " " + customer.getLastName()).trim()); - userRepository.save(user); - }); - } - - private User createLinkedUser(Customer customer) { - User user = new User(); - user.setUsername(generateUsername(customer)); - user.setPassword(passwordEncoder.encode(TEMP_PASSWORD)); - user.setEmail(customer.getEmail()); - user.setFullName((customer.getFirstName() + " " + customer.getLastName()).trim()); - user.setPhone(generatePhone(customer)); - user.setRole(User.Role.CUSTOMER); - user.setActive(false); - user.setTokenVersion(0); - return userRepository.save(user); - } - - private String generateUsername(Customer customer) { - return "customer_" + customer.getCustomerId(); - } - - private String generatePhone(Customer customer) { - return String.format("200-000-%04d", customer.getCustomerId()); - } - - private void ensureEmailAvailable(String email, Long currentUserId) { - if (email == null || email.isBlank()) { - return; - } - - userRepository.findByEmail(email).ifPresent(existing -> { - if (currentUserId == null || !existing.getId().equals(currentUserId)) { - throw new ResponseStatusException(CONFLICT, "Email already exists"); - } - }); - } -} diff --git a/backend/src/main/java/com/petshop/backend/service/EmployeeService.java b/backend/src/main/java/com/petshop/backend/service/EmployeeService.java deleted file mode 100644 index baf83bb8..00000000 --- a/backend/src/main/java/com/petshop/backend/service/EmployeeService.java +++ /dev/null @@ -1,183 +0,0 @@ -package com.petshop.backend.service; - -import com.petshop.backend.dto.employee.EmployeeRequest; -import com.petshop.backend.dto.employee.EmployeeResponse; -import com.petshop.backend.entity.Employee; -import com.petshop.backend.entity.User; -import com.petshop.backend.exception.ResourceNotFoundException; -import com.petshop.backend.repository.EmployeeRepository; -import com.petshop.backend.repository.UserRepository; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.server.ResponseStatusException; - -import static org.springframework.http.HttpStatus.CONFLICT; - -@Service -public class EmployeeService { - private final EmployeeRepository employeeRepository; - private final UserRepository userRepository; - private final PasswordEncoder passwordEncoder; - private final UserBusinessLinkageService userBusinessLinkageService; - - public EmployeeService(EmployeeRepository employeeRepository, UserRepository userRepository, PasswordEncoder passwordEncoder, UserBusinessLinkageService userBusinessLinkageService) { - this.employeeRepository = employeeRepository; - this.userRepository = userRepository; - this.passwordEncoder = passwordEncoder; - this.userBusinessLinkageService = userBusinessLinkageService; - } - - public Page getAllEmployees(String query, Pageable pageable) { - Page employees; - if (query != null && !query.trim().isEmpty()) { - employees = employeeRepository.searchEmployees(query, pageable); - } else { - employees = employeeRepository.findAll(pageable); - } - return employees.map(this::mapToResponse); - } - - public EmployeeResponse getEmployeeById(Long id) { - Employee employee = employeeRepository.findById(id) - .orElseThrow(() -> new ResourceNotFoundException("Employee not found with id: " + id)); - return mapToResponse(employee); - } - - @Transactional - public EmployeeResponse createEmployee(EmployeeRequest request) { - validateRole(request.getRole()); - if (request.getPassword() == null || request.getPassword().trim().length() < 6) { - throw new IllegalArgumentException("Password must be at least 6 characters"); - } - if (userRepository.findByUsername(request.getUsername()).isPresent()) { - throw new ResponseStatusException(CONFLICT, "Username already exists"); - } - if (request.getEmail() != null && userRepository.findByEmail(request.getEmail()).isPresent()) { - throw new ResponseStatusException(CONFLICT, "Email already exists"); - } - String phone = trimToNull(request.getPhone()); - if (phone != null && userRepository.findByPhone(phone).isPresent()) { - throw new ResponseStatusException(CONFLICT, "Phone already exists"); - } - - User user = new User(); - user.setUsername(request.getUsername()); - user.setPassword(passwordEncoder.encode(request.getPassword())); - user.setFullName(fullName(request)); - user.setEmail(request.getEmail()); - user.setPhone(phone); - user.setRole(request.getRole()); - user.setActive(request.getActive() != null ? request.getActive() : true); - user = userRepository.save(user); - - Employee employee = userBusinessLinkageService.ensureLinkedEmployee(user); - return mapToResponse(employee, user); - } - - @Transactional - public EmployeeResponse updateEmployee(Long id, EmployeeRequest request) { - Employee employee = employeeRepository.findById(id) - .orElseThrow(() -> new ResourceNotFoundException("Employee not found with id: " + id)); - User user = requireLinkedUser(employee); - - validateRole(request.getRole()); - if (!user.getUsername().equals(request.getUsername()) && userRepository.findByUsername(request.getUsername()).isPresent()) { - throw new ResponseStatusException(CONFLICT, "Username already exists"); - } - if (!java.util.Objects.equals(user.getEmail(), request.getEmail()) && request.getEmail() != null && userRepository.findByEmail(request.getEmail()).isPresent()) { - throw new ResponseStatusException(CONFLICT, "Email already exists"); - } - String phone = trimToNull(request.getPhone()); - Long currentUserId = user.getId(); - if (!java.util.Objects.equals(user.getPhone(), phone)) { - userRepository.findByPhone(phone) - .filter(existing -> !existing.getId().equals(currentUserId)) - .ifPresent(existing -> { throw new ResponseStatusException(CONFLICT, "Phone already exists"); }); - } - - user.setUsername(request.getUsername()); - if (request.getPassword() != null && !request.getPassword().trim().isEmpty()) { - user.setPassword(passwordEncoder.encode(request.getPassword())); - user.setTokenVersion(user.getTokenVersion() + 1); - } - user.setEmail(request.getEmail()); - user.setPhone(phone); - user.setFullName(fullName(request)); - user.setRole(request.getRole()); - user.setActive(request.getActive() != null ? request.getActive() : true); - user = userRepository.save(user); - - employee = userBusinessLinkageService.ensureLinkedEmployee(user); - return mapToResponse(employee, user); - } - - @Transactional - public void deleteEmployee(Long id) { - Employee employee = employeeRepository.findById(id) - .orElseThrow(() -> new ResourceNotFoundException("Employee not found with id: " + id)); - if (employee.getUserId() != null && userRepository.existsById(employee.getUserId())) { - userRepository.deleteById(employee.getUserId()); - return; - } - employeeRepository.deleteById(id); - } - - private EmployeeResponse mapToResponse(Employee employee) { - User user = employee.getUserId() == null ? null : userRepository.findById(employee.getUserId()).orElse(null); - return mapToResponse(employee, user); - } - - private EmployeeResponse mapToResponse(Employee employee, User user) { - EmployeeResponse response = new EmployeeResponse(); - response.setEmployeeId(employee.getEmployeeId()); - response.setUserId(user != null ? user.getId() : employee.getUserId()); - response.setUsername(user != null ? user.getUsername() : null); - response.setFirstName(employee.getFirstName()); - response.setLastName(employee.getLastName()); - response.setFullName(user != null ? user.getFullName() : fullName(employee)); - response.setEmail(user != null ? user.getEmail() : employee.getEmail()); - response.setPhone(user != null ? user.getPhone() : null); - response.setRole(user != null ? user.getRole().name() : normalizeRole(employee.getRole())); - response.setActive(user != null ? user.getActive() : employee.getIsActive()); - response.setCreatedAt(employee.getCreatedAt()); - response.setUpdatedAt(employee.getUpdatedAt()); - return response; - } - - private User requireLinkedUser(Employee employee) { - if (employee.getUserId() == null) { - throw new ResourceNotFoundException("Employee user account not found"); - } - return userRepository.findById(employee.getUserId()) - .orElseThrow(() -> new ResourceNotFoundException("Employee user account not found")); - } - - private void validateRole(User.Role role) { - if (role != User.Role.STAFF && role != User.Role.ADMIN) { - throw new IllegalArgumentException("Employee role must be STAFF or ADMIN"); - } - } - - private String fullName(EmployeeRequest request) { - return (request.getFirstName().trim() + " " + request.getLastName().trim()).trim(); - } - - private String fullName(Employee employee) { - return (employee.getFirstName().trim() + " " + employee.getLastName().trim()).trim(); - } - - private String normalizeRole(String role) { - return role == null ? null : role.trim().toUpperCase(java.util.Locale.ROOT); - } - - private String trimToNull(String value) { - if (value == null) { - return null; - } - String trimmed = value.trim(); - return trimmed.isEmpty() ? null : trimmed; - } -} diff --git a/backend/src/main/java/com/petshop/backend/service/PetService.java b/backend/src/main/java/com/petshop/backend/service/PetService.java index 7d038ed4..ef6ab4c5 100644 --- a/backend/src/main/java/com/petshop/backend/service/PetService.java +++ b/backend/src/main/java/com/petshop/backend/service/PetService.java @@ -4,16 +4,15 @@ import com.petshop.backend.dto.common.BulkDeleteRequest; import com.petshop.backend.dto.pet.PetRequest; import com.petshop.backend.dto.pet.PetResponse; import com.petshop.backend.entity.Adoption; -import com.petshop.backend.entity.Customer; import com.petshop.backend.entity.Pet; import com.petshop.backend.entity.StoreLocation; import com.petshop.backend.entity.User; import com.petshop.backend.exception.ResourceNotFoundException; import com.petshop.backend.security.AppPrincipal; import com.petshop.backend.repository.AdoptionRepository; -import com.petshop.backend.repository.CustomerRepository; import com.petshop.backend.repository.PetRepository; import com.petshop.backend.repository.StoreRepository; +import com.petshop.backend.repository.UserRepository; import org.springframework.core.io.Resource; import org.springframework.http.MediaType; import org.springframework.data.domain.Page; @@ -33,14 +32,14 @@ public class PetService { private final PetRepository petRepository; private final AdoptionRepository adoptionRepository; - private final CustomerRepository customerRepository; + private final UserRepository userRepository; private final StoreRepository storeRepository; private final CatalogImageStorageService catalogImageStorageService; - public PetService(PetRepository petRepository, AdoptionRepository adoptionRepository, CustomerRepository customerRepository, StoreRepository storeRepository, CatalogImageStorageService catalogImageStorageService) { + public PetService(PetRepository petRepository, AdoptionRepository adoptionRepository, UserRepository userRepository, StoreRepository storeRepository, CatalogImageStorageService catalogImageStorageService) { this.petRepository = petRepository; this.adoptionRepository = adoptionRepository; - this.customerRepository = customerRepository; + this.userRepository = userRepository; this.storeRepository = storeRepository; this.catalogImageStorageService = catalogImageStorageService; } @@ -188,7 +187,7 @@ public class PetService { } return adoptionRepository.findFirstByPet_IdAndAdoptionStatusOrderByAdoptionDateDesc(pet.getPetId(), "Completed") .map(Adoption::getCustomer) - .map(customer -> userId.equals(customer.getUserId())) + .map(customer -> userId.equals(customer.getId())) .orElse(false); } @@ -257,7 +256,7 @@ public class PetService { } private PetResponse mapToResponse(Pet pet) { - Customer customer = pet.getCustomer(); + User owner = pet.getOwner(); StoreLocation store = pet.getStore(); return new PetResponse( pet.getPetId(), @@ -270,8 +269,8 @@ public class PetService { pet.getImageUrl() != null && !pet.getImageUrl().isBlank() ? "/api/v1/pets/" + pet.getPetId() + "/image" : null, pet.getCreatedAt(), pet.getUpdatedAt(), - customer != null ? customer.getCustomerId() : null, - customer != null ? customer.getFirstName() + " " + customer.getLastName() : null, + owner != null ? owner.getId() : null, + owner != null ? owner.getFirstName() + " " + owner.getLastName() : null, store != null ? store.getStoreId() : null, store != null ? store.getStoreName() : null ); @@ -280,11 +279,11 @@ public class PetService { private void applyOwnerAndStore(Pet pet, PetRequest request) { if ("owned".equalsIgnoreCase(request.getPetStatus())) { if (request.getCustomerId() != null) { - Customer customer = customerRepository.findById(request.getCustomerId()) + User owner = userRepository.findById(request.getCustomerId()) .orElseThrow(() -> new ResourceNotFoundException("Customer not found with id: " + request.getCustomerId())); - pet.setCustomer(customer); + pet.setOwner(owner); } else { - pet.setCustomer(null); + pet.setOwner(null); } pet.setStore(null); } else if ("available".equalsIgnoreCase(request.getPetStatus()) || "unadopted".equalsIgnoreCase(request.getPetStatus())) { @@ -295,14 +294,14 @@ public class PetService { } else { pet.setStore(null); } - pet.setCustomer(null); + pet.setOwner(null); } else { if (request.getCustomerId() != null) { - Customer customer = customerRepository.findById(request.getCustomerId()) + User owner = userRepository.findById(request.getCustomerId()) .orElseThrow(() -> new ResourceNotFoundException("Customer not found with id: " + request.getCustomerId())); - pet.setCustomer(customer); + pet.setOwner(owner); } else { - pet.setCustomer(null); + pet.setOwner(null); } if (request.getStoreId() != null) { StoreLocation store = storeRepository.findById(request.getStoreId()) @@ -318,8 +317,8 @@ public class PetService { if (!"owned".equalsIgnoreCase(normalizeStatus(pet.getPetStatus()))) { return false; } - Customer customer = pet.getCustomer(); - return customer != null && userId.equals(customer.getUserId()); + User owner = pet.getOwner(); + return owner != null && userId.equals(owner.getId()); } public record ImagePayload(Resource resource, MediaType mediaType) { diff --git a/backend/src/main/java/com/petshop/backend/service/RefundService.java b/backend/src/main/java/com/petshop/backend/service/RefundService.java index 61c067fb..6d3ef880 100644 --- a/backend/src/main/java/com/petshop/backend/service/RefundService.java +++ b/backend/src/main/java/com/petshop/backend/service/RefundService.java @@ -46,13 +46,13 @@ public class RefundService { throw new RuntimeException("Sale has no associated customer"); } - if (customerId != null && !sale.getCustomer().getCustomerId().equals(customerId)) { + if (customerId != null && !sale.getCustomer().getId().equals(customerId)) { throw new RuntimeException("You can only create refunds for your own purchases"); } Refund refund = new Refund(); refund.setSaleId(sale.getSaleId()); - refund.setCustomerId(sale.getCustomer().getCustomerId()); + refund.setCustomerId(sale.getCustomer().getId()); refund.setReason(request.getReason()); refund.setStatus(Refund.RefundStatus.PENDING); diff --git a/backend/src/main/java/com/petshop/backend/service/SaleService.java b/backend/src/main/java/com/petshop/backend/service/SaleService.java index b8d5861e..acad5e68 100644 --- a/backend/src/main/java/com/petshop/backend/service/SaleService.java +++ b/backend/src/main/java/com/petshop/backend/service/SaleService.java @@ -24,20 +24,14 @@ public class SaleService { private final ProductRepository productRepository; private final StoreRepository storeRepository; private final InventoryRepository inventoryRepository; - private final EmployeeRepository employeeRepository; - private final EmployeeStoreRepository employeeStoreRepository; private final UserRepository userRepository; - private final CustomerRepository customerRepository; - public SaleService(SaleRepository saleRepository, ProductRepository productRepository, StoreRepository storeRepository, InventoryRepository inventoryRepository, EmployeeRepository employeeRepository, EmployeeStoreRepository employeeStoreRepository, UserRepository userRepository, CustomerRepository customerRepository) { + public SaleService(SaleRepository saleRepository, ProductRepository productRepository, StoreRepository storeRepository, InventoryRepository inventoryRepository, UserRepository userRepository) { this.saleRepository = saleRepository; this.productRepository = productRepository; this.storeRepository = storeRepository; this.inventoryRepository = inventoryRepository; - this.employeeRepository = employeeRepository; - this.employeeStoreRepository = employeeStoreRepository; this.userRepository = userRepository; - this.customerRepository = customerRepository; } @Transactional(readOnly = true) @@ -60,18 +54,16 @@ public class SaleService { @Transactional public SaleResponse createSale(SaleRequest request) { - User user = AuthenticationHelper.getAuthenticatedUser(userRepository); - Employee employee = AuthenticationHelper.getAuthenticatedEmployee(userRepository, employeeRepository); - Long employeeStoreId = employeeStoreRepository.findByEmployeeEmployeeId(employee.getEmployeeId()) - .orElseThrow(() -> new BusinessException("Authenticated staff member is not assigned to a store")) - .getStore() - .getStoreId(); + User employee = AuthenticationHelper.getAuthenticatedUser(userRepository); StoreLocation store = storeRepository.findById(request.getStoreId()) .orElseThrow(() -> new ResourceNotFoundException("Store not found with id: " + request.getStoreId())); - if (user.getRole() == User.Role.STAFF && !employeeStoreId.equals(store.getStoreId())) { - throw new BusinessException("Staff can only create sales for their assigned store"); + if (employee.getRole() == User.Role.STAFF) { + Long assignedStoreId = employee.getPrimaryStore() != null ? employee.getPrimaryStore().getStoreId() : null; + if (!store.getStoreId().equals(assignedStoreId)) { + throw new BusinessException("Staff can only create sales for their assigned store"); + } } Sale sale = new Sale(); @@ -82,7 +74,7 @@ public class SaleService { sale.setIsRefund(request.getIsRefund() != null ? request.getIsRefund() : false); if (request.getCustomerId() != null) { - Customer customer = customerRepository.findById(request.getCustomerId()) + User customer = userRepository.findById(request.getCustomerId()) .orElseThrow(() -> new ResourceNotFoundException("Customer not found with id: " + request.getCustomerId())); sale.setCustomer(customer); } @@ -185,7 +177,7 @@ public class SaleService { SaleResponse response = new SaleResponse(); response.setSaleId(sale.getSaleId()); response.setSaleDate(sale.getSaleDate()); - response.setEmployeeId(sale.getEmployee().getEmployeeId()); + response.setEmployeeId(sale.getEmployee().getId()); response.setEmployeeName(sale.getEmployee().getFirstName() + " " + sale.getEmployee().getLastName()); if (sale.getStore() != null) { diff --git a/backend/src/main/java/com/petshop/backend/service/StoreAssignmentService.java b/backend/src/main/java/com/petshop/backend/service/StoreAssignmentService.java deleted file mode 100644 index 31cc18d5..00000000 --- a/backend/src/main/java/com/petshop/backend/service/StoreAssignmentService.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.petshop.backend.service; - -import com.petshop.backend.entity.Employee; -import com.petshop.backend.entity.EmployeeStore; -import com.petshop.backend.entity.StoreLocation; -import com.petshop.backend.exception.ResourceNotFoundException; -import com.petshop.backend.repository.EmployeeStoreRepository; -import com.petshop.backend.repository.StoreRepository; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -public class StoreAssignmentService { - - private final EmployeeStoreRepository employeeStoreRepository; - private final StoreRepository storeRepository; - - public StoreAssignmentService(EmployeeStoreRepository employeeStoreRepository, StoreRepository storeRepository) { - this.employeeStoreRepository = employeeStoreRepository; - this.storeRepository = storeRepository; - } - - @Transactional - public void assignStoreIfMissing(Employee employee, Long storeId) { - if (employeeStoreRepository.findByEmployeeEmployeeId(employee.getEmployeeId()).isPresent()) { - return; - } - - StoreLocation store = storeRepository.findById(storeId) - .orElseThrow(() -> new ResourceNotFoundException("Store not found with id: " + storeId)); - - employeeStoreRepository.save(new EmployeeStore(employee, store)); - } -} diff --git a/backend/src/main/java/com/petshop/backend/service/UserBusinessLinkageService.java b/backend/src/main/java/com/petshop/backend/service/UserBusinessLinkageService.java deleted file mode 100644 index 05751688..00000000 --- a/backend/src/main/java/com/petshop/backend/service/UserBusinessLinkageService.java +++ /dev/null @@ -1,152 +0,0 @@ -package com.petshop.backend.service; - -import com.petshop.backend.entity.Customer; -import com.petshop.backend.entity.Employee; -import com.petshop.backend.entity.User; -import com.petshop.backend.repository.CustomerRepository; -import com.petshop.backend.repository.EmployeeRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; - -@Service -public class UserBusinessLinkageService { - - private final EmployeeRepository employeeRepository; - private final CustomerRepository customerRepository; - - @Autowired - public UserBusinessLinkageService(EmployeeRepository employeeRepository, CustomerRepository customerRepository) { - this.employeeRepository = employeeRepository; - this.customerRepository = customerRepository; - } - - @Transactional - public Employee ensureLinkedEmployee(User user) { - if (user.getId() != null) { - var existing = employeeRepository.findByUserId(user.getId()); - if (existing.isPresent()) { - return syncEmployee(existing.get(), user); - } - } - - List emailMatches = employeeRepository.findAllByEmail(user.getEmail()); - - if (emailMatches.size() == 1) { - Employee employee = emailMatches.get(0); - if (employee.getUserId() == null) { - employee.setUserId(user.getId()); - return syncEmployee(employee, user); - } - } - - Employee newEmployee = new Employee(); - newEmployee.setUserId(user.getId()); - newEmployee.setEmail(user.getEmail()); - - String[] nameParts = splitFullName(user.getFullName()); - newEmployee.setFirstName(nameParts[0]); - newEmployee.setLastName(nameParts[1]); - - newEmployee.setIsActive(true); - - if (user.getRole() == User.Role.ADMIN) { - newEmployee.setRole("Manager"); - } else if (user.getRole() == User.Role.STAFF) { - newEmployee.setRole("Staff"); - } else { - newEmployee.setRole("Staff"); - } - - return syncEmployee(newEmployee, user); - } - - @Transactional - public Customer ensureLinkedCustomer(User user) { - if (user.getId() != null) { - var existing = customerRepository.findByUserId(user.getId()); - if (existing.isPresent()) { - return syncCustomer(existing.get(), user); - } - } - - List emailMatches = customerRepository.findAllByEmail(user.getEmail()); - - if (emailMatches.size() == 1) { - Customer customer = emailMatches.get(0); - if (customer.getUserId() == null) { - customer.setUserId(user.getId()); - return syncCustomer(customer, user); - } - } - - Customer newCustomer = new Customer(); - newCustomer.setUserId(user.getId()); - newCustomer.setEmail(user.getEmail()); - - String[] nameParts = splitFullName(user.getFullName()); - newCustomer.setFirstName(nameParts[0]); - newCustomer.setLastName(nameParts[1]); - - return syncCustomer(newCustomer, user); - } - - @Transactional - public void syncLinkedRecords(User user) { - if (user.getRole() == User.Role.CUSTOMER) { - ensureLinkedCustomer(user); - return; - } - ensureLinkedEmployee(user); - } - - private Employee syncEmployee(Employee employee, User user) { - employee.setUserId(user.getId()); - employee.setEmail(user.getEmail()); - String[] nameParts = splitFullName(user.getFullName()); - employee.setFirstName(nameParts[0]); - employee.setLastName(nameParts[1]); - if (user.getRole() == User.Role.ADMIN) { - employee.setRole("Manager"); - } else { - employee.setRole("Staff"); - } - return employeeRepository.save(employee); - } - - private Customer syncCustomer(Customer customer, User user) { - customer.setUserId(user.getId()); - customer.setEmail(user.getEmail()); - String[] nameParts = splitFullName(user.getFullName()); - customer.setFirstName(nameParts[0]); - customer.setLastName(nameParts[1]); - return customerRepository.save(customer); - } - - private String[] splitFullName(String fullName) { - if (fullName == null || fullName.trim().isEmpty()) { - return new String[]{"System", "User"}; - } - - String trimmed = fullName.trim(); - int spaceIndex = trimmed.indexOf(' '); - - if (spaceIndex == -1) { - return new String[]{trimmed, "User"}; - } - - String firstName = trimmed.substring(0, spaceIndex).trim(); - String lastName = trimmed.substring(spaceIndex + 1).trim(); - - if (firstName.isEmpty()) { - firstName = "System"; - } - if (lastName.isEmpty()) { - lastName = "User"; - } - - return new String[]{firstName, lastName}; - } -} diff --git a/backend/src/main/java/com/petshop/backend/service/UserService.java b/backend/src/main/java/com/petshop/backend/service/UserService.java index e3a17c5c..a6661cf1 100644 --- a/backend/src/main/java/com/petshop/backend/service/UserService.java +++ b/backend/src/main/java/com/petshop/backend/service/UserService.java @@ -26,13 +26,11 @@ public class UserService { private final UserRepository userRepository; private final PasswordEncoder passwordEncoder; - private final UserBusinessLinkageService userBusinessLinkageService; private final StoreRepository storeRepository; - public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder, UserBusinessLinkageService userBusinessLinkageService, StoreRepository storeRepository) { + public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder, StoreRepository storeRepository) { this.userRepository = userRepository; this.passwordEncoder = passwordEncoder; - this.userBusinessLinkageService = userBusinessLinkageService; this.storeRepository = storeRepository; } @@ -79,8 +77,6 @@ public class UserService { user = userRepository.save(user); - userBusinessLinkageService.syncLinkedRecords(user); - return mapToResponse(user); } @@ -117,7 +113,6 @@ public class UserService { } user = userRepository.save(user); - userBusinessLinkageService.syncLinkedRecords(user); return mapToResponse(user); } diff --git a/backend/src/main/java/com/petshop/backend/util/AuthenticationHelper.java b/backend/src/main/java/com/petshop/backend/util/AuthenticationHelper.java index b1ab33a1..66c7418f 100644 --- a/backend/src/main/java/com/petshop/backend/util/AuthenticationHelper.java +++ b/backend/src/main/java/com/petshop/backend/util/AuthenticationHelper.java @@ -1,10 +1,6 @@ package com.petshop.backend.util; -import com.petshop.backend.entity.Customer; -import com.petshop.backend.entity.Employee; import com.petshop.backend.entity.User; -import com.petshop.backend.repository.CustomerRepository; -import com.petshop.backend.repository.EmployeeRepository; import com.petshop.backend.repository.UserRepository; import com.petshop.backend.security.AppPrincipal; import org.springframework.security.core.Authentication; @@ -47,16 +43,4 @@ public class AuthenticationHelper { return userRepository.findByUsername(username) .orElseThrow(() -> new RuntimeException("User not found: " + username)); } - - public static Employee getAuthenticatedEmployee(UserRepository userRepository, EmployeeRepository employeeRepository) { - User user = getAuthenticatedUser(userRepository); - return employeeRepository.findByUserId(user.getId()) - .orElseThrow(() -> new RuntimeException("Employee record not found for user: " + user.getUsername())); - } - - public static Customer getAuthenticatedCustomer(UserRepository userRepository, CustomerRepository customerRepository) { - User user = getAuthenticatedUser(userRepository); - return customerRepository.findByUserId(user.getId()) - .orElseThrow(() -> new RuntimeException("Customer record not found for user: " + user.getUsername())); - } }